Stop treating system design as one giant question
A backend engineer opens a shared document five minutes before a mock interview. The prompt reads: "Design a URL shortener." They draw a database, add a cache, say "use Kafka", and finish early, feeling prepared. Then the interviewer asks what happens when one celebrity's link receives 100,000 requests per second, and the design falls apart.
The unpopular truth: practising the most famous system design questions is not enough. Backend interviews don't reward memorised architectures. They reward your ability to identify constraints, make trade-offs, estimate scale, and evolve a design when requirements change.
The best system design questions for backend interviews are therefore a ladder, not a checklist. Start with bounded services that show your fundamentals, then move towards high-write systems, real-time delivery, reliability, and ambiguous product constraints. This guide orders the highest-value prompts, explains what each one tests, and shows where each fits in your preparation.
What a strong practice plan looks like
- Work through questions in increasing complexity: read-heavy services first, then write-heavy, real-time, and multi-region systems.
- For every design, state functional requirements, non-functional requirements, rough traffic estimates, data model, APIs, and failure modes before choosing technology.
- "Use caching" is not a design decision. Specify the cache key, eviction policy, invalidation approach, consistency expectation, and fallback behaviour.
- Good practice includes changing constraints midway through a session, for example adding a global audience or a 99.99% availability target.
- The best prompt depends on the role. A payments company may prioritise idempotency and consistency; an infrastructure company may care more about rate limiting, queues, and operational resilience.
- Repeat fewer questions, more deeply. A second attempt should improve your assumptions, trade-off explanations, and recovery plan, not just add more boxes to the diagram.
The question set that builds backend judgement
Which system design questions should you practise first?
| System design question | Core concepts tested | What it shows | Common gap it reveals | Best fit |
|---|---|---|---|---|
| URL shortener | APIs, hashing, storage, caching | Structured communication | Skipping collision and hot-key handling | Early-career to mid-level backend roles |
| Rate limiter | Distributed counters, atomicity, fairness | Precise trade-offs under load | Treating all algorithms as interchangeable | API, platform, and infrastructure roles |
| Notification service | Queues, retries, fan-out, preferences | Async processing and reliability | Ignoring duplicate delivery | Product backend and platform roles |
| Chat system | WebSockets, ordering, presence, storage | Real-time architecture | Overpromising global ordering | Collaboration and messaging products |
| News feed | Fan-out, ranking, caching, data modelling | Read/write trade-off thinking | Reaching for fan-out-on-write without analysis | Consumer-scale backend roles |
| Payment processing system | Idempotency, ledgers, consistency | A production safety mindset | Missing reconciliation and auditability | Fintech and transaction-heavy roles |
| File storage service | Metadata, object storage, uploads, CDN | Separating control and data planes | Storing large files in the primary database | Cloud and developer-tool roles |
| Job queue or task scheduler | Leases, retries, dead-letter queues | Failure-mode reasoning | Forgetting worker crashes and duplicate work | Infrastructure and distributed-systems roles |
1. Design a URL shortener: the baseline question
A URL shortener seems simple: convert a long URL into a short code, store the mapping, and redirect users. That simplicity is the point. It lets an interviewer see whether you can build a coherent design without hiding behind unnecessary complexity.
Start by clarifying whether custom aliases are supported, whether links expire, and whether analytics matter. Then estimate scale. At 100 million stored URLs, an 8-byte numeric ID plus metadata is manageable in a distributed key-value store, but the read path may need a cache because redirects vastly outnumber creates.
A strong answer covers:
- An API such as
POST /urlsandGET /{shortCode} - ID generation: database sequences, a Snowflake-style distributed ID, or random codes with collision checks
- Redirect caching for popular links
- A durable primary mapping store
- Abuse controls, link expiry, and observability
What it shows: end-to-end structure with a low cognitive load.
Watch out for: stopping at "database plus Redis". Push yourself by introducing hot links, deletion, and regional failover.
Best fit: your first timed practice question, and a useful warm-up before harder prompts.
2. Design a distributed rate limiter: the precision test
Rate limiting is one of the most useful backend prompts because every detail matters. You must define what is being limited (requests per user, API key, IP address, route, or tenant) and decide whether a slight overshoot is acceptable.
Compare common approaches:
- Fixed window: easy and inexpensive, but allows bursts at window boundaries.
- Sliding log: accurate but memory-intensive at high traffic.
- Token bucket: allows controlled bursts while enforcing an average rate.
- Sliding-window counter: a practical compromise between accuracy and cost.
For a distributed implementation, discuss atomic updates. A central in-memory store with a Lua script can provide atomicity, but it adds a dependency and regional latency. A local limiter reduces latency but may need coordination for global limits.
What it shows: vague "scalability" claims don't survive here; you have to explain correctness.
Watch out for: forgetting what happens when the limiter store is unavailable. State whether you fail open, fail closed, or use a local fallback.
Best fit: backend, API gateway, developer-platform, and infrastructure interviews.
3. Design a notification service: the asynchronous reliability question
A notification platform sends email, push, SMS, or in-app messages when events occur. The question isn't simply "how do messages get sent?" It's how you make delivery reliable without blocking the user-facing request.
A solid architecture separates event ingestion from delivery:
- Producers publish an event such as
order_shipped. - A notification service applies user preferences and templates.
- It places channel-specific jobs on durable queues.
- Workers send messages through channel providers.
- Delivery results update status and trigger retries where appropriate.
Explain at-least-once delivery and its consequence: duplicates can happen. Use idempotency keys, deduplication records, and carefully scoped retry policies. Permanent failures should reach a dead-letter queue for inspection rather than retry forever.
What it shows: queues, retries, preferences, and data ownership in a relatable product context.
Watch out for: claiming "exactly once" without acknowledging external providers and failure boundaries.
Best fit: product-focused backend roles.
4. Design a real-time chat service: the connection-management question
Chat introduces persistent connections, message ordering, online presence, and sync across devices. Begin by narrowing the scope: one-to-one messaging or group chat? Is order required only within a conversation? Are messages kept indefinitely?
A practical design can use WebSockets for active connections, a connection registry for routing, and a durable message log for offline recipients. Partition messages by conversation ID so that one partition owner can preserve order within that conversation. That is very different from promising a single global order, an expensive requirement most products don't need.
Discuss:
- Acknowledgements and retry behaviour
- Multi-device delivery
- Offline storage and catch-up sync
- Presence as approximate, ephemeral state
- Backpressure when a client or group is slow
What it shows: whether you understand the difference between real-time delivery and durable storage.
Watch out for: making presence perfectly accurate, even though disconnect detection is inherently delayed.
Best fit: messaging, collaboration, gaming, and consumer applications.
5. Design a news feed: the trade-off question
A feed is an excellent test of architectural judgement because there is no universally correct fan-out strategy.
With fan-out on write, a new post is pushed into followers' feed inboxes. Reads are fast, but a creator with millions of followers causes an enormous write spike. With fan-out on read, the system composes the feed when a user opens the app. Writes are cheaper, but reads become expensive and latency-sensitive.
A thoughtful answer often proposes a hybrid: fan out normal accounts on write, and pull content from high-follower accounts on read. Add pagination, cached feed pages, ranking, and clear eventual-consistency expectations.
What it shows: read/write trade-offs, articulated rather than components named.
Watch out for: ignoring celebrity accounts and ranking freshness.
Best fit: mid-level and senior backend interviews where scalability reasoning matters.
6. Design a payment processing service: the correctness question
This prompt is less about raw throughput and more about never losing track of money. Your design must keep an auditable record of what happened, including partial failures and retries.
Core principles include:
- Idempotency keys for client retries
- An immutable ledger rather than only mutable balance fields
- Clear payment state transitions: authorised, captured, failed, refunded
- Reconciliation with external payment providers
- Audit logs, access controls, and sensitive-data boundaries
If a client times out after submitting a payment, it can't safely assume the payment failed. The service should return the result for the same idempotency key rather than create a second charge.
What it shows: mature thinking about consistency, auditability, and failure recovery.
Watch out for: focusing on card processing and leaving out reconciliation, where real-world discrepancies surface.
Best fit: fintech, marketplaces, subscriptions, and senior backend roles.
7. Design a job queue: the failure-mode question
A task queue processes work asynchronously: resizing images, sending webhooks, generating reports, or running scheduled jobs. It's one of the most practical prompts for backend engineers because it mirrors everyday production systems.
Cover visibility timeouts or leases: a worker claims a task, and if it crashes before acknowledging completion, the task becomes available again. That means at-least-once execution, so handlers must be idempotent. Include retry delays, exponential backoff, priority queues, dead-letter queues, and monitoring for queue depth and processing lag.
What it shows: operational realism and the lifecycle of background work.
Watch out for: poison messages that fail repeatedly.
Best fit: nearly any backend interview, especially for services with asynchronous workflows.
Turning prompts into realistic rehearsal
Reading a question is not the same as answering one under pressure. Use a repeatable structure such as this system design interview framework:
- Clarify scope and success criteria.
- Estimate traffic, storage, and latency targets.
- Define APIs and core data entities.
- Draw the simplest viable architecture.
- Go deep on the bottleneck most relevant to the prompt.
- Name failure modes, trade-offs, and future evolution.
For solo sessions, adapt the techniques in this guide to practise system design on your own: record your answer, time-box it to 35–45 minutes, then look for what you did not explain. If you can't say why a database, queue, or cache belongs in the design, it probably doesn't belong there yet.
Build your own backend practice loop
Choose three prompts based on the role you want, not on popularity alone. A useful weekly sequence:
- Session 1: URL shortener or rate limiter, for clear fundamentals.
- Session 2: notification service or job queue, for asynchronous workflows.
- Session 3: news feed, chat, or payments, for deeper trade-offs.
- Review session: answer one earlier question again with a new constraint: multi-region deployment, 10 times the traffic, stricter consistency, or lower cost.
After each session, look back across five areas: requirement clarity, estimates, data modelling, trade-off reasoning, and failure handling. Note one thing that went well and one focus area for next time. The aim is to find the exact explanation that needs another repetition.
For role-specific rehearsal, Hardmode's system design interview round can build the session from a job posting and, if you add it, your CV, rather than giving every candidate the same generic prompt.
Practise the conversation, not just the architecture
An interviewer is listening to how you reason aloud. Say your assumptions before they become hidden constraints. For example: "I'll aim for p99 read latency under 200 ms, accept eventual consistency in the feed, and preserve ordering only within a conversation."
That statement gives the interviewer something concrete to challenge, and gives you room to defend or revise your choices. Full mock loops through Hardmode interviews let you rehearse this dialogue across technical, behavioral, and negotiation rounds, with detailed written feedback and a recording you can download to revisit later.
Use feedback to choose the next question
If sizing keeps coming up as a focus area, repeat the URL shortener and file storage with different assumptions. If your designs are technically sound but light on operational depth, spend time on job queues, notification systems, and payments. If you jump to technology too quickly, practise clarifying requirements before drawing anything.
The goal is not to collect completed prompts. It's to build the habit of making defensible decisions under uncertainty, which is exactly what backend work and system design interviews ask for.
The best question is the one that shows your blind spot
A familiar system design prompt is only useful when it reveals how you think. URL shorteners teach structure; rate limiters teach precision; queues and notifications teach reliability; feeds and chat teach scale; payments teach correctness. Together they make a practical backend interview curriculum.
Practise each question until you can explain not just the happy path, but the assumptions, bottlenecks, trade-offs, and failures behind it. That's how system design preparation becomes more than diagram drawing, and how you walk into the interview ready to reason like the backend engineer the team needs.