Vasu Patel logoVasu Patel
← Whiteboard to Blueprint: HLD & LLD
All chapters in this track
  1. 01Chapter 1: What HLD and LLD Are, and How They Differ
  2. 02Chapter 2: Gathering and Clarifying Requirements Before Designing Anything
  3. 03Chapter 3: HLD Deliverables: Architecture, Components, Technology Choices, Data Flow
  4. 04Chapter 4: LLD Deliverables: Class Diagrams and Sequence Diagrams
  5. 05Chapter 5: LLD Deliverables: Database Schema and API Contracts
  6. 06Chapter 6: Documenting Decisions: ADRs and Communicating Trade-offs to Stakeholders
  7. 07Chapter 7: Moving Cleanly from HLD to LLD Without Losing Intent
  8. 08Chapter 8: Common Mistakes: Over-Designing, Under-Specifying, and Skipping Non-Functional Requirements
  9. 09Chapter 9: When LLD Contradicts Its Own HLD
  10. 10Chapter 10: HLD and LLD in Design Reviews: What Reviewers Actually Look For
  11. 11Chapter 11: Worked Example: Ride-Sharing Dispatch — Requirements Through HLD to LLD
  12. 12Chapter 12: Worked Example: Hotel Booking — Requirements Through HLD to LLD
  13. 13Chapter 13: Worked Example: Food Delivery — Requirements Through HLD to LLD
  14. 14Chapter 14: How HLD and LLD Show Up in Interviews and Design Reviews
  15. 15Chapter 15: Common Interview Questions About HLD and LLD

Chapter 2 of 15

Chapter 2: Gathering and Clarifying Requirements Before Designing Anything

Why this matters

The companion SDLC book's Chapter 4 and System Design book's Chapter 3 both cover requirements gathering in depth — this chapter's specific contribution is the HLD/LLD angle: which requirements shape HLD decisions versus LLD decisions, and why designing before requirements are clear produces a design that has to be substantially reworked once the real requirements surface, at a cost proportional to how much design work had already been built on the wrong assumption.

Which requirements shape which level of design

[BEGINNER] Non-functional requirements (scale, availability, consistency — System Design book Chapter 3) overwhelmingly shape HLD decisions: whether to use a single database or multiple, whether components need to be separate services, what technology choices are viable at the stated scale. Functional requirements, especially detailed edge cases and specific business rules, overwhelmingly shape LLD decisions: exact validation logic, specific class responsibilities, precise API contracts. This mapping is useful practically: if a stakeholder can't yet answer a scale/availability question, HLD work is premature; if functional edge cases are still unclear, LLD work specifically (even with HLD settled) is premature.

Example: "Should the payment processing component be a separate service?"
(HLD question) depends on a NON-FUNCTIONAL requirement: does payment
processing need independent scaling/deployment from the rest of the
system, or different compliance/security isolation? Answering this
requires the non-functional requirements, not the functional details
of exactly how a specific payment method is validated.

Example: "What fields does the PaymentRequest class need?" (LLD
question) depends on FUNCTIONAL requirements: which payment methods
are supported, what data each one requires, what validation rules apply.

The cost of designing before requirements are clear, restated for HLD/LLD specifically

[SENIOR INSIGHT] Directly extending the companion SDLC book's Chapter 4 point about the cost of a requirements change scaling with how much has been built on the wrong assumption: an HLD decision made on an incorrect or incomplete non-functional requirement is especially expensive to unwind, because LLD work for every affected component gets built assuming that HLD decision — discovering the HLD was wrong after several components' LLD (and possibly implementation) is complete means reworking not just the HLD itself but a potentially large amount of downstream, dependent work. This is precisely why non-functional requirements deserve extra diligence in clarification specifically before HLD begins — more so than functional requirements, which primarily affect the more locally-scoped, more cheaply-revisited LLD layer.

A practical clarification checklist before starting HLD

[IN PRACTICE]

## Before starting HLD, confirm:
- [ ] Expected scale (users, requests/second, data volume) - even a
      rough order of magnitude (System Design book, Chapter 4)
- [ ] Availability requirements (can this tolerate brief downtime, or
      does it need to be highly available?)
- [ ] Consistency requirements (can data be briefly stale, or must
      reads always reflect the latest write?)
- [ ] Integration points (what existing systems must this interact with?)
- [ ] Major constraints (budget, team's existing technology expertise,
      regulatory/compliance requirements)

## Before starting LLD for a specific component, confirm:
- [ ] Detailed functional requirements and edge cases for THIS component
- [ ] The HLD decisions that constrain this component (which database,
      which communication mechanism with other components)
- [ ] Any component-specific non-functional requirements not covered
      by the system-wide HLD requirements (e.g., this ONE component
      needs unusually low latency, beyond the system's general target)

Common mistakes

  1. Starting HLD work before non-functional requirements are reasonably clear, risking a major architectural decision that has to be unwound after significant downstream LLD/implementation work depends on it.
  2. Starting LLD work for a component before its relevant HLD decisions are settled, risking LLD work that has to be redone if the HLD changes underneath it.
  3. Treating functional and non-functional requirements as equally relevant to HLD, missing that non-functional requirements are disproportionately the ones that actually shape architecture-level decisions.
  4. Assuming requirements are fully "gathered" once at the start and never need revisiting, rather than recognizing (per the companion SDLC book's Chapter 4) that requirements clarification is genuinely iterative, especially as LLD work surfaces questions the original requirements didn't anticipate.

Checklist: clarifying requirements at the right time, for the right level

  1. Clarify non-functional requirements (scale, availability, consistency, integration points) before starting HLD — these are what actually shape architecture-level decisions.
  2. Clarify detailed functional requirements and edge cases before starting LLD for a specific component, once the relevant HLD decisions are settled.
  3. Treat an HLD decision made on unclear non-functional requirements as high-risk, worth extra diligence to clarify before proceeding, given how expensive it is to unwind later.
  4. Stay willing to revisit requirements clarification when LLD work surfaces a question the original gathering didn't anticipate — this is normal, not a sign of a failed initial process.

Discussion / interview questions

  1. "What kinds of requirements primarily shape HLD decisions, versus LLD decisions?" Strong answer: Non-functional requirements (scale, availability, consistency) primarily shape HLD (architecture, technology choices, service boundaries); detailed functional requirements and edge cases primarily shape LLD (specific class design, validation logic, API contracts) — this mapping helps identify which kind of requirements clarity is needed before starting which level of design.

  2. "Why is it especially costly to start HLD work before non-functional requirements are clear?" Strong answer: Every downstream component's LLD (and eventual implementation) gets built assuming the HLD's decisions; discovering the HLD was wrong after this downstream work exists means reworking not just the HLD but potentially significant dependent work built on top of it — a much larger cost than revisiting a single component's LLD in isolation.

  3. "Would you start writing a class's low-level design before its relevant high-level architectural decisions are settled?" Strong answer: No — LLD work should generally wait until the relevant HLD decisions (which service this component lives in, what it communicates with, and how) are settled, since LLD work done before that risks being invalidated if the HLD changes underneath it.

  4. "Is requirements gathering something you do once, at the very start of a project, or is it ongoing?" Strong answer: Ongoing — while an initial pass should happen before HLD begins, LLD work frequently surfaces functional edge cases or questions the original requirements gathering didn't anticipate, requiring targeted, iterative clarification rather than treating the initial gathering as complete and final.

Chapter summary / cheat sheet

  • Non-functional requirements (scale, availability, consistency) primarily shape HLD; detailed functional requirements and edge cases primarily shape LLD.
  • Starting HLD before non-functional requirements are clear is especially costly, since downstream LLD/implementation work across multiple components ends up built on the potentially-wrong assumption.
  • Use a practical checklist: confirm HLD-relevant requirements before starting HLD; confirm LLD-relevant, component-specific requirements before starting that component's LLD.
  • Requirements clarification is genuinely iterative — LLD work surfacing a gap in the original requirements is normal and should trigger targeted re-clarification, not be treated as a process failure.