Cloud · Scale & Traffic · DWG NO. 037

Rate Limiting / Throttling

Cap how much traffic a client can send in a given window, so one caller can't exhaust capacity meant for everyone.

TypeScale/Traffic
ScopePer-client or per-API request rate
ComplexityLow–Medium
Common inPublic APIs, multi-tenant platforms, abuse prevention

One noisy client can starve every other client

Without a cap, one misbehaving script — or one tenant with an unusually bursty workload — can consume enough of a shared API's capacity that other, well-behaved clients start seeing slow responses or errors, even though they did nothing wrong.

A token bucket per client

Each client gets a bucket that refills with tokens at a fixed rate, up to a cap. Every request consumes one token; a request with no tokens available is rejected (or delayed) until more refill. This allows small bursts while still capping the sustained rate.

Client requestsconsume tokenToken Bucketrefills over timeallowed429 rejectedHandlerRejected

A token bucket rate limiter

Tokens refill continuously based on elapsed time; a request is only allowed if at least one token is currently available.

token-bucket.js
class TokenBucket {
  #capacity; #tokens; #refillPerMs; #lastRefill;

  constructor(capacity, refillPerSecond) {
    this.#capacity = capacity;
    this.#tokens = capacity;
    this.#refillPerMs = refillPerSecond / 1000;
    this.#lastRefill = Date.now();
  }

  #refill() {
    const now = Date.now();
    const elapsed = now - this.#lastRefill;
    this.#tokens = Math.min(this.#capacity, this.#tokens + elapsed * this.#refillPerMs);
    this.#lastRefill = now;
  }

  tryConsume() {
    this.#refill();
    if (this.#tokens >= 1) {
      this.#tokens -= 1;
      return true;
    }
    return false;
  }
}

const bucket = new TokenBucket(5, 1); // 5 burst capacity, refills 1/sec

for (let i = 1; i <= 7; i++) {
  console.log(`request ${i}: ${bucket.tryConsume() ? "200 OK" : "429 rate limited"}`);
}

Trade-offs