System Design Interview Questions: Fundamentals Practice Quiz
Reviewed by Mark Dickie · Last updated
6 questions on this page you can answer and see marked on the spot. Go to the first one
System design is the process of defining a system's architecture, components, data flow, and interfaces to meet given requirements. For a fundamentals interview, you need to talk through how a request moves from a client to a database, name the components you'd put in its path, and explain the tradeoffs each choice introduces. Interviewers are listening for concrete building blocks: load balancers, caches, message queues, partitioned databases, and whether you can justify why each one belongs. They also want you to reason about latency, throughput, consistency, and availability as pressures you balance against each other, not items on a memorized checklist.
| Area | What the interviewer is checking |
|---|---|
| Horizontal vs vertical scaling | Can you say when adding machines beats adding CPU and RAM? |
| Load balancing | Do you know the common algorithms and where session state lives? |
| Caching | Can you pick a write strategy and explain cache invalidation? |
| Partitioning / sharding | Can you shard by key, spot hot partitions, and reason about cross-shard reads? |
| Consistency models | Do you understand strong vs eventual consistency and the CAP tradeoff? |
| Replication | Can you compare single-leader and multi-leader setups and say what fails over? |
What does a System Design fundamentals interview test?
It tests whether you can take a vague prompt like "design a URL shortener" and produce a coherent, defensible architecture under time pressure. The interviewer cares less about the exact tool names and more about your reasoning: why a cache goes here, why a message queue goes there, and what breaks if traffic doubles. You should be able to estimate rough capacity numbers and identify the single component that would fail first.
A typical interview flow looks like this:
- Clarify functional and non-functional requirements before drawing anything.
- Estimate the scale: queries per second, storage, bandwidth, and the read/write ratio.
- Sketch a high-level diagram and walk a single request through every hop.
- Name the bottleneck and state which tradeoff you accept.
- Discuss failure modes: what happens when a node dies or a network partition occurs.
Which tradeoffs come up most often?
The CAP theorem is the one interviewers reach for first: in the presence of a network partition you choose between consistency and availability. Beyond CAP, expect to compare latency against throughput, strong consistency against eventual consistency, and synchronous writes against asynchronous ones. Caching questions tend to center on invalidation and the stale-read window. Partitioning questions tend to center on hot keys and the cost of cross-shard joins. Knowing which side of each tradeoff a system sits on, and being able to say why, is what separates a passing answer from a strong one.
Key facts
- Tarmac has 51 System Design interview questions on this topic, 10 of them on this page, at difficulty 1–5 of 5.
- Tarmac tracked 3,763 job postings asking for System Design in September 2026.
- Roles asking for System Design advertise a median base salary of US$180,347, across 1,250 job postings as of September 2026.
- Tarmac last reviewed these System Design interview questions on 12 October 2026.
At a glance
| Questions | 10 shown · 51 in the bank |
|---|---|
| Difficulty | 1–5 of 5 |
| Formats | True / false, Fill in the blank, Multiple choice, Multiple answer, Ordering, Flashcard, Design exercise, Short answer |
What you'll review
- scalability
- caching strategies
- id generation
Practice questions
Try one before you open the answer. Pick an option and press Check; it's marked on the spot.
Vertical scaling (scaling up) is generally considered easier to implement than horizontal scaling (scaling out), but it has a hard upper limit because a single machine's hardware capacity is finite.#
Options
Show answer
This statement is true. Vertical scaling is simpler to implement because it involves only upgrading a single machine's hardware with no application-level changes. However, it hits a hard ceiling determined by the maximum specs available for a single server. Horizontal scaling bypasses this limit by adding more machines, at the cost of increased architectural complexity.
Vertical scaling requires no changes to application architecture — you simply upgrade the server's CPU, RAM, or storage — making it straightforward to implement. However, hardware has a physical ceiling: there is a maximum amount of RAM or number of CPU cores you can add to one machine. Horizontal scaling removes this ceiling by adding more machines, but it introduces complexity such as load balancing, distributed state management, and network partitioning concerns.
To reduce repeated expensive database queries and improve read scalability, engineers store the results of those queries temporarily in a fast in-memory store. This technique is called _____, and a widely used open-source tool for this purpose that supports rich data structures (strings, lists, sets, hashes, and more) beyond simple key-value pairs is _____.#
Show answer
To reduce repeated expensive database queries and improve read scalability, engineers store the results of those queries temporarily in a fast in-memory store. This technique is called caching, and a widely used open-source tool for this purpose that supports rich data structures (strings, lists, sets, hashes, and more) beyond simple key-value pairs is Redis.
Caching is the technique of storing the results of expensive or frequently repeated operations (such as database queries) in a fast, temporary storage layer so that subsequent requests can be served without hitting the database again. The second blank is pinned to Redis specifically because the prompt qualifies it as supporting rich data structures (strings, lists, sets, hashes, and more) beyond simple key-value pairs — a distinguishing feature of Redis that does not apply to Memcached, which supports only plain string key-value storage. Redis is one of the most widely adopted open-source in-memory data stores used for caching in distributed systems.
A stateless web service is receiving increasing read traffic and its single server is approaching CPU saturation. Which scalability strategy most directly addresses this by allowing the service to handle more concurrent requests without changing the server's hardware specs?#
Options
Show answer
Horizontal scaling (adding more identical server instances behind a load balancer) is the correct approach. Because the service is stateless, any instance can handle any request, so distributing traffic across multiple servers directly increases concurrent-request capacity without touching the existing hardware. Vertical scaling also helps but requires downtime and has a hard ceiling.
Horizontal scaling (scaling out) adds more machines/instances to distribute load, making it well-suited for stateless services. Vertical scaling (scaling up) increases the resources of a single machine. A load balancer distributes traffic but does not itself replicate application logic. A CDN caches static content closer to users. Only horizontal scaling directly handles increased read throughput on stateless web servers by adding replicas behind a load balancer.
Which of the following techniques directly improve the read scalability of a relational database? Select all that apply.#
Options
Pick every one that applies.
Show answer
The techniques that directly improve read scalability of a relational database are: read replicas (routing SELECTs to replica nodes adds horizontal read capacity), read-through caching (serving repeated reads from memory bypasses the database entirely), and sharding (partitioning data so each shard handles a smaller dataset and fewer concurrent queries). Increasing connection pool threads alone and rewriting stored procedures do not directly increase the database's read throughput.
Read replicas directly improve read scalability by creating additional database nodes that serve SELECT queries, relieving pressure on the primary and allowing the system to handle more concurrent reads horizontally. Read-through caching (e.g., Redis) directly improves read scalability by intercepting repeated read requests and returning results from memory, drastically reducing the number of queries that ever reach the database. Sharding directly improves read scalability by partitioning data across nodes so each node owns and serves a subset of the data — queries for a given user hit only one shard, reducing per-node dataset size and concurrent read contention. All three are well-accepted, direct read-scalability techniques. Increasing connection pool threads is tempting, but the question specifies doing so without changing the database server's own max_connections or hardware: the database itself still becomes the bottleneck once its connection limit is saturated, so this manages client-side overhead rather than increasing the database's fundamental read throughput. Rewriting stored procedures in the application layer is an architectural refactoring that does not inherently increase the database's capacity to serve more reads.
Arrange the following scalability milestones in the order a typical web application team would adopt them as traffic grows from hundreds to millions of daily active users (earliest first), following the canonical progression described in widely cited system design literature (e.g., Alex Xu's System Design Interview).#
Put these in order
Show answer
The canonical order is: (1) single-server monolith, (2) move the database to a dedicated server, (3) add a load balancer with multiple stateless app servers, (4) deploy a caching layer, (5) shard the database. Separating the database onto its own server comes before horizontal app-server scaling because resource contention on a shared box must be resolved first, and a standalone DB server is a prerequisite for multiple app instances to connect to it correctly.
According to canonical system design literature (e.g., Alex Xu's System Design Interview), the standard incremental scaling progression is: (1) Start with a single-server monolith to ship and validate quickly. (2) Move the database to a dedicated server — this is done early to eliminate resource contention between the app and the DB on the same machine, and it is a prerequisite for meaningful horizontal app-server scaling. (3) Add a load balancer with multiple stateless app servers now that the DB is independently reachable by all instances. (4) Introduce a caching layer (e.g., Redis/Memcached) to absorb hot reads and reduce DB load. (5) Shard the database to distribute write load and data volume at massive scale. This C → E → B → A → D order is the consensus ordering in the most widely cited system design references.
Describe the cache-aside (lazy-loading) caching strategy and its main failure mode.#
Show answer
In cache-aside the application code owns the cache: on a read it checks the cache first, and on a miss it loads from the database, populates the cache, and returns. Writes go to the database and then invalidate (or update) the cache entry. Its main failure mode is the thundering herd / cache stampede — when a hot key expires, many concurrent requests all miss and hammer the database at once. Mitigate with request coalescing (single-flight), a short lock per key, or probabilistic early refresh.
Cache-aside is the most common strategy because the app stays in control and the cache only ever holds data that was actually requested. The trade-offs are an extra round trip on misses and the need to manage invalidation carefully, since stale entries linger until they expire or are explicitly evicted.
Design a URL shortener (think Bitly / TinyURL).#
Show answer
Requirements. Two operations dominate: create (write a mapping, optionally with a custom alias and expiry) and redirect (look up a code and 30x to the long URL). The system is overwhelmingly read-heavy (100:1), so the redirect path is what we optimise. I'd confirm: are custom aliases required (yes), do links expire (optional TTL), and how precise must click counts be (approximate/eventually-consistent is fine). I'd use a 302 (temporary) redirect so we keep serving redirects through our system and can still count clicks; a 301 would let browsers cache and bypass us.
Capacity. ~40 writes/sec average, ~200/sec peak; ~4K reads/sec average, ~20K peak. Storage: ~6B links over 5 years; at ~500 bytes/row (code, URL, metadata) that's ~3 TB — comfortably shardable. Keyspace: base62 with 7 characters gives 62⁷ ≈ 3.5×10¹² codes, far more than 6B, so 7 chars (often padded to a fixed length) is plenty. The hot working set (recently/ popularly accessed links) is a small fraction of 6B, so a cache of tens of GB covers the bulk of redirect traffic.
Data model. A single mapping table/collection keyed by the short code: code (PK) → long_url, created_at, expires_at, owner_id. Point lookups by primary key suit a key-value store (DynamoDB/Redis-backed) or a sharded relational table sharded by code. Click counts live separately — incrementing a counter on every redirect would put write load on the read path — so clicks are emitted as events and aggregated asynchronously.
Short-code generation. Generate a unique 64-bit id (a distributed counter handed out in ranges per server, or a Snowflake-style id) and base62-encode it to get the short code; this guarantees uniqueness with no collision checks and no hotspot from a single shared counter. Custom aliases are written directly with a uniqueness check and stored in the same table, reserving that code. (A hash-of-URL scheme is the alternative but needs collision handling and breaks idempotency for duplicate URLs.)
Read/write paths. Write: allocate id → base62 → insert mapping → return the short URL. Redirect: a load balancer / CDN fronts stateless app servers; the server does a cache-aside lookup (code → long_url) in Redis, falling back to the store on a miss and populating the cache, then returns a 302. This keeps p99 well under 100 ms for cache hits. Expiry is enforced by TTL on both the row and the cache entry. Each redirect fires a lightweight click event onto a queue (Kafka) that a consumer aggregates into per-link counts.
Bottleneck & scaling. The bottleneck is the redirect read path at peak. We scale it with cache layers (most reads never touch the store), read replicas, and sharding the mapping store by code so lookups stay single-shard. Id generation scales by handing each server an independent id range (or using Snowflake), avoiding a single global counter as a SPOF. At 10× traffic, the cache absorbs most of it; we add cache nodes and replicas and, if needed, push redirects further to the edge.
A URL shortener is the canonical warm-up design: it forces a clean separation of a heavily read-optimised redirect path from a comparatively rare write path. The two pivotal decisions are short-code generation (a base62-encoded distributed id avoids both collisions and the hotspot of a single shared counter) and caching (cache-aside on code→URL, fronted by a CDN/LB, is what meets the latency budget when reads outnumber writes 100:1). Click counting is deliberately moved off the redirect path and made asynchronous so analytics never slow a redirect. The dominant bottleneck is the redirect read path, scaled by caching, read replicas, and sharding the mapping store by code.
A team is horizontally scaling a stateless web service behind a round-robin load balancer. They notice that certain user sessions break when requests land on different instances, so they enable sticky sessions (session affinity) at the load balancer.#
Options
Show answer
Sticky sessions re-introduce per-instance state, unevenly distributing load and creating a soft single point of failure per user — defeating horizontal scalability. The canonical fix is to externalise session state to a shared distributed cache (e.g., Redis or Memcached) so the service remains truly stateless and any instance can handle any request without affinity.
In a horizontally scaled stateless service behind a load balancer, session affinity (sticky sessions) pins a user's requests to a single instance. This re-introduces a single point of failure per user and prevents full horizontal elasticity. The correct alternative is to externalise session state into a shared distributed store (e.g., Redis) so any instance can serve any request. Rate-limiting at the LB, distributing static assets via CDN, and database read replicas are all orthogonal scalability improvements that do not conflict with statelessness.
You are designing a globally distributed database for a social-media 'likes' counter that must keep serving reads and writes even during a network partition between data centres. You choose an AP (Available + Partition-tolerant) system per the CAP theorem.#
Options
Pick every one that applies.
Show answer
In an AP system, both sides of a network partition keep accepting writes, so the 'likes' counts can diverge until the partition heals and the replicas reconcile. CRDTs such as a G-Counter are a good fit for merging those diverged counts, since increment-based counters combine without conflict. The application layer must tolerate eventual consistency, so reads can temporarily return stale counts until replicas catch up.
This question probes deep knowledge of the CAP theorem's practical implications for scalable distributed databases. A network partition means nodes cannot communicate, so a CP system (e.g., HBase, Zookeeper) will refuse writes or reads to avoid returning stale data, sacrificing Availability. An AP system (e.g., Cassandra, DynamoDB in eventual-consistency mode) will continue serving reads and accepting writes on both sides of the partition, accepting that data may diverge and require later reconciliation. CA systems cannot exist in a distributed setting when partitions are possible — the theorem asserts you must choose between C and A when P occurs. The reconciliation mechanism for AP systems is typically vector clocks, last-write-wins, or CRDTs.
A write-heavy event-logging system uses range-based sharding on a monotonically increasing event_id to distribute data across 16 database shards. After launch, operators observe that almost all writes land on a single shard while the others sit idle.#
Show answer
-
This is the hot shard (or write-hotspot) anti-pattern. Because
event_idis monotonically increasing, new events always map to the uppermost range, which belongs to the last (highest-range) shard. All other shards only receive reads for historical data, never new writes. The range boundaries do not self-adjust, so the system is effectively single-shard for writes. -
Consistent hashing maps both shard nodes and keys onto a circular hash ring. Each key is owned by the first node clockwise from the key's position on the ring. When a node is added or removed, only the keys between the new node and its predecessor (approximately K/n keys, where K is total keys and n is node count) need to be remapped and migrated. All other keys remain on their current nodes. This minimal disruption property — O(K/n) remapping vs O(K) for naive modular hashing — makes it operationally far superior for elastic, dynamically scaled shard clusters.
This question tests nuanced understanding of database sharding strategies and their scalability trade-offs. Range-based sharding on a monotonically increasing key (e.g., timestamp or auto-increment ID) concentrates all writes on the last shard ('hot shard' or 'write hotspot'), making it effectively unscalable for write-heavy workloads. Consistent hashing distributes keys uniformly across nodes and, crucially, minimises key remapping when nodes are added or removed — only ~K/n keys need to move (K = total keys, n = node count). Directory-based sharding with a lookup service adds a network hop and a single point of failure unless the directory itself is highly available. Composite/hierarchical sharding (e.g., hash on user ID, then range on timestamp within shard) is common in practice but adds operational complexity.
Related interview questions
Job market
See system-design salaries and hiring demand from live job postings.
The other 41 questions
This page shows 10 and marks what you pick. That's as far as a page can go. A free account opens the other 41 and keeps every answer. What you miss comes back until it's right: after a day, then at longer gaps.
Free · the whole bank · 100 marked answers per 30 days · written feedback on the paid plan