Software Engineering8 min read

System Design Fundamentals

Approach system design: requirements gathering, capacity estimation, API design, database selection, scalability patterns, and communication frameworks for interviews.

system-designarchitecturescalabilityinterviews

System design involves making architectural decisions at scale - how to handle millions of users, petabytes of data, and high availability requirements. It requires knowing scalability patterns, database trade-offs, and communication strategies.

Start with requirements, not solutions. Quantify scale before choosing architecture. Most systems need SQL, not NoSQL. Horizontal scaling + caching solves most read-heavy problems. Design for failure - assume every component will fail.

Workflow

  1. Clarify requirements and constraintsBuilding the wrong thing at scale wastes engineering. Requirements define what needs to be designed.
  2. Design the API layerAPIs define the contract between clients and services - they're hard to change later.
  3. Choose the right databaseDatabase choice determines consistency guarantees, query flexibility, and scale characteristics.
  4. Scale reads and writes separatelyMost systems are read-heavy - scaling reads independently is more efficient than scaling the entire DB.
  5. Design for high availabilitySingle points of failure make SLAs impossible - every layer needs redundancy.

Output Format

Requirements doc with functional + non-functional, capacity estimates, API spec, database selection with rationale, read/write scaling approach, HA across 2+ AZs.

Examples

URL shortener design: `POST /shorten → { url: "long-url" } → { shortCode: "abc123" }; GET /abc123 → 301 redirect. DB: KV store (Redis for hot codes, DynamoDB for all codes). Scale: 100M URLs, 10B redirects/day = 115K QPS reads → CDN cache redirects at edge. Short code: base62 encode a 7-digit counter or random ID`
Capacity estimate: `Instagram: 500M DAU. Upload: 10% users post = 50M posts/day = 578/s. Size: 1MB avg = 50TB/day. Storage: 50TB/day × 365 × 5 years = 91PB. CDN needed. QPS for feed: 500M × 10 views/day = 5B feed loads/day = 57K QPS reads`
Sharding: `User table sharded by user_id % 16 (16 shards). Each shard is a separate PostgreSQL cluster. Shard determination: `shard = userId % SHARD_COUNT; const db = shardConnections[shard]`. Cross-shard queries (e.g., search): use Elasticsearch as the search layer`

Edge Cases & Gotchas

  • Hot partitions: sharding by user_id can create hot shards if celebrity users generate disproportionate traffic. Use consistent hashing or shard by hashed ID to distribute more evenly
  • Global distribution: multi-region writes require distributed consensus (Spanner, CockroachDB) or accepting eventual consistency. Multi-region reads: route to nearest region via GeoDNS
  • Thundering herd on cache miss: when a popular item's cache expires, many requests hit the DB simultaneously. Solutions: request coalescing, probabilistic early expiration, or a distributed lock

When to Break These Rules

  • Most startups don't need distributed system complexity. Start simple (single region, single Postgres, no sharding) and evolve as scale demands. Premature optimization at the architecture level is the most expensive kind.

Reference Files

  • System Design Interview (book): Alex Xu
  • High Scalability blog: http://highscalability.com/
  • AWS Architecture Center: https://aws.amazon.com/architecture/
  • Designing Data-Intensive Applications (book): Martin Kleppmann

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.