Rate Limiting Is the First Thing That Breaks When Agents Replace Humans
The Architecture That Survives Agent Traffic
Databricks published the clearest production case study for taking rate limiting off the latency budget. Old path: Envoy → Ratelimit Service → Redis. Two network hops per request. 20-40ms at p99 under contention. New path: in-memory counters with 100ms async batch reporting, server-pushed rejection instructions, zero network calls on the hot path. p99 dropped roughly 10x.
The mechanism is the point. A synchronous shared-store limiter adds a network hop to every request it gates. Under normal load, invisible. When one tenant bursts, Redis becomes the bottleneck for everyone, including the requests you wanted to reject. Stop asking permission on every call. Report counts asynchronously.
A synchronous check against a centralized store is fundamentally incompatible with low-latency requirements once traffic gets large. The network is the bottleneck, not the algorithm.
Why This Matters Now: The Agent Traffic Cliff
Box's CEO projects a 90/10 agent-to-human traffic ratio within three years. Discount the timeline if you want. The direction is confirmed across multiple sources. Limiters keyed on IP or user token degrade under agent load. One agent holding one token issues bursts that look like a DDoS from a logged-in customer. The limiter does what it was configured to do. That is the problem.
Compounding this: reasoning models burn 10-100x the tokens of a plain completion. Personalized prompts break caching because each prompt varies per user. Multi-tenant batching breaks when every call carries user-specific context. The two escape hatches SaaS teams relied on are gone for AI workloads.
The Databricks Design Decisions Worth Copying
Three coupled choices made the system work:
- In-memory token bucket — CAS is free in-memory and expensive over network to Redis. State location constrained algorithm choice.
- Batch-reporting on a 100ms timer — spiky inbound becomes constant outbound. Thundering-herd goes away.
- Server-pushed rejection — "reject key X at Y% until timestamp Z" replaces per-request permission checks.
The ~5% overshoot tolerance is explicit. Their backends already absorb slight over-limit traffic, so the tradeoff is cheap. If your rate limits enforce hard financial or security boundaries, this architecture does not apply. For everything else, which is most traffic, you are paying 20-40ms per request for exact enforcement nobody needed.
Migration Path
They could not modify Envoy, so they ran a localhost sidecar for the batch-reporting client. Before in-memory counters shipped, Redis Lua scripts batched writes as a bridge. Each step shipped value independently. Dependencies forced the order: sharded in-memory first, then batch-reporting to decouple the hot path, then token bucket to leverage in-memory CAS.
What to do
Audit rate limiting hot path for synchronous network calls — if Redis or any shared store sits on every request path, measure actual p99 under tenant burst
Prototype async batch-reporting with 100ms flush interval on your highest-QPS rate-limited endpoint
Stress-test rate limiting at 100x current per-tenant peak to simulate agent traffic patterns
Design separate rate-limit tiers for agent-authenticated vs human-authenticated traffic with different ceilings and different auth mechanisms