System Design
Case studies you can explore
Real systems I designed — trace a request, break it, and see the tradeoffs. Pick one:
Async Notification Pipeline
Decoupling push delivery from the request path so a slow third party can never stall the app — how I built it, the tradeoffs, and how it scales to 100M users.
JavaAmazon SQSRedisAPNs / FCMshipped in production
The problem
Send push notifications to 100M users — some time-sensitive, some batched — without the notification path ever blocking the action that triggered it, and without spamming users into muting the app.
Architecture — explore it
Press Trace a request to watch the flow.
Key decisions & tradeoffs
1A queue, not a direct call›
DecisionPublish the event to SQS instead of calling the push provider inline on the request thread.
Instead ofA synchronous HTTP call to the notification service from the request path.
WhyDecouples delivery latency from the action. A slow or down provider can never stall the request or push back-pressure into app logic.
2Route per platform at the worker›
DecisionWorkers branch to APNs (iOS) or FCM (Android) with platform-specific payloads and retry behavior.
Instead ofOne unified sender hiding both providers.
WhyAPNs and FCM differ in API shape, payload limits, and retry semantics — isolating them keeps each provider’s quirks contained.
3Redis for rate limiting›
DecisionPer-user TTL counters checked before dispatch; thresholds configurable per notification type.
Instead ofCounting in the primary database.
WhyTTL counters are O(1) and in-memory — cheap on every send, so we never spam a user or trip Apple/Google abuse flags.
4Dead-letter queue for failures›
DecisionUndeliverable messages move to a DLQ for inspection and retry.
Instead ofDrop the message, or retry inline until it succeeds.
WhyInline retries block the worker; dropping loses the notification. A DLQ makes failures auditable and replayable without stalling live traffic.
Questions an interviewer would probe
- How do you handle device-token invalidation — expired tokens, reinstalls?
- How do you support notification preferences — a user opts out of a category?
- How do you keep ordering for time-sensitive alerts vs. batched digests?
- What happens if the worker pool falls behind — how do you shed or prioritize load?