

Software Architect
Pós-graduado em arquitetura de software e soluções. Conecto profundidade técnica com resultados de negócio para entregar produtos que as pessoas realmente usam. Também mentoro desenvolvedores e criadores em programas ao vivo, podcasts e iniciativas de comunidade focadas em tecnologia inclusiva.
Productos gratuitos y de pago para convertir ideas en una base que puedas lanzar.
11 productos disponiblesContinúa explorando temas similares

A production-grade system design for building recommendation platforms at internet scale, covering candidate generation, retrieval, ranking, feature stores, online inference, real-time feedback loops,

A comprehensive system design guide for building a payment processing platform like Stripe, handling millions of transactions with exactly-once semantics, double-entry ledger, idempotency, fraud detec

Um guia completo de system design para construir uma plataforma estilo Dropbox ou Google Drive com upload resumível, chunking, deduplicação, metadados, cursores de sincronização, compartilhamento,...
Una lista de 47 puntos para encontrar errores, riesgos de seguridad y problemas de rendimiento antes del lanzamiento.
Templates probados en producción, usados por desarrolladores. Ahorra semanas de setup en tu próximo proyecto.
At 09:00 AM, your API receives normal traffic. At 09:01 AM, a broken client release starts retrying every request with zero backoff. At 09:02 AM, one enterprise tenant launches a data backfill. At 09:03 AM, a botnet starts credential stuffing.
Without rate limiting, everything shares the same blast radius.
With weak rate limiting, the wrong users get blocked and abusive traffic still leaks through.
A good rate limiter is not just a counter. It is a control system that protects fairness, cost, and availability:
This guide covers a production architecture that interviewers expect from senior candidates.
Rate limiting scope must be explicit. Are you protecting one endpoint, an API gateway, or all service-to-service traffic? Are limits hard-blocking or soft-throttling? Is billing involved?
| Requirement | Target | Why it matters |
|---|---|---|
| Decision latency | < 5ms p99 at gateway | limiter cannot become bottleneck |
| Availability | 99.99% decision path | protects mission-critical APIs |
| Throughput | millions of checks/sec | every request may be checked |
| Correctness | bounded error on distributed counters | fairness and billing trust |
| Update propagation | < 30s policy propagation | operational agility |
| Isolation | noisy tenants contained | protect shared platform |
API requests/day: 90 billion
Average RPS: ~1,041,667
Peak RPS: 6,000,000
Requests requiring limiter check: 100%
Unique active API keys/day: 80 million
Rate-limit policies: 300,000 active rules
Limiter checks/sec average ~= 1.04M
Peak ~= 6M checks/sec
Assume each check includes:
- key parsing and policy lookup
- counter operation
- decision response
At 6M checks/sec, single centralized node is impossible.
Need horizontal partitioning and edge-local acceleration.
If active keys in short windows are 80M and each counter state is ~120 bytes:
80M * 120B ~= 9.6GB hot state per primary window
With replicas and multiple dimensions, practical memory need is much higher.
If we sample 10% of decisions and each log is 180 bytes:
90B * 0.1 * 180B ~= 1.62TB/day raw sampled logs
The primary challenge is not writing one algorithm. It is building a low-latency, low-error distributed decision system under traffic spikes and partial outages.
Rate limiting algorithms are workload-dependent.
| Algorithm | Precision | Cost | Burst Support | Typical Use |
|---|---|---|---|---|
| Fixed window | low-medium | low | weak | simple limits |
| Sliding log | very high | high | medium | small-scale precision needs |
| Sliding counter | high | medium | medium | common API limits |
| Token bucket | high | low-medium | strong | gateway traffic shaping |
| Leaky bucket | medium | medium | controlled | smooth downstream load |
A rate limiter must return structured decisions for clients and observability.
POST /internal/v1/limit/check
Request:
{
"request_id": "req_901",
"subject": {
"tenant_id": "t_44",
"api_key_id": "k_77",
"user_id": "u_12",
"ip": "203.0.113.8"
},
"resource": {
"route": "/v1/payments",
"method": "POST",
"service": "payments-api"
},
"context": {
"region": "us-east-1",
"risk_score": 0.14
}
}
Response:
{
"decision": "ALLOW",
"applied_policy_id": "policy_payments_post_tier2",
"remaining": 127,
"reset_after_ms": 1820,
"retry_after_ms": 0,
"reason": "WITHIN_LIMIT",
"limit_headers": {
"x-ratelimit-limit": "200",
"x-ratelimit-remaining": "127",
"x-ratelimit-reset": "2"
}
}
Deny example:
{
"decision": "DENY",
"applied_policy_id": "policy_payments_post_tier2",
"remaining": 0,
"reset_after_ms": 780,
"retry_after_ms": 780,
"reason": "TOKEN_BUCKET_EMPTY"
}
Key design determines partition distribution and fairness behavior.
rl:{policy_id}:{tenant_id}:{api_key_id}:{route_hash}:{window_bucket}
{
"policy_id": "policy_payments_post_tier2",
"scope": {
"tenant_tier": "PRO",
"route": "/v1/payments",
"method": "POST"
},
"algorithm": "TOKEN_BUCKET",
"config": {
"capacity": 200,
"refill_per_sec": 50
},
"mode": "HARD",
"fail_behavior": "FAIL_CLOSED",
"priority": 900,
"enabled": true,
"updated_at": "2026-02-22T22:10:00Z"
}
{
"quota_tree": [
{
"level": "TENANT",
"limit": "50000/min"
},
{
"level": "API_KEY",
"limit": "1000/min"
},
{
"level": "ROUTE",
"limit": "200/min"
}
]
}
The lowest-latency architecture puts first-stage checks directly in gateway workers.
Pure local limiters are fast but less globally accurate. Hybrid mode balances speed and correctness.
For plan billing and cross-region quota, you need shared counters or coordinated state.
Common Redis pattern with Lua script:
-- Pseudo Lua for token bucket consume
-- keys: bucket state key
-- args: now_ms, capacity, refill_rate, requested_tokens
Shard by hash(policy + subject key) for distribution.
If exact global atomicity is impossible within latency budget, use:
Global quotas are common in enterprise pricing.
A tenant has 1,000,000 req/day globally, traffic split across 6 regions.
Bursts are normal and often legitimate.
Use dual limits:
ALLOW only if:
burst_limit_passed AND sustained_limit_passed
For denied responses, return Retry-After with slight jitter to avoid synchronized retry storms.
Rate limiting is often part of product packaging.
| Plan | Global limit | Burst limit | Premium routes |
|---|---|---|---|
| Free | 60 req/min | 10 req/5s | no |
| Pro | 3,000 req/min | 200 req/5s | yes |
| Enterprise | custom | custom | yes |
Policy changes should propagate quickly without restarting gateways.
Static limits are insufficient against abuse waves.
if risk_score > 0.9:
tighten limit by 80%
elif risk_score between 0.7 and 0.9:
tighten by 40%
else:
default plan limits
Rate limiting interacts with retries and idempotent writes.
For idempotent write APIs, duplicate retries with same idempotency key should not double-charge quota unfairly (depending business rule).
Need short-lived dedupe cache for (api_key, idempotency_key, route).
Attackers rotate identifiers.
DENY if any hard dimension exhausted:
- api_key bucket
- tenant bucket
- ip reputation threshold
THROTTLE if soft-risk threshold breached.
Rate limiter is one control layer, not the only security layer.
Decision logging at full volume is expensive; use intelligent sampling plus unsampled logs for critical endpoints.
| Endpoint Type | Fail Mode | Recommended |
|---|---|---|
| payment/critical writes | limiter unavailable | fail-closed or strict fallback |
| read endpoints | limiter unavailable | fail-open with emergency caps |
| internal low-risk | limiter unavailable | fail-open with telemetry |
Use monotonic time source per node where possible. Sliding windows with skew tolerance are safer than hard edge timestamps.
| SLI | SLO |
|---|---|
| limiter decision p99 latency | < 5ms at gateway path |
| limiter availability | > 99.99% |
| policy propagation lag p95 | < 30s |
| false deny rate (known good cohort) | below agreed threshold |
| counter store error rate | within error budget |
x-request-id
x-tenant-id
x-api-key-id
x-policy-id
x-rate-limit-decision
Problem: easy evasion and collateral damage behind NAT.
Fix: multi-dimensional policy keys.
Problem: operationally brittle and slow to respond.
Fix: externalized policy service with versioned rollout.
Problem: race conditions under concurrency.
Fix: atomic scripts/transactions in counter store.
Problem: latency blow-up and availability risks.
Fix: regionalized counters + quota leasing where acceptable.
Problem: abuse traffic bypasses protection during incidents.
Fix: endpoint-class-based fail behavior.
Problem: client retries blindly and support costs rise.
Fix: structured 429 responses with retry hints.
Problem: inconsistent behavior across regions.
Fix: monitor policy version convergence.
A high-quality rate limiter is a distributed control layer, not just middleware.
Production-ready design combines:
If you can explain these trade-offs clearly, you can handle one of the most recurrent and high-signal system design interview topics.
| Component | Responsibility |
|---|---|
| API Gateway | first-hop enforcement and headers |
| Local Limiter Cache | ultra-fast provisional checks |
| Decision Service | policy resolution + strict decision |
| Counter Store | atomic bucket state |
| Policy Service | authoring and versioned distribution |
| Risk Service | adaptive control inputs |
| Analytics Pipeline | insights, billing, anomaly detection |
1) Clarify dimensions and strictness.
2) Choose token bucket + sliding window hybrid.
3) Draw gateway local check + distributed strict check.
4) Explain regional quota leasing for global plans.
5) Add fail behavior matrix and observability.
6) Close with abuse and adaptive controls.
You now have a production-grade blueprint for global distributed rate limiting with interview-ready depth.