All chapters in this track
- 01Chapter 1: What HLD and LLD Are, and How They Differ
- 02Chapter 2: Gathering and Clarifying Requirements Before Designing Anything
- 03Chapter 3: HLD Deliverables: Architecture, Components, Technology Choices, Data Flow
- 04Chapter 4: LLD Deliverables: Class Diagrams and Sequence Diagrams
- 05Chapter 5: LLD Deliverables: Database Schema and API Contracts
- 06Chapter 6: Documenting Decisions: ADRs and Communicating Trade-offs to Stakeholders
- 07Chapter 7: Moving Cleanly from HLD to LLD Without Losing Intent
- 08Chapter 8: Common Mistakes: Over-Designing, Under-Specifying, and Skipping Non-Functional Requirements
- 09Chapter 9: When LLD Contradicts Its Own HLD
- 10Chapter 10: HLD and LLD in Design Reviews: What Reviewers Actually Look For
- 11Chapter 11: Worked Example: Ride-Sharing Dispatch — Requirements Through HLD to LLD
- 12Chapter 12: Worked Example: Hotel Booking — Requirements Through HLD to LLD
- 13Chapter 13: Worked Example: Food Delivery — Requirements Through HLD to LLD
- 14Chapter 14: How HLD and LLD Show Up in Interviews and Design Reviews
- 15Chapter 15: Common Interview Questions About HLD and LLD
Chapter 7 of 15
Chapter 7: Moving Cleanly from HLD to LLD Without Losing Intent
Why this matters
The transition from an approved HLD to detailed LLD work is where a design's original intent most commonly gets silently eroded — not through any single bad decision, but through the accumulation of small, locally-reasonable LLD choices that each individually seem fine but collectively drift away from what the HLD actually specified or intended. This chapter covers keeping that transition faithful, and handling the realistic cases where LLD work genuinely needs to revisit the HLD.
The core discipline: trace every LLD decision back to an HLD constraint
[BEGINNER] For every significant LLD decision, it should be possible to answer "which HLD decision does this serve, or does this fall outside what the HLD anticipated?" — this single habit is what catches drift early, before it compounds across many components' independent LLD work.
HLD said: "The Notification Service communicates with the Booking
Service asynchronously, via an event queue, specifically to avoid
notification-sending latency affecting the booking confirmation
response time" (companion System Design book, Chapter 8's synchronous
vs. asynchronous reasoning).
LLD drift to watch for: an engineer implementing the Notification
Service's LLD adds a SYNCHRONOUS callback from Notification back to
Booking Service "just to confirm delivery," reintroducing exactly the
latency coupling the HLD explicitly decided to avoid -- this LLD
decision needs to be caught and reconciled against the HLD's stated
intent, not implemented as if it were a purely local, LLD-scoped choice.
When LLD genuinely should revisit the HLD
[SENIOR INSIGHT] Not every HLD-LLD tension is "LLD drifted incorrectly" — sometimes LLD work reveals a genuine flaw or gap in the HLD that the HLD's own level of detail simply couldn't have anticipated, and revisiting the HLD is the correct response, not a failure of the original design process. The distinguishing question: does the LLD-level discovery reveal that an HLD assumption was actually wrong, or does it just reveal an implementation convenience that would be nice to have at the cost of violating the HLD's actual intent? The first case warrants revisiting the HLD explicitly (and updating any associated ADR, Chapter 6); the second case warrants finding an LLD-level solution that honors the HLD's original constraint instead.
Genuine HLD flaw (revisit HLD): LLD work on the Booking Service reveals
that the assumed database (a document store, chosen in HLD for schema
flexibility) can't efficiently support a REQUIRED query pattern
(complex date-range availability queries) that wasn't fully considered
when the HLD's technology choice was made -- this is a genuine gap
requiring the HLD's database decision to be revisited, ideally with an
updated ADR documenting why.
Implementation convenience, NOT a genuine flaw (find an LLD solution
instead): an engineer finds it "easier" to make a synchronous call
between two services the HLD specified as asynchronous, purely for
implementation convenience -- this should be resolved by finding an
LLD approach that honors the HLD's asynchronous requirement, not by
quietly overriding the HLD's actual intent.
Practical mechanisms for keeping the transition faithful
[IN PRACTICE]
## Practices that keep HLD intent intact through LLD
1. Reference the specific HLD section/decision each LLD document is
built against, explicitly, at the top of the LLD document itself.
2. When an LLD decision conflicts with the HLD, flag it EXPLICITLY in
the LLD review (Chapter 10) rather than silently resolving it
unilaterally -- let the reviewer (or the original HLD's author)
weigh in on whether this is a genuine flaw or an implementation
convenience that shouldn't override the HLD.
3. Update the HLD document (and any associated ADR) when a genuine
flaw is found and the HLD is deliberately revised -- don't leave
the original HLD looking authoritative when it's actually been
superseded by a later, better-informed decision.
Common mistakes
- Letting LLD decisions silently drift from HLD intent through an accumulation of individually-reasonable-seeming local choices, without anyone explicitly checking each significant LLD decision against the HLD it should be serving.
- Treating every HLD-LLD tension as "the HLD was wrong," using genuine LLD-level discoveries as cover for implementation conveniences that actually violate the HLD's real, still-valid intent.
- Treating every HLD-LLD tension as "LLD must conform no matter what," missing genuine cases where LLD work has revealed a real, previously-unknown flaw that warrants revisiting the HLD.
- Revising the HLD without updating its documentation/ADR, leaving an out-of-date HLD document that misleads future readers about what was actually decided and why.
Discussion / interview questions
-
"How would you make sure detailed LLD work stays faithful to an approved HLD's actual intent?" Strong answer: For every significant LLD decision, explicitly trace it back to the HLD decision it serves — this habit catches silent drift (small, individually-reasonable LLD choices that collectively violate the HLD's intent) before it compounds across many components' independent work.
-
"When should LLD work trigger revisiting the HLD, versus finding a way to conform to it?" Strong answer: Revisit the HLD when LLD work reveals that an actual HLD assumption was wrong (a chosen technology can't support a required query pattern); find an LLD-level solution instead when the tension is really just an implementation convenience that would violate the HLD's still-valid intent.
-
"An engineer implementing LLD for a component the HLD specified as asynchronous decides to make it synchronous 'because it was easier.' How would you handle this?" Strong answer: Flag this explicitly rather than letting it proceed silently — this is an implementation convenience overriding a deliberate HLD decision (likely made specifically to avoid a latency coupling), not a genuine flaw in the HLD; find an LLD-level way to honor the original asynchronous requirement instead.
-
"If LLD work genuinely reveals a flaw in the HLD, what should happen to the HLD documentation?" Strong answer: The HLD document (and any associated ADR) should be explicitly updated to reflect the revised decision and the reasoning for the change — leaving the original HLD looking authoritative and unchanged would mislead future readers about what was actually decided.
Chapter summary / cheat sheet
- Trace every significant LLD decision back to the specific HLD decision it serves — this catches silent, accumulating drift from the HLD's actual intent before it compounds.
- Distinguish a genuine HLD flaw (revealed by LLD work, warranting revisiting the HLD) from an implementation convenience (should be resolved at the LLD level, honoring the HLD's original intent instead).
- Flag HLD-LLD tensions explicitly during review rather than resolving them silently and unilaterally.
- Update HLD documentation and any associated ADR when a genuine, deliberate revision happens — don't leave a superseded HLD looking authoritative.