
Tech • AI • Robotics
A practical system design interview approach centers on narrowing vague prompts into concrete scope, estimating scale, defending trade-offs, and solving the hardest bottleneck rather than drawing the biggest architecture.
Strong candidates are judged less on memorized technologies and more on judgment under ambiguity, technical depth, communication, and collaboration. The key signals are whether they clarify the problem, explain trade-offs clearly, and adapt when assumptions change. Common failure patterns are jumping straight into architecture and overengineering with caches, queues, shards, and multi-region complexity before proving they are needed.
A repeatable framework helps structure a 45-minute design discussion: clarify requirements, make back-of-the-envelope estimates, define APIs, sketch a high-level design, deep-dive into the hardest component, and finish with bottlenecks and scaling. The time split is roughly 5 minutes for requirements, 5 for estimates, 5 for APIs, 10 to 15 for high-level design, 10 to 15 for deep dives, and the last 5 for failure analysis and scaling options.
Good questions are the ones whose answers alter scope, scale, or architecture. Useful examples include user count and growth, whether the system is read-heavy or write-heavy, what data cannot be lost, and what latency matters most. Weak questions such as whether to use SQL or NoSQL, or whether the system should be scalable, delegate design judgment instead of showing it.
In a photo-sharing design, asking whether the focus is uploads or feed generation can turn a vague prompt into a solvable problem. Limiting scope to posting photos, following users, and loading the home feed produces a smaller but correct design, while trying to include search, direct messages, and every edge case often leads to an impressive but irrelevant system.
A basic short-link service can be scoped with three design-changing questions: whether users can choose custom aliases, whether links expire, and whether click analytics are required. One concrete version is simple: no custom links, no expiry, analytics optional. That reduces the core requirement to creating a short code and redirecting users from the short URL to the original one.
With 1 million new links created per day, the write path is only about 12 writes per second, which almost any database can handle. If each short link gets roughly 1,000 clicks, the service faces around 1 billion redirects per day, or more than 11,000 reads per second. Over 10 years, that becomes about 3.6 billion stored links, making the system clearly read-heavy.
The essential API needs only a create-link operation and a redirect operation. The data model is a one-to-one mapping from short code to long URL, a shape that fits a relational store such as Postgres with an index on the short code. The justification is the access pattern: simple key lookup, no joins, and no need for complex multi-row operations.
Two main approaches are hashing and counters. Hashing can produce collisions when different URLs share the same first few characters, which grows costlier as the database fills. A global counter encoded in base62 avoids collisions entirely; a 7-character code yields roughly 3.5 trillion combinations, far above the 3.6 billion needed in a decade.
A counter introduces two weaknesses that must be addressed. First, sequential values are guessable, so the number should be transformed with a reversible secret shuffle before encoding to make links look random. Second, concurrent create requests can race for the same value, so the counter update must be protected with a lock or equivalent atomic mechanism.
Viral traffic creates a hot key problem when millions of users request the same short link. Putting Redis in front of the database allows the first miss to load from Postgres and the rest to be served from cache in under a millisecond. This is unusually safe because URL mappings are immutable after creation, so the usual cache staleness problem largely disappears.
A 301 redirect is faster and lets browsers remember the destination, reducing future load on the service. But that also removes visibility into later clicks and makes it harder to disable malicious links. A 302 redirect keeps requests flowing through the service, preserving analytics and operational control at the cost of more traffic handling.
The central lesson is that strong system design performance comes from disciplined scoping and explicit trade-offs, not from the number of components drawn. In practice, the best designs start simple, identify the true bottleneck, and add complexity only when the scale or product requirements justify it.
Explain this