We recently added a share counter to the ZeroHost homepage - a live count of secrets shared and forgotten on the platform. The interesting constraint: we built it without logging a single IP address, user agent, or session identifier. This post walks through the thinking behind that decision and what privacy-by-design actually looks like when it constrains a real engineering choice.
The Problem with Conventional Analytics
Most counters are a side effect of user tracking - tools that answer "how many?" by first answering "who?". For a privacy-first product, that's a contradiction. We don't want the data that would let us answer the second question.
The conventional approach would have given us richer data: geographic breakdowns, usage trends, retention curves. We chose not to build any of it. The goal was a counter that is genuinely impossible to reverse into individual user data.
The Architecture: One Atomic Number
The implementation is deliberately minimal: a single record in our database containing a running total and nothing else. Every share creation triggers an atomic increment - one operation that adds 1 to the count.
Atomic increments matter here. They eliminate race conditions, prevent double-counting, and remain consistent under concurrent load. But critically: no timestamps are attached to the increment. No user identifiers. No session data. No IP addresses.
The counter is a pure integer. There is nothing else stored, nothing to join it against, nothing to leak. The entire "analytics system" for this feature is approximately 20 lines of code.
The Public API
A single lightweight endpoint reads the counter and returns it - no authentication required, it's just a number. Edge caching keeps the response fast without hitting our database on every page load. Most visitors never trigger a live database read.
The cache window means the number updates periodically rather than in real time. That's acceptable for a vanity metric, and it eliminates any per-visitor database cost. The entire stats surface area: one integer, one endpoint, one function.
The Increment is Non-Fatal
If the counter increment fails, the share still succeeds. Share creation is the core transaction - the counter is a side effect. The increment is wrapped so that any failure is logged but never surfaces to the user.
This is a general architecture principle worth stating explicitly: observability and instrumentation must never degrade the primary user action. Any telemetry you add to a critical path should be fire-and-forget. A broken analytics call should never break the feature it's measuring.
What We Deliberately Didn't Build
The list of things we chose not to build is as important as the list of things we did:
- No per-user share counts - would require user identifiers
- No daily or weekly breakdowns - would require per-event timestamps
- No geographic distribution - would require IP logging
- No retention or return-visit data - would require session tracking
Each of these would have answered genuinely useful business questions. Each would have required storing data about people. We chose the single integer instead.
Privacy by design isn't a constraint you apply at the end of a project. It's a constraint that shapes what you build in the first place. When you commit to it early, the decisions become simpler - not because they're obvious, but because most of the options simply fall off the table.
Conclusion
The share counter is a small example of what privacy-by-design looks like when it's taken seriously rather than used as a marketing line. It's less powerful than conventional analytics. It answers fewer questions. It also stores nothing about anyone.
For a product built on the premise that your data disappears, that felt like the only coherent choice.