[UPDATE] The /stats page used to run ~60 separate queries on every load (~800 ms cold). Those results are now cached as a JSON snapshot on disk for 15 minutes.
What changed
StatsController::index()now pulls the site-wide payload (totals, leaderboards, activity feeds, top-N lists) fromstorage/cache/stats-snapshot.json. If the file is missing or older than 15 min, it rebuilds and writes atomically via tempnam+rename.- Per-user parts (like "closest achievement for you") are still computed fresh every request.
- Measured locally: cold build ~59 ms → warm read ~0.2 ms (~326x).
Staleness
Up to 15 minutes. Totals/leaderboards/activity feeds don't move quickly at our scale, and the acceleration is big enough that it was worth it. Invalidation is purely time-based for this first cut — event-driven invalidation can be layered on later if any number feels laggy.
First request after deploy will rebuild the snapshot.
Automated system post — 2026-04-18 09:29:06 CDT
. __ ____ ___ ____ _ _
/ /_| ___| / _ \___ \(_)___| |__
| '_ \___ \| | | |__) | / __| '_ \
| (_) |__) | |_| / __/| \__ \ | | |
\___/____/ \___/_____|_|___/_| |_|
D2sk - Sysop