perf(cache): LRU eviction, store-hit metric, peek() probes, bigger char cap - #177
Merged
Conversation
…ar cap
The Grafana cache panels showed ~4% hit ratios with the character cache
pinned at its 500 cap. Investigation: most "misses" were served instantly
by census_store (invisible to the metrics), bulk lookup probes counted
misses they never act on, and eviction was FIFO-by-insert so roster
floods cycled out the hot working set.
- cache_store_hits_total{cache}: incremented where a memory miss is
served from the durable census_store (character/guild/aa/gear-sets) —
dashboards can now split misses into store-absorbed vs Census fetches.
- TTLCache eviction is LRU-by-access: get/get_stale and overwrites move
the entry to the back of the eviction queue.
- peek(): metric-free, side-effect-free read for opportunistic probes;
/api/characters/lookup's 50-name sweep uses it so enrichment probes
stop polluting hit ratios and LRU order.
- character_cache maxsize 500 -> 2000 (guild rosters + startup prewarm
exceeded 500 combined; entries are a few KB, ~10-20 MB worst case).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to the Grafana cache investigation: hit ratios read ~4% with the character cache pinned at its 500 cap, but most "misses" were false positives — served instantly from census_store, which the metrics couldn't see.
cache_store_hits_total{cache}: new counter incremented where a memory miss is served from the durable census_store (character / guild / aa / gear-sets read paths). Dashboards can now split misses into store-absorbed vs real Census fetches (rate(cache_misses_total) − rate(cache_store_hits_total)≈ true fetch pressure).get/get_staleand overwrites now move entries to the back of the eviction queue.peek(): metric-free, side-effect-free read for opportunistic probes./api/characters/lookup's 50-name enrichment sweep uses it, so probe misses (which never fall through to anything) stop polluting hit ratios and LRU order.Testing
9 new TTLCache tests (LRU survival on read/overwrite, peek fresh+stale semantics without metrics or LRU side effects, hard-expiry, store-hit counter) + lookup-endpoint mocks updated. Full suite 1611 passed, pyright clean. Frontend untouched.
🤖 Generated with Claude Code