> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limiter Requirements and Estimation

> A guide to designing a rate limiter covering identification methods, limits and responses, storage and traffic estimations, algorithms and deployment implications for protecting APIs from abusive clients.

In this lesson we design a rate limiter — a component that protects APIs and services from noisy clients who make too many requests in a short time. Rate limiting is essential for systems like public APIs, URL shorteners, and large web services (e.g., ChatGPT, Claude) to maintain performance and protect backend resources.

We’ll use a simple six-step design framework. Step 1 is clarifying requirements; step 2 is a back-of-the-envelope estimation. The content below follows that sequence, with code samples and diagrams retained in their original position.

Example attacker script (simple abusive client that posts repeatedly):

```bash theme={null}
# shadow — bash
U=shortlink.io/api/create
while true; do
  curl -sX POST $U -d url=example.com
done
```

This could create millions of junk records and degrade service for normal users. We need a rate limiter that can slow down or block such noisy clients.

## Step 1 — Clarify requirements (ask these questions)

1. How do we identify who is making an API call?

Common identifiers:

* Account ID (logged-in users)
* IP address
* API key

Each approach has trade-offs. Use the table below to summarize these trade-offs for quick interview answers.

| Identifier | When to use | Trade-offs |
| - | - | - |
| Account ID | Logged-in users | Accurate for individual users; does not apply to unauthenticated traffic |
| IP address | Anonymous users | Works for unauthenticated clients; shared IPs (e.g., NAT) can unfairly aggregate users; easy for attackers to rotate |
| API key | Developer APIs | Precise for service-to-service or developer integrations; not applicable to general app users |

For this design exercise we assume:

* Count per account for logged-in users.
* Count per IP for non-logged-in requests.

2. What is the limit per user?

For this example we’ll set a limit of 100 requests per minute per user.

<Callout icon="lightbulb" color="#1CB2FE">
  In interviews, avoid pretending limits are production-ready. Say you would measure real traffic (requests/minute per user) and set thresholds to sit comfortably above typical usage while protecting the system.
</Callout>

3. What should happen when the limit is exceeded?

Two main approaches:

* Queue excess requests and process later.
* Reject excess requests immediately.

Queuing can be useful in some contexts but introduces risk: clients often retry on slow or timed-out requests, which can create duplicates and extra load when the queue drains. For many APIs, rejecting excess requests with HTTP 429 and a `Retry-After` header is safer and clearer.

<Callout icon="warning" color="#FF6B6B">
  Queuing excess requests can lead to duplicate operations if clients retry while waiting. For most APIs, it's preferable to reject excess requests with a clear HTTP 429 response and an explicit retry window.
</Callout>

Summary of scope for this design:

* Limit: 100 requests per minute per user.
* Identification: by account for logged-in users, otherwise by IP.
* Behavior: reject excess requests with a clear response (HTTP 429 + `Retry-After`).

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/FNsK4qjOEH3p_rqy/images/System-Design-for-Interview-Prep/Warm-Ups-The-Read-Heavy-Classics/Rate-Limiter-Requirements-and-Estimation/rate-limiter-100min-user-app-db.jpg?fit=max&auto=format&n=FNsK4qjOEH3p_rqy&q=85&s=87e0869dcb0673ccf596d21c32823e4c" alt="A dark-themed architecture diagram showing a user (labelled &#x22;alan&#x22; with IP 203.0.113.7) sending requests through a rate limiter (100/minute) to an app server and database. Notes on the right state limits are applied by account or IP, 100 per minute per user, and rejected requests include a reason." width="1920" height="1080" data-path="images/System-Design-for-Interview-Prep/Warm-Ups-The-Read-Heavy-Classics/Rate-Limiter-Requirements-and-Estimation/rate-limiter-100min-user-app-db.jpg" />
</Frame>

Normal users should be unaffected by the rate limiter — it operates transparently for typical usage and only intervenes when a client exceeds the agreed-upon threshold.

## Step 2 — Back-of-the-envelope estimation

Only estimate numbers that affect architecture choices (memory, throughput, peak QPS, etc.). Two key numbers for this design are: storage per user, and total request rate hitting the rate limiter.

### 1) Storage per user

A minimal per-user state for a fixed-window or sliding-window counter typically stores:

* a numeric counter
* a timestamp for the window start or last update

Estimated size: \~50 bytes per user (counter + timestamp + small metadata). Use this to reason about memory requirements.

Example estimate:

* 10,000,000 active users × 50 bytes/user ≈ 500 MB — small enough to store in memory on one reasonably sized server if desired, or sharded across multiple instances.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/FNsK4qjOEH3p_rqy/images/System-Design-for-Interview-Prep/Warm-Ups-The-Read-Heavy-Classics/Rate-Limiter-Requirements-and-Estimation/stored-per-user-50b-10m.jpg?fit=max&auto=format&n=FNsK4qjOEH3p_rqy&q=85&s=fd4db85000c73d318a3e8391489f9046" alt="A dark-themed dashboard slide titled &#x22;Stored per user&#x22; showing a user's counter (Count: 42, Since: 10:41) and a storage estimate of 50 B/user scaled across 10,000,000 users with a 500 MB usage bar. Small &#x22;interviewer&#x22; and &#x22;you&#x22; user icons appear at the bottom." width="1920" height="1080" data-path="images/System-Design-for-Interview-Prep/Warm-Ups-The-Read-Heavy-Classics/Rate-Limiter-Requirements-and-Estimation/stored-per-user-50b-10m.jpg" />
</Frame>

Keep the \~50 B/user estimate in mind for capacity planning. If you use richer data (sliding logs, per-minute buckets), memory increases accordingly.

### 2) Request traffic (QPS estimate)

Example scenario:

* 10,000,000 users, average 100 requests/day per user ⇒ 1,000,000,000 requests/day total.

Convert to QPS and peak:

* 1,000,000,000 requests/day ≈ 11,574 requests/second (≈ 12k RPS) average.
* If peak = 3× average, peak ≈ 35,000 RPS.

Use the table below for quick conversions you can present in an interview:

| Metric | Calculation | Result |
| - | - | - |
| Total/day | 10,000,000 × 100 | 1,000,000,000 requests/day |
| Avg RPS | 1,000,000,000 / 86,400 | ≈ 11,574 ≈ 12k RPS |
| Peak RPS (3×) | 12k × 3 | ≈ 35k RPS |

Important clarification: the "100 requests/day per user" is an average activity metric — not the per-minute throttle. The per-minute limit (100/min) protects against short bursty abuse; normal users typically generate far fewer than 100 requests in a single minute.

## Design implications (short checklist)

* Memory: \~50 B/user (adjust if design uses buckets or logs).
* Throughput: design rate limiter to handle average and peak RPS (e.g., 12k average, 35k peak in the example).
* Placement: rate limiter should be on the request path (edge or API gateway) to protect downstream services.
* Failure handling: fail-open vs fail-closed — prefer fail-open only if downstream can rate-limit again; otherwise fail-safe decisions depend on SLA.
* Responses: use HTTP 429 + `Retry-After` to guide clients.

## Links and further reading

* HTTP 429 Too Many Requests: [https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429)
* Common rate limiting algorithms: Token Bucket, Leaky Bucket, Fixed Window, Sliding Window
* Implementations and patterns: Redis-based counters, in-memory sharded counters, API gateways with built-in rate limiting

Use these talking points and numbers in interviews: they show you understand identifications, limits, client behavior trade-offs, storage and traffic estimation, and how to translate those estimates into capacity and placement decisions.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/system-design-for-interview-prep/module/bf4e82c2-1292-42c6-b85f-8b6a0dad559f/lesson/ace026cf-8739-4364-bdb1-324c87030190" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.