Observed since 20 Oct, 19:56 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
AdVal adaptive in-memory cache SDK — value-scored, freshness-aware, zero dependencies.
A cache that knows the difference between a $0.31 recommendation vector and a stock ticker that is worthless two seconds after you store it.
LRU asks when did you last touch this. LFU asks how often. Neither asks the only question a bill cares about: what does losing this actually cost me? In a real service that answer spans four orders of magnitude — a free 4 MB product image against a ten-second, fifty-cent ML inference. AdVal-Cache computes a per-object value score from access pattern, resource footprint, regeneration cost and data volatility, then decides retain / evict / refresh / decline — and separately decides, in dollars, when buying more cache capacity is worth the rent.
python -m venv venv; venv\Scripts\activate; pip install -r requirements.txt
python -m benchmarks.run_all --seed 42 # 80 cells in ~4 min -> results/report.md
streamlit run dashboard/app.py # playback dashboard
Everything is a deterministic simulation: no network, no Redis, no Docker, CPU only. Same seed ⇒ byte-identical traces, results and charts.
60 simulated minutes per scenario, seed 42. The problem statement's baselines are LRU, LFU and GDS; exact GDSF ships alongside because it is stronger than the brief requires (D29).
AdVal is cheaper and fresher than the best baseline in 8 of 8 cells.
| scenario / profile | best baseline | baseline $ | AdVal $ | saving | baseline fresh | AdVal fresh | pre-D31 base $ | pre-D31 AdVal $ |
|---|---|---|---|---|---|---|---|---|
| chaos / compute_heavy_rec | gds | 2854.48 | 2816.52 | 1.3% | 66.2% | 78.5% | 98.91 | 124.13 |
| chaos / read_heavy_api | gds | 1086.05 | 986.37 | 9.2% | 64.2% | 74.2% | 98.91 | 117.41 |
| gradual_shift / compute_heavy_rec | gds | 3034.96 | 2989.81 | 1.5% | 67.1% | 80.2% | 98.91 | 124.51 |
| gradual_shift / read_heavy_api | gds | 1046.89 | 923.08 | 11.8% | 64.7% | 77.7% | 98.91 | 123.12 |
| steady / compute_heavy_rec | gds | 4275.14 | 4235.45 | 0.9% | 59.7% | 73.1% | 98.91 | 122.15 |
| steady / read_heavy_api | gdsf_exact | 1282.12 | 1142.86 | 10.9% | 57.9% | 70.8% | 100.01 | 120.88 |
| viral_spike / compute_heavy_rec | gds | 4850.61 | 4802.40 | 1.0% | 60.2% | 72.6% | 98.91 | 124.59 |
| viral_spike / read_heavy_api | gds | 1877.68 | 1755.22 | 6.5% | 47.1% | 56.0% | 98.91 | 120.20 |
The cost model used to bill compute and memory and nothing at all for serving a customer
stale data. Nobody decided that; it is what you get by leaving wrong answers unpriced,
and it meant a cache-freshness system was scored on everything except the thing it does —
gds won on cost by serving 75,526 wrong answers an hour for free.
D31 fixes it on a principle rather than a knob: a stale hit is not a hit, it is a miss
you failed to notice, so it is charged the regen_usd of the very object it displaced.
The price is read per object out of the catalog, billed by the simulator so every policy
pays the same for the same event, and measured at $0.0077–$0.186 per stale serve. That is
7–170x the ~0.11 cent break-even, which is why the ranking flips.
On the old model gds is still cheaper — that is the pre-D31 pair above, kept in
summary.csv as total_usd_compute_only in every run, and
python -m benchmarks.run_all --stale-mult 0 reproduces it exactly (a test asserts it).
The honest caveat: at the shipped price the staleness bill is ~10x compute plus memory, so
the ranking now rests mostly on this one priced assumption. The full flat-price sweep,
including where AdVal loses, is in results/dominance.md.
Savings are 6.5–11.8% on read_heavy_api and only 0.9–1.5% on compute_heavy_rec, where
slow-changing ml_result objects dominate the staleness bill for every arm alike.
Separately from the cost model, results/dominance.md:
gds serves 75,526 stale responses at 100 MB and
75,526 at 500 MB while its hit rate climbs 81.6% → 93.9%. AdVal at 100 MB is cheaper
and 12.2 pp fresher than gds at 500 MB.Against LRU and LFU, AdVal is 92–99% cheaper on either model. It still loses on tail
latency — 158 ms p95 against 55 ms — because refreshing on read is not free. Full tables,
timelines, the ablation ladder and an auto-generated "where this result is weakest"
section: results/report.md.
score(i) = hotness(i) × pain(i) × freshness(i) / size_units(i)
c ← 1 + c·e^(−λΔt), λ = 0.001 (half-life ≈ 693 s);
recency at short lags, frequency at long ones, one number.exp(−(now − last_sync) / change_interval), which for a Poisson
mutation process is exactly P(the cached copy is still valid). Multiplying a value
by a probability gives an expected value, which is the right thing to rank by.
Exactly 1.0 for immutable objects and anything slower than 1800 s.log1p(bytes / 1 KB), so 5 MB is penalised ~12× rather than ~5000×.
Large objects must justify themselves; they are not banned.Two runtime loops keep it from being a set of hardcoded constants:
steady picks
freq_heavy; chaos picks fresh_heavy. Nobody told it which signal matters.ARCHITECTURE.md has the decision-engine diagram and the full justification.
models.py THE CONTRACT: Request, CatalogEntry, object classes, ops, constants
proxy/ FastAPI reverse proxy sidecar · live cache engine · traffic generator
database/ Neon PostgreSQL client · schema · real-world dataset ingestion pipeline
cache/ base (interface, sampling, event sink) · lru · lfu · gdsf · adaptive · controller
generator/ catalog · popularity modes · scenario engine · trace writer · validator
sim/ simulator (replay + window aggregation) · metrics (the only cost model)
benchmarks/ run_all (the 80-cell matrix) · report (tables, charts, honest caveats)
dashboard/app.py Streamlit control center: batch replay scrubber & live dynamic proxy mode
web_adval/ React/Vite standalone web control UI mounted on proxy port 8000
traces/ trace samples & Postgres query trace generator
tests/ unit & integration tests: core, live cache, and proxy API
results/ event logs, window CSVs, summary.csv, report.md, charts/
python -m generator.validate --minutes 60 --seed 42 # 9 workload checks, ~6 s
python -m pytest -q # 63 tests, ~8 s
python -m benchmarks.run_all --seed 42 # 80 cells, ~4 min
generator/validate.py is the workload referee: it asserts the arrival-rate curve
matches the scenario spec within 4σ on all four scenarios, that the top-10 popular keys
genuinely rotate during gradual_shift (0 shared keys), that the reuse working set is
4.05× cache capacity (a cache that never fills has no story), that static_asset is
99.4% of bytes but only 30.1% of requests, and that seed 42 reproduces byte-identical
files. A cache benchmark is only as honest as its workload.
| file | what is in it |
|---|---|
ARCHITECTURE.md | decision-engine diagram, every term of the score justified, the two adaptive loops |
results/report.md | generated results: headline tables, charts, ablation, capacity fairness, weaknesses |
DECISIONS.md | 22 numbered assumptions and corrections, including two places the problem statement's own numbers disagree, three bugs that only a benchmark could have caught, and one metric that was measuring the wrong thing |
DEMO.md | the scripted 5-minute walkthrough, with fallbacks |
FORMATS.md | every on-disk schema: catalog, trace, change stream, event log, window CSV |
PROGRESS.md | phase-by-phase build log with the ACCEPT evidence for each |
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 5 Sept 2026 | 8 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 19:56 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:e3291af5363299c309b8a35503af12eba5eef8908d61526b9da9a18f3a405aa9