

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.
Produtos gratuitos e pagos para transformar ideias em uma base que você consegue executar.
11 produtos disponíveisContinue explorando tópicos 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 cache distribuído com Redis e Memcached, cobrindo cache-aside, read-through, write-through, invalidação, TTL, eviction, sharding, replicação, hot keys, preven...
Checklist de 47 pontos para encontrar bugs, riscos de segurança e problemas de performance antes do lançamento.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.
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.