perf(cf): cut KV list/write quota burn on health, tenero, and uncached GETs#993
Merged
Conversation
…V list scans kv.list() ops are the smallest KV quota on the $5/mo plan (1M/mo, $5/M after) and /api/health ran two full prefix scans per hit with no-store. Counts now come from caches.default with a 5-min TTL; connectivity is probed with a single keys-read. Response shape unchanged.
The 5-min refresh wrote every token every tick (~458k KV writes/mo at 53 tokens) against the 1M/mo write quota. Now a comparison read (10x cheaper than a write) gates the put: skip when priceUsd matches and the entry is under TENERO_UNCHANGED_REWRITE_MS (1h) old. The hourly forced rewrite keeps fetchedAt honest for readers and renews the 24h TTL safety net.
Same address always produces the same name, so success responses are cached long + immutable; the self-doc response gets 1h/24h. Repeat hits stop invoking the full handler.
Capability declarations change rarely (signed profile updates). An hour of edge staleness collapses the per-request agents:index KV read and per-agent record fan-out to once per TTL per colo. Errors stay uncached.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
landing-page | 5711a7b | Commit Preview URL Branch Preview URL |
Jun 10 2026, 08:15 AM |
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
Three cost-hygiene fixes from a Cloudflare $5/mo Workers plan audit (pricing verified against Cloudflare docs). Goal: keep the bill at $5 by closing the only realistic paths to overage.
1.
/api/health— stop full KV list scans per hitThe endpoint ran two full cursor-paginated
kv.list()prefix scans (stx:+claim:) on every request, withno-storeso nothing was ever cached. List ops are the smallest KV quota on the paid plan (1M/mo, $5/M after), and this is a public endpoint polled by monitors and agents — cost also doubles automatically once the keyspace passes 1,000 keys/prefix.Now: agent counts are served from
caches.default(5-min TTL, via the existingwithEdgeCachehelper) and KV connectivity is probed with a single keys-read (10M/mo quota). Response shape unchanged, including theagentCountbackwards-compat field; counts can be up to 5 min stale.2. Tenero price refresh — write-on-change
The 5-min refresh wrote every token to KV every tick: ~458k writes/mo at 53 tokens, i.e. ~46% of the 1M/mo write quota from one task. Now a comparison read (reads bill at 1/10th the write rate) gates the put: skip when the price is unchanged and the entry is under 1h old. The hourly forced rewrite keeps
fetchedAthonest and renews the 24h TTL safety net, so a stable token can never silently expire. Verified no reader enforces a freshness threshold onfetchedAtbefore making this change. 3 new tests cover skip / stale-rewrite / changed-price-rewrite.Trade-off: adds ~458k KV reads/mo against the 10M read quota — net strongly positive.
3. Cache-Control on the two fully uncached GET endpoints
/api/get-name: deterministic (same address → same name, no storage reads), nowpublic, max-age=86400, s-maxage=604800, immutable; self-doc response 1h/24h./api/capabilities:public, max-age=300, s-maxage=3600, stale-while-revalidate=86400on all three response shapes, mirroring the/api/agentslist cadence; errors stay uncached. Collapses the per-requestagents:indexKV read + per-agent record fan-out.Testing
npm run lintclean (one pre-existing<img>warning onapp/page.tsx)npm run test: 96 files / 1515 tests passed (incl. 3 new)npm run buildpasses