How to Approach Any Problem — The Questions Senior Engineers Ask
The difference between junior and senior isn't the answer — it's the questions first
Given "design X" or "make Y faster," a junior starts coding/drawing boxes. A senior engineer spends the first minutes narrowing the problem with questions, because the quality of any solution is capped by the quality of the understanding behind it. The questions also are half the score in an interview, and at work they prevent the most expensive mistake: building the wrong thing well.
The six questions, in order
Run these on any problem — a design, a bug, a feature, an outage.
1. Understand the real problem (before any solution)
- Can I restate it in one sentence? What exactly are we solving?
- Who is the user, and what is the real job-to-be-done behind the stated ask? (the classic X–Y problem: they ask for X because they think it solves Y — solve Y).
- What does "done" look like, and how will we measure success?
- What are we explicitly not doing? (scope boundaries)
2. Surface the constraints
- Scale: how many users / QPS / how much data? Read-heavy or write-heavy?
- Latency budget? Consistency needs (strong vs eventual)? Availability target?
- Security/compliance? Cost ceiling? Deadline? What's fixed vs negotiable?
3. Challenge assumptions
- What am I taking for granted? What would have to be true for my approach to work?
- What's the riskiest assumption — and can I test it cheaply before committing?
4. Decompose
- What are the independent sub-problems? (a MECE issue tree — mutually exclusive, collectively exhaustive)
- What's the core 20% that delivers 80% of the value? Solve that first.
5. Invert — the pre-mortem
- How could this fail? (run the 8 Fallacies + failure modes over it)
- What breaks at 10× / 100× load or data?
- What's the blast radius when it fails — and how do I contain it?
6. Find the simplest thing that works
- What's the simplest version that meets the real requirements? Do I actually need the distributed / sharded / cached version yet? (Simplicity is a senior signal; premature complexity is a junior one.)
Worked example: "make the dashboard faster"
A junior adds a cache. A senior asks:
- Faster for whom — p50 or p99? (averages hide the pain) · Which page/query? · How slow now, and what's the target? (no number = no goal)
- Where is the time actually going — the DB query, the network, or the render? → profile first; don't optimize blind (the Pareto rule).
- How much data, growing how fast? → is this an index problem (see Indexes-in-Practice), an N+1 query, or a payload-size problem?
Half those questions change the solution entirely. Then you design.
The 45-minute design interview clock
In a real system-design interview you do not have time to ask every question in depth. The six questions are a checklist, but the art is knowing which ones to compress. Here is a standard pacing plan (from the RESHADED / Hello Interview school):
| Minutes | Question(s) | What to produce | Compressible? |
|---|---|---|---|
| 0–4 | Understand + Constraints | One-sentence restatement; functional + non-functional requirements; scale/latency/availability targets | No — this is the contract with the interviewer |
| 4–8 | Constraints (estimation) + Assumptions | Back-of-envelope QPS, storage, bandwidth; explicit assumptions you are relying on | Yes — arithmetic can be assumption-based when time is short |
| 8–12 | Decompose | API / data model sketch — the nouns and verbs of the system | No — this anchors the design |
| 12–25 | Decompose + Invert | High-level design (HLD): clients, load balancer, services, storage; one failure mode | No — HLD is the deliverable |
| 25–35 | Invert | Deep dive on the highest-risk component (consistency, scaling, failure) | Yes — pick one risk, not three |
| 35–42 | Invert + Simplest | Failure modes, bottlenecks at 10× scale, and a simpler alternative if time permits | Yes — one good failure trace beats a laundry list |
| 42–45 | — | Recap the design and the trade-offs | — |
Non-negotiable: restating the problem, surfacing constraints, sketching the API/data model, and producing a coherent HLD. Compressible: the depth of estimation, the number of failure modes, and the breadth of the deep dive.
Traced example: designing a rate limiter
- 0–4 min: "We need to limit requests per user per window; assume 10× the average burst, 100 ms latency budget, 99.9% availability."
- 4–8 min: "100K users, 1K QPS average → 10K burst QPS; I'll assume a sliding window and a 1-minute bucket for estimation."
- 8–12 min: API:
allow(userId)returns true/false; data model:userId → counter + window start. - 12–25 min: HLD: API gateway → distributed counter (Redis with TTL) → fallback to local in-memory counter if Redis is slow.
- 25–35 min: Deep dive on consistency: a race between read and increment; fix with Redis
INCR+ Lua or compare-and-set. - 35–42 min: Failure: Redis partition → circuit breaker opens → local rate limiter degrades gracefully; at 10× scale shard by userId.
Notice that questions 1, 2, 4, and 5 are asked in every block; question 3 (assumptions) is folded into the estimation; question 6 (simplest) only appears if there is time.
Takeaways
- Ask before you solve: understand → constraints → assumptions → decompose → invert → simplest.
- The X–Y problem and "no number = no goal" are the two traps; clarify the real goal and the metric.
- Inversion ("how does this fail / at 10×?") and "simplest thing that works" are what separate senior judgment.
Re-authored for this guide; approach-funnel diagram hand-authored as SVG. Synthesizes consulting issue-trees, first-principles/inversion (Munger), and the RESHADED/Hello-Interview clarification step. See also: The System Design Interview (RESHADED), Capacity Estimation, The 8 Fallacies, Designing for Failure.
Constraint questions by system type
When the interviewer says "design X," the first questions you ask depend on the shape of the system. Use this table as a first-90-seconds checklist.
| System type | Read path | Write path | Cost / scale / ops |
|---|---|---|---|
| Read-heavy news feed, search, product catalog | Cache hit-rate target? p99 latency? CDN? | Write amplification? Invalidation strategy? | CDN vs DB replica trade-off? Read:write ratio? |
| Write-heavy logging, metrics, messaging | Eventual consistency window? Aggregate reads? | Partition key? Sharding limit? Write fan-out? | Storage growth per day? Retention policy? |
| Latency-sensitive trading, ads, real-time games | Synchronous vs cached? p50 vs p99 budget? | Sync replication tolerated? Durability vs latency? | Geography of users? Edge deployment cost? |
| Consistency-critical payments, inventory, reservations | Read-your-writes required? Stale reads OK? | Atomic updates across entities? Saga vs 2PC? | Downtime budget? Fail-open vs fail-closed? |
| Cost-constrained startups, batch pipelines | Can reads be eventually consistent? | Can writes be batched / async? | Storage class (hot/warm/cold)? Spot instances? |
| Geo-distributed global SaaS, maps, collaboration | Nearest replica or global quorum? | Conflict resolution (LWW, CRDT, custom)? | Cross-region replication cost? Compliance zones? |
How to use it: after the restatement, label the system type in your head and ask the read-path question first. It signals that you know what matters most.
Worked example: deriving a URL shortener from requirements
Here is how the six questions turn a vague "design a URL shortener" into a concrete design.
1. Understand
- What does it do? Given a long URL, return a short code; given a short code, redirect to the long URL.
- Scope: custom aliases? Analytics? Expiry? User accounts?
2. Constraints
- Scale: 100M new URLs/day, 10B redirects/day.
- Latency: redirect p99 < 100 ms; create p99 < 500 ms.
- Availability: 99.99%.
- Length: short code should be < 10 characters.
3. Assumptions
- Short codes are random, not sequential (security).
- Redirect traffic is 100× create traffic.
- Analytics are read later, not real-time.
4. Decompose → design
| Decision | Derived from | Choice |
|---|---|---|
| API | Functional requirements | POST /shorten → 201 + short code; GET /{code} → 302 redirect. |
| Code length | Scale + length constraint | 7-character base62 gives 62⁷ ≈ 3.5T codes; enough forever. |
| Data model | Read-heavy + strong mapping | SQL table (code PK, long_url, created_at); Redis cache hot codes. |
| Hashing | Uniqueness + short code | Generate random base62, check SQL for collision; much simpler than hash-then-truncate. |
| Storage estimate | 100M URLs/day | ~1 KB/row → 100 GB/day, ~36 TB/year before replication. |
| Redirect QPS | 10B/day | ~115K average; assume a ~8–10× diurnal/burst peak → ~1M QPS. A single Redis node sustains ~100K ops/s, so the peak needs a ~10-shard Redis cluster (shard by code) — or accept serving the p99.9 burst from SQL replicas. |
5. Invert
- What if Redis is down? Fallback to SQL read replica; p99 rises but service stays up.
- What if two users get the same random code? SQL unique constraint rejects the second; retry with a new code.
- What if someone enumerates short codes? Rate-limit
GET /{code}by IP; do not expose sequential IDs.
6. Simplest thing
Start with one SQL table + one Redis cache. Add sharding only when code storage exceeds one database. The read-heavy redirect path is the only part that needs to scale early.
5-why deep-dive checklist
For every major decision, run five whys until you hit a first-principle constraint. If you stop at "because that is the pattern," you are pattern-matching, not reasoning.
| Decision | Why? | Bottoms out at |
|---|---|---|
| Why base62 encoding? | URL-safe, compact, human-typable. Why 7 chars? 62⁷ ≈ 3.5T > lifetime need. Why not UUID? UUID is 36 chars, violates the <10-char product constraint. | Product requirement + combinatorics. |
| Why Redis for redirects? | Redirect is read-heavy and latency-sensitive. Why not serve from SQL? SQL p99 ~10 ms vs Redis ~1 ms, and 1M QPS would need many replicas. Why not CDN? Dynamic redirects cannot be cached safely without invalidation logic. | Latency budget + cost at peak QPS. |
| Why SQL primary for code creation? | Need a unique, durable code→URL mapping. Why not a NoSQL store? Eventual consistency risks duplicate codes; a unique key requires consensus anyway. Why not generate in application? Centralized storage is the source of truth for cross-server uniqueness. | Correctness (uniqueness) + durability. |
| Why rate-limit by IP? | Prevents enumeration and abuse. Why not by user? Unauthenticated users have no user ID. Why not both? Defense in depth; authenticated users get per-user limits too. | Threat model + identity availability. |
Interview signal: when you can articulate the bottom of each why-chain, you have moved from "I chose Redis" to "I chose Redis because the redirect path must serve 1M QPS under a 100 ms p99 budget, and SQL replicas would cost 10× more." That is the answer a senior engineer gives.
🤖 Don't fully get this? Learn it with Claude
Stuck on How to Approach Any Problem — The Questions Senior Engineers Ask? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **How to Approach Any Problem — The Questions Senior Engineers Ask** (System Design) and want to truly understand it. Explain How to Approach Any Problem — The Questions Senior Engineers Ask from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **How to Approach Any Problem — The Questions Senior Engineers Ask** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **How to Approach Any Problem — The Questions Senior Engineers Ask** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **How to Approach Any Problem — The Questions Senior Engineers Ask** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.