🛡️ Portarus: the gateway for AI agents Discover more →
Engineering

Rate Limiting AI Agents to Prevent Bot Abuse

Turn a 3am retry storm into a non-event.

Orlando Quijada · · 7 min read
A 3am burst of bot requests hitting a token-bucket rate limiter at the Portarus gateway, letting a steady clean stream reach the AI agent
  • An uncapped retry loop can run an agent 10,000× overnight before anyone notices.
  • A rejected request costs ~0; a processed one costs an execution plus a model call.
  • A token bucket absorbs a human burst while capping the sustainable average.

The problem

  • Every uncapped request is a real execution and a real model call.
  • Retry storms, bot abuse and runaway loops run at full speed and full cost.
  • An integration stuck in a loop overnight is an unbounded bill before anyone's awake.

The solution

Cap how fast a sender can hit the agent — and reject the excess cheaply.

Pick an algorithm, set a rate, and enforce it in front of the agent, not inside it.

  1. Default to a token bucket — it absorbs a short human burst, caps the sustainable average.
  2. Limit per sender (stop one abuser) and globally (survive a broad spike).
  3. Reject the excess with 429 + Retry-After so good clients back off.

A rejected request costs almost nothing; a processed one costs an execution plus a model call.

Result: the 3am flood is throttled, not billed.

See the full fix
A closer look

The incident always happens at 3am: a misconfigured integration starts retrying in a loop, or a bot discovers your webhook, and by morning your AI agent has run ten thousand times and your bill has a new digit. Rate limiting is the control that turns that night into a non-event. Here is how to do it right, and the two places you can enforce it.

What rate limiting protects against

Rate limiting caps how many requests a sender can make in a given period. Three sources produce the floods it stops: retry storms (a downstream failure makes an integration retry endlessly), bot abuse (an automated client hammers your public webhook), and runaway loops (two systems trigger each other in a cycle nobody noticed until the invoice arrived). Without a limit, all three run at full speed and full cost. With one, the excess is rejected cheaply instead of processed expensively.

Three rate-limiting algorithms

The right choice depends on how bursty your legitimate traffic is.

AlgorithmHow it worksBest forWeakness
Fixed windowN requests per clock intervalSimple, low-traffic agentsBursts at window edges
Sliding windowN requests per rolling intervalSmoother enforcementSlightly more state
Token bucketTokens refill at a steady rate; each request spends oneBursty but bounded trafficNeeds tuning

Fixed window is simplest: allow N per minute, reset on the minute — but a sender can fire N at 0

and N more at 1
, doubling the rate for an instant. Sliding window counts over the last rolling interval, smoothing that edge at the cost of a little more bookkeeping. Token bucket holds tokens that refill at a steady rate and each request spends one — it allows a short legitimate burst while enforcing a sustainable average. For AI agents with naturally bursty human traffic, it’s usually the best fit.

When a sender exceeds the limit, reject with 429 Too Many Requests and, where you can, a Retry-After header — the standard signal well-behaved clients understand.

The manual fix (Option 1)

You can implement any of these in your own middleware — but the state is where it gets hard.

Fix 1: pick an algorithm and enforce it

A token bucket for most agents, sized above your real per-sender peak, then tightened.

On a gateway, the algorithm and rate are choices you set, not code you ship.

Fix 2: back it with a shared, fast counter store

The limit needs a store for counters (per sender, per window) that’s fast, shared across instances, and correct under concurrency.

On a gateway, the counter state is managed for you, in front of everything.

The catch: you replicate it at every entry point

Every channel and workflow your agent exposes needs the same limiter, sharing the same counters — so the DIY path is not one limiter but a distributed system you own and keep correct as you add channels.

Place a gateway layer (Option 2) — faster

A message gateway applies the limit once, in front of everything, with the counter state managed for you. You choose the algorithm and the rate; the gateway enforces it on every channel. It runs alongside token budgeting, its natural partner against oversized input — see token floods.

Option 1 (DIY) vs Option 2 (gateway)

 Do it yourselfUse a gateway
Choose algorithm & rate ✓Full control ✓A setting you pick
Shared counter store ✕You build & host ✓Managed for you
Concurrency under load ~Yours to get right ✓Handled
Every entry point ~Replicate the limiter ✓One layer, all channels
Reject cost (429) ✓Near zero ✓Near zero, before the agent
Control of internals ✓Full ~Abstracted away

The full set of input-layer defenses is in the complete guide to message quality for AI agents.

If option 2 sounds more like you, here’s the short version of how to set it up: cap abusive senders before the agent →.

Either way — go make a 3am retry storm a non-event.

Thanks for reading. 👋

Orlando. -

Found this helpful? Share it with someone who needs it

OQ

Orlando Quijada

Technologist with 15+ years of experience. Developer, SaaS tester, and AI collaboration & optimization specialist. Currently contributing at portarus.com.

Written on

What to read next