</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 6: Six Boxes and Five Deliberate Absences - High-Level Architecture

Executive Summary: The architecture for the Marlin Bay Miami is mostly an exercise in subtraction. Six boxes carry it: static delivery, a stateless API, a PostgreSQL primary with a synchronous standby, and three things we do not own — payments, identity, and the property-management system. Every component a candidate instinctively reaches for is then refused by name, with the ledger number that vetoes it and the trigger that brings it back: no cache at 0.76 peak search QPS, no search index for four room types, no queue in the commit path, no shards for 340 MB, no second serving region for a building already in the hurricane's path. We then label the escape hatches, so Section 8's chain-scale rebuild walks through doors instead of knocking out walls.

Section 5 settled what a room is here: a counter on a row keyed by (property_id, room_type_id, stay_date). Dana Reyes's three-night Ocean-View Suite is three rows, decremented in one transaction. That decision has already done most of the architectural work — the diagram serving it is embarrassingly small, and the interesting conversation is no longer about what you drew.

The Six Boxes

Architecture of the six boxes: guest browser, CDN, load balancer, reservation API, PostgreSQL primary and standby, plus identity, payment and property-management systems

Draw the two paths separately: at Stage A they overlap, at Stage B they diverge beyond recognition.

The read path. A guest opens the date picker. The page comes from the CDN; the availability call reaches either API instance, which runs one indexed range scan over inventory — a few dozen rows for a normal stay — and returns room types with per-night rates. Budget: p95 under 150 ms, the SLO that gates the date picker feeling interactive. An in-buffer-pool query has no trouble here; most of that 150 ms is network.

The write path. POST /v1/holds opens a transaction, conditionally increments held_count on each of Dana's three date rows, and commits — p95 under 500 ms. POST /v1/bookings authorises the card at the PSP, writes the booking, and converts the hold — p99 under 4 s, most of it the authorisation round trip to a provider we do not control, which is why that budget is the loosest we set. The capture is not on this path at all: it rides the outbox, and for the FLEX-REF rate plan it happens at check-in. The commit returns MBM-7K4P2Q synchronously; only after commit does the outbox relay push to the PMS, the confirmation email, and the audit trail.

The three external boxes are things we would be reckless to build: card handling (PCI scope we decline), identity (Section 1's trust boundary), and the PMS the front desk lives in.

Key Insight: Two API instances exist for availability, not throughput. One absorbs 0.76 peak search QPS and a booking write every two minutes without noticing; the second exists so a deploy, a patch, or an instance dying at 2 a.m. is not an outage on a path with a 99.99% target. Sizing for redundancy and sizing for load are different arguments, and conflating them means defending the wrong number.

Quick check before moving on:


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.