BE AWESOME
Settings
Dev Notes
📅 September 17, 2026 · ⏱️ 5 min read

Retiring the One Lifetime Visit Counter for Real Per-Day Data

A single ever-climbing number can't answer whether traffic is growing — and the hot-fix bug that shipped alongside the rebuild that replaced it.

This post is about Retiring the One Lifetime Visit Counter for Real Per-Day Data
Check the Status Page →

The site tracked exactly one number since launch — a single, ever- climbing lifetime visit counter. Today that becomes real per-day tracking for visits and per-game favorite counts, which sounds like a small upgrade and actually meant touching a genuinely large surface area across the backend to get right.

A lifetime counter can't answer the questions that actually matter

A single ever-increasing number tells you the site has been visited some total number of times since launch, and tells you almost nothing useful beyond that. It can't answer whether traffic is growing or shrinking, whether a specific update actually moved the needle, or whether a given day was unusually busy for a reason worth investigating. Every one of those questions requires the data broken down by day, not collapsed into one running total, which is exactly the limitation that made this worth rebuilding rather than just displaying the same lifetime number more prominently somewhere.

Per-day tracking meant a real schema change, not just a new counter

Moving from one running total to genuine per-day records meant the underlying data model had to change, not just the display layer on top of it — a single incrementing counter and a collection of dated daily records are fundamentally different shapes of data to store and query. I built dedicated modules for daily stats and per-game favorites tracking specifically because bolting per-day granularity onto the existing single-counter structure would have meant awkwardly retrofitting date-awareness into code that was never designed to think in terms of individual days at all.

Historical data before today doesn't just disappear, but it doesn't magically gain detail either

The old lifetime counter's total still means something and stays intact — it's simply not being replaced or discarded, just supplemented going forward by genuinely granular data the site didn't used to collect. What it can't do is retroactively tell me what yesterday, or last month, actually looked like day by day, since that detail was never captured in the first place under the old system. Per-day tracking only becomes genuinely useful in hindsight once enough days have actually accumulated under it, which means today's launch is really the start of a dataset rather than a feature that's immediately as useful as it will eventually become weeks from now.

Favorites needed their own per-game breakdown, not just a global count

Knowing that favorites happened site-wide on a given day is less useful than knowing which specific games and tools are actually being favorited, since the whole point of tracking this is understanding what's resonating with visitors well enough to inform what to build or promote next. Building genuine per-game favorite tracking, not just a global daily total, meant the data could actually answer "what's catching on" rather than just "is the site generally active today," which is a meaningfully more useful question for actually making decisions about where to focus effort next.

Batching reads mattered here for the same reason it mattered for leaderboards

Per-day, per-game data multiplies the number of individual records that could theoretically need reading compared to one lifetime counter, and I wanted to avoid the same mistake a naive leaderboard implementation could have made — firing off a separate database read for every individual metric instead of batching related reads together. The stats and favorites modules both batch their reads per request rather than per metric, which is the same underlying lesson the games lobby's leaderboard display already taught me, applied here before it had the chance to become a real performance problem instead of after.

The header and page-level surfaces needed real, small display changes too

Beyond the backend rebuild, this touched genuinely visible surfaces too — a small stats readout added to the game page header, and updates to how the favorites-star interaction reports back what it's tracking. Those small display changes needed to stay honest about what the new per-day data actually represents rather than just showing a bigger, more impressive-looking number pulled from the new system. A stats display that technically shows more precise data but frames it misleadingly would be a worse outcome than the simple lifetime counter it's replacing, even though the underlying data is genuinely richer now than it was before today.

Why this rebuild happened now, and not months earlier

A single lifetime counter was a reasonable, minimal choice for a brand new site with no real history to break down yet. It stopped being reasonable once there was enough site history, enough games, and enough actual traffic pattern to make per-day and per-game breakdowns genuinely useful rather than a premature optimization for data that didn't really exist yet. Rebuilding this today, once real content and real growth actually existed to analyze, made far more sense than building the more complex version back when there was barely enough history to make it worth the added complexity.

The bug that shipped alongside the rebuild, and why I'm not hiding it

A real bug shipped with this rebuild that briefly miscounted visits right after the new tracker went live, which I caught and fixed quickly, and I want to mention it here rather than pretend today's launch was clean. Rebuilding a core piece of tracking infrastructure that's been running one simple way since the site's first day carries real risk of exactly this kind of transition bug, and I'd rather be upfront that it happened than let the update log's brief mention of a "hot fix" stand in for the actual story of what went slightly wrong on the way to something better.

Rebuilding infrastructure this fundamental is inherently riskier than shipping a new, self-contained feature, since a mistake here doesn't just affect one page, it affects the numbers every future decision about the site will partly rely on. I'd rather ship this carefully, catch a bug quickly, and be transparent about it than move slower out of fear of exactly this kind of transition issue and never actually replace a system that had already outgrown what it was originally built to do.

Hello!