Skip to content

Demo: shared Workers KV answer cache and 60/min cap - #8

Merged
Karthick-Ramachandran merged 3 commits into
mainfrom
demo/kv-cache
Sep 23, 2026
Merged

Karthick-Ramachandran merged 3 commits into
mainfrom
demo/kv-cache

Conversation

@Karthick-Ramachandran

Copy link
Copy Markdown
Owner

ADR-0010 (supersedes ADR-0009).

  • Cap: global limit 30 -> 60 searches/min for launch traffic; per-IP stays 10/min.
  • Cache: isolate memory, then Workers KV shared by all isolates; KV writes go through ctx.waitUntil. The library is unchanged.
  • Verified on production: after a redeploy (fresh isolates), a repeat store search took 3 ms and 0 tokens instead of 714 ms and 2,960; Acme hit, Globex missed. KV entries hold answers only, no search text or secrets.
  • 9 new tests for the KV store, plus docs.

The Worker is already deployed from this branch; the landing FAQ change needs a Pages deploy after merge.

🤖 Generated with Claude Code

- Global rate cap 30 -> 60 searches/min for launch traffic (per-IP stays
  10/min); worst case ~$8-11/day.
- Two-level answer cache in the demo Worker: isolate memory, then the
  ANSWER_CACHE KV namespace shared by all isolates. KV writes are handed
  to ctx.waitUntil so the runtime doesn't cancel them after the response.
  Failing/slow KV falls back to memory or a miss. The library is unchanged;
  the adapter shows how an external store plugs into CacheStore.
- Verified: 9 unit tests (cross-isolate, tenants, failures); local
  restart test; production redeploy test (714 ms/2,960 tokens -> 3 ms/0,
  Acme hit, Globex miss); KV entries read back contain answers only.
- Docs: README and landing FAQ explain sharing the cache across servers
  and what stored entries contain; security model, lessons (waitUntil),
  tasks and cards point at ADR-0010.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Mutation-tested demo/test/kv-cache.test.ts with five deliberate breaks;
  the "junk object accepted from KV" break slipped through (the test only
  used a junk string). The test now covers six junk shapes and catches it.
- CI runs demo/test/*.test.ts (no extra install needed).
- Re-ran the full live security check on the KV-enabled Worker (clean).
- Recorded that Cloudflare's rate limiter is approximate in bursts (first
  429 after 12-27 requests at a 10/min limit), so the spend estimate is
  not a hard ceiling; listed what remains untested.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Answers "can users set up Redis?": yes, through the existing CacheStore
interface. The README snippet is the exact code that was typechecked
(strict, no skipLibCheck) and run against a real Redis with jevfilter@0.1.1
from npm: second process hit in 21 ms with 0 tokens, other tenant missed,
Redis frozen or stopped still returned correct filters.

The first draft of the snippet did not compile (node-redis generics vs
ReturnType<typeof createClient>); it now types the client by the two
methods it uses. Lesson recorded.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Karthick-Ramachandran
Karthick-Ramachandran merged commit 46c6762 into main Sep 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant