Week 5 — Message Queues & Rate Limiting
Why Message Queues
Section titled “Why Message Queues”Without queues, services are tightly coupled — Service A waits for Service B to respond before continuing.
Without queue: A → B → A (A blocked while B processes)With queue: A → Queue ← B (A continues, B processes when ready)Benefits:
- Buffer traffic spikes — queue absorbs bursts, consumers process at their rate
- Decouple failures — B can go down without affecting A
- Async processing — user doesn’t wait for slow operations (email sending, report generation)
RabbitMQ vs Kafka
Section titled “RabbitMQ vs Kafka”| RabbitMQ | Kafka | |
|---|---|---|
| Model | Message broker — push to consumers | Distributed log — consumers pull |
| Message retention | Deleted after consumed | Retained for configurable duration |
| Consumers | One consumer per message (competing) | Multiple independent consumer groups |
| Ordering | Per queue | Per partition |
| Best for | Task queues, work distribution | Event streaming, audit logs, fan-out |
Use RabbitMQ when: one worker should process each job (email queue, report generation).
Use Kafka when: multiple systems need the same event (order placed → billing, warehouse, analytics all need it).
Rate Limiting Algorithms
Section titled “Rate Limiting Algorithms”Token Bucket
Section titled “Token Bucket”- Bucket holds N tokens, refilled at R tokens/sec
- Each request consumes 1 token
- Allows bursting up to bucket size
Leaky Bucket
Section titled “Leaky Bucket”- Requests enter a queue (the bucket), processed at fixed rate
- Excess dropped
- Smooths output regardless of burst input
Fixed Window
Section titled “Fixed Window”- Count requests per time window (e.g. per minute)
- Vulnerable to boundary attack: 100 req at 11:59, 100 req at 12:00 = 200 in 2 seconds
Sliding Window Log
Section titled “Sliding Window Log”- Track timestamp of every request
- Count requests in the last N seconds
- Most accurate, but memory-intensive
Sliding Window Counter
Section titled “Sliding Window Counter”- Weighted blend of current and previous window counts
count = prev_window_count × (1 - elapsed/window) + curr_window_count- Redis-friendly, good accuracy
Where to Enforce Rate Limits
Section titled “Where to Enforce Rate Limits”Client → API Gateway (global limits) → Service (per-endpoint limits)Response headers to include:
X-RateLimit-Limit: 100X-RateLimit-Remaining: 23X-RateLimit-Reset: 1719000000Retry-After: 30 ← on 429 responsePractice
Section titled “Practice”Design the notification system for an ERP:
- Email: send within 5 minutes, not time-critical → RabbitMQ
- SMS: send within 30 seconds, must not duplicate → RabbitMQ + idempotency key
- Warehouse alerts: real-time, multiple systems need it → Kafka
- Analytics events: high volume, replay needed → Kafka
- Dashboard updates: low latency, ephemeral → WebSocket / Redis pub-sub
Self-check
Section titled “Self-check”- What happens to Kafka messages when the consumer is down for 2 days?
- Why is the fixed window algorithm dangerous for financial rate limits?
- How does a rate limiter work in a horizontally scaled system (multiple app servers)?