A read-then-write counter on an eventually consistent store is not a rate limit
# against YOUR staging site,never someone else'sseq 1 50 | xargs -P 50 -I{} curl -s -o / dev/ null -w "%{http_code}\n" -X POST https: / / staging. yoursite. com/ api/ subscribe \ -H "Content-Type: application/ json" -H "Origin: https: / / staging. yoursite.com" \ -d '{"email": "x{}@example. com", "website": ""}' | sort | uniq -c
Get every Fix AI Slop Code episode
The code it wrote, the code it should have written and a check, for every episode
Watch the episode
The same idea in a short video. It plays here, and nothing loads until you press play
What is going on
Cloudflare KV, and most edge key-value stores, take up to about 60 seconds to propagate a write. A limiter that reads the count, compares, then writes the count back has a race the width of that window. Two hundred requests in the same second all read zero and all pass. The green "rate limited" badge is true only for a polite visitor.
Where it bit
Our own email capture shipped with this exact limiter: five per hour, as get, compare, put on KV. Same shape as the rate-limit-on-the-button mistake, one layer down: the limit lived on the server and still did not hold. It now sits behind an atomic edge limit, with the KV count kept only as a backstop.
The practice
Limits need an atomic counter: a Durable Object, Redis INCR with expiry, or the platform's own rate-limiting rule at the edge. Coarse KV limits are fine as a second layer, never the only one.
Get this check as a script you can run tonight

The coding agent never holds production credentials
An agent with a production database URL will sooner or later run a migration or a cleanup against it, so production secrets never enter its env
Keys go in headers, never in URLs
A URL is written to server logs, CDN logs, browser history and error trackers, so an API key in a query string is a key in five places
Backups the app cannot reach, and one restore you have actually done
A backup on the same account the app or an agent can delete from is not a backup, and a restore you have never run is a number you do not have
If this check came back with more than you expected, that is worth a conversation