Skip to content
Interview

System Design Interview: A Beginner’s Framework

A simple, repeatable framework for your first system design interviews — from clarifying requirements to discussing trade-offs — with a worked URL shortener example.

Aditya Sharma3 min read
System design diagram with users, load balancer, stateless app servers, cache, primary database and read replica
On this page

System design interviews are open-ended by design. There is no single correct answer; the interviewer wants to see how you think, communicate and make trade-offs. A repeatable framework keeps you from freezing or diving into details too early.

The framework

  1. Clarify requirements (5 minutes)
  2. Estimate scale (3–5 minutes)
  3. Define the API and data model (5–10 minutes)
  4. Draw the high-level design (10 minutes)
  5. Deep-dive into one or two components (10–15 minutes)
  6. Discuss bottlenecks, failures and trade-offs (5 minutes)

Timings assume a 45–60 minute interview. Adapt them to the prompt and follow the interviewer’s lead.

Worked example: design a URL shortener

1. Clarify requirements

Ask before you draw anything:

  • Functional: create a short link for a long URL; redirect short link to the original; optional custom aliases; optional expiry.
  • Non-functional: redirects must be fast and highly available; links should not be guessable in sequence; analytics can be eventually consistent.

Write these down where the interviewer can see them.

2. Estimate scale

Rough numbers guide design decisions. Suppose 100 million new links per month and a 100:1 read-to-write ratio.

  • Writes: 100M / (30 × 24 × 3600) ≈ 40 per second.
  • Reads: about 4,000 redirects per second on average, with higher peaks.
  • Storage: 100M links × ~500 bytes ≈ 50 GB per month.

Conclusion: this is a read-heavy system, so caching matters a lot.

3. API and data model

POST /api/links      { "url": "https://example.com/very/long", "alias": "optional" }
  → 201 { "code": "aZ3kP9q", "short_url": "https://sho.rt/aZ3kP9q" }

GET /{code}          → 301/302 redirect to the original URL
CREATE TABLE links (
  code        VARCHAR(10) PRIMARY KEY,
  target_url  TEXT NOT NULL,
  created_at  TIMESTAMP NOT NULL,
  expires_at  TIMESTAMP NULL
);

4. High-level design

Users → load balancer → stateless application servers → cache (Redis) → database. Redirect requests check the cache first; on a miss, read from the database and populate the cache. A separate asynchronous pipeline records click events for analytics so redirects stay fast.

5. Deep dive: generating codes

Options to discuss:

ApproachProsCons
Hash the URL and take a prefixSame URL → same codeCollisions must be handled
Random base62 stringSimple, not sequentialMust check uniqueness on insert
Counter + base62 encodingNo collisionsSequential and guessable unless obfuscated; counter coordination

A reasonable answer: generate random 7-character base62 codes (62⁷ ≈ 3.5 trillion possibilities), insert with a uniqueness constraint and retry on the rare collision.

6. Bottlenecks and trade-offs

  • Hot links: a viral link hits the same key; the cache absorbs it, and a CDN can cache redirects too.
  • Database growth: partition by code prefix or move to a key-value store designed for this access pattern.
  • 301 vs 302: a permanent redirect is cached by browsers (fewer requests, but less accurate analytics); a temporary redirect keeps every click visible to you.
  • Availability: replicate the database; if the analytics pipeline is down, redirects must still work.

Building blocks worth knowing

  • Load balancers
  • Caching (and invalidation)
  • SQL vs NoSQL trade-offs
  • Replication and sharding
  • Message queues
  • Rate limiting
  • CDNs
  • Consistency models

Common mistakes

  • Jumping straight to microservices and Kubernetes before understanding the requirements.
  • Ignoring numbers. Without rough estimates, you cannot justify a cache, a queue or sharding.
  • Designing only the happy path. Mention what happens when the database, cache or a dependency fails.
  • Going silent. Long pauses make it hard for the interviewer to help you; narrate your reasoning instead.
  • Over-engineering. A simple design that meets the requirements beats a complex one that handles problems nobody asked about.

Communication tips

  • Think aloud and check in: “Would you like me to go deeper on storage or on the redirect path?”
  • State assumptions explicitly.
  • Name trade-offs instead of presenting one option as perfect.
  • Keep the diagram tidy and update it as the design evolves.

Practise with a timer and a whiteboard (physical or digital). After a few rounds, the framework becomes second nature — and you can spend your energy on the interesting parts of the problem.

Written by

Aditya Sharma

Backend developer · Java & APIs

Enjoys taking apart backend frameworks to see how requests really flow, and writing down what he finds. (Demo author profile.)

Comments

Join the discussion

Your email address will not be published. Be kind and stay on topic.