The System Design Newsletter

The System Design Newsletter

System Design Interview: Design Airbnb

#113: System Design Interview

Neo Kim's avatar
Hayk's avatar
Neo Kim and Hayk
Jan 15, 2026
∙ Paid

Get my system design playbook for FREE on newsletter signup:

  • Share this post & I'll send you some rewards for the referrals.

  • Block diagrams created using Eraser.


A hotel booking system like Booking.com or Airbnb is a common system design interview question.

It looks simple, right until it breaks in the worst way.

Two users click “Book” on the last available room in the same second. Your API does a SELECT check, so both requests see availability, and you charge two credit cards for one room. Next, you’re dealing with refunds, angry customers, and a system that can’t be trusted.

And that’s not a bug… That’s the default outcome if you don’t design it correctly.

This is why Airbnb and Booking.com aren’t just “tables + endpoints”.

Most developers jump straight into boxes and arrows without understanding the actual problems. They miss concurrency1 traps, forget double booking2, and can’t explain tradeoffs.

In this newsletter, we’ll design it the way interviews and real traffic demand: with strong consistency for inventory, fast reads for search, and clear tradeoffs for caching and scaling.

But before we design anything, let’s zoom out, define the real problem, and lay out the approach step by step.

Onward.


Find out why 150K+ engineers read The Code twice a week (Partner)

Tech moves fast, but you’re still playing catch-up?

That’s exactly why 150K+ engineers working at Google, Meta, and Apple read The Code twice a week.

Here’s what you get:

  • Curated tech news that shapes your career - Filtered from thousands of sources so you know what’s coming 6 months early.

  • Practical resources you can use immediately - Real tutorials and tools that solve actual engineering problems.

  • Research papers and insights decoded - We break down complex tech so you understand what matters.

All delivered twice a week in just 2 short emails.

Sign up and get access to the Ultimate Claude code guide to ship 5X faster.

Join 150K+ Engineers

(Thanks for partnering on this post and sharing the ultimate claude code guide.)


I want to reintroduce Hayk Simonyan as a guest author.

He’s a senior software engineer specializing in helping developers break through their career plateaus and secure senior roles.

If you want to master the essential system design skills and land senior developer roles, I highly recommend checking out Hayk’s YouTube channel.

His approach focuses on what top employers actually care about: system design expertise, advanced project experience, and elite-level interview performance.


Let’s dive in!

What You’ll Learn

  • Design Requirements - How to scope the system

  • Back of the Envelope Calculations3 - Math that proves you understand scale

  • High-Level Design - System components and architecture

  • API Design - RESTful endpoints

  • Data Model - Schema decisions that matter

  • Handling Concurrency - Real approaches that work in production

  • Scaling the System - What happens when you hit real traffic

  • Handling Failures and Edge Cases - Problems that break systems


Design Requirements

Every well-architected system design starts with constraints.

If you skip this step, everything that follows is guesswork.

Clarifying Questions

Here are some clarifying questions we’ll ask about the design requirements.

  • Scale:

    • How many hotels?

    • How many rooms in total?

    • Single chain or platform like Booking.com?

  • Payment timing:

    • Pay at booking or check-in?

  • Booking channels:

    • Web only?

    • Mobile apps?

    • Phone reservations?

  • Cancellation:

    • Can users cancel?

    • What’s the policy?

  • Overbooking4:

    • Do we support it? (Hotels typically allow 5-10% overbooking)

  • Dynamic pricing:

    • Does the room price change based on demand/date?

With these constraints clarified, we can now define what the system must actually do.

Functional Requirements

  • Hotel Management: Admins can add, update, and remove hotels and room types. They adjust pricing and inventory5.

  • Search & Discovery: Users can search for hotels by location, dates, guest count, price range, and amenities.

  • Reservation Flow: Users can book rooms, view reservations, and cancel bookings. The system should prevent double bookings.

  • Payment Processing: Integrate with payment gateways. And handle failures gracefully.

  • Notifications: Send confirmations for bookings, cancellations, and payments.

Functional requirements define behavior, while non-functional requirements determine whether the system can withstand real traffic.

Non-Functional Requirements

  • Strong Consistency: Two users cannot book the same room for the same dates. Non-negotiable.

  • High Concurrency: Handle thousands of users trying to book the same hotel simultaneously.

  • Low Latency: Search results under 500ms. Booking confirmation in 2-3 seconds.

  • High Availability: 99.9%+ uptime.

  • Scalability: Scale horizontally without redesigning the system.

Now that we know what the system must support, let’s start with back-of-the-envelope calculations.


Back of the Envelope Calculations

Booking Holdings reported over 1.1 billion room nights6 in 2024.

Let’s turn that into usable numbers:

Assumptions

  • Room nights per year: 1.1 billion

  • Average stay: 2 nights per booking

  • Days per year: 365

Daily Reservations and TPS

Bookings per year:

  • 1.1B room nights / 2 nights per booking ≈ 550M bookings/year

Bookings per day:

  • 550M / 365 ≈ 1.5M bookings/day

Bookings per second (TPS7):

  • 1.5M / 86,400 ≈ 17 bookings/second

At Booking.com scale:

  • ~1.5 million bookings per day

  • ~17 bookings per second on average

Traffic Funnel and Read QPS

Similarweb shows ~516.5 million visits per month to booking.com with about 7.56 pages per visit.

Visits per day:

  • 516.5M / 30 ≈ 17M visits per day

Visits per second:

  • 17M / 86,400 ≈ 200 visits per second

If we assume around 5 backend reads per visit (search queries, availability checks, pricing):

  • Backend read QPS8 ≈ 200 visits/s × 5 ≈ 1,000 read requests per second

Key insights:

  • This is strongly read-heavy.

  • You handle around 1,000 read QPS and only ~17 write TPS.

  • Your architecture should optimize for reads while keeping writes consistent.

Storage Estimation

For the inventory table, tracking availability by room type and date.

Assume:

  • Average hotel occupancy: 70%

  • Room nights sold per year: 1.1B

Total annual capacity:

  • 1.1B / 0.7 ≈ 1.57B room nights/year

Total rooms on the platform:

  • 1.57B / 365 ≈ 4.3M rooms

If an average hotel has 50 rooms:

  • ~85,000 hotels globally

Room type inventory table rows:

  • Hotels: ~85,000

  • Average room types per hotel: 10

  • Horizon: 2 years = 730 days

Rows:

  • 85,000 × 10 × 730 ≈ 620M rows

Assuming each row is around 100 bytes:

  • Storage ≈ 620M × 100 bytes ≈ 62 GB of raw data

Reality check:

With indexes (typically 2-3x table size), related tables (reservations, hotels, guests), you’re looking at 500GB+ total.

So you need a proper ‘sharding and indexing strategy’.


High-Level Design

With the scale and data size understood, we can design an architecture that actually fits these numbers…

We’re using a service-oriented architecture with clear boundaries, but keeping “tightly coupled” data on the same database.

Core Components

Client Layer

  • Web and mobile apps

  • CDN for static assets (images, JavaScript, hotel photos)

API Gateway

  • Single entry point

  • Authentication, rate limiting, request routing

  • Load balancing across service instances

Services

  • Hotel Service: Hotel and room information. Mostly static, heavily cacheable.

  • Rate Service: Room pricing by date. Dynamic pricing based on demand.

  • Reservation Service: Handles booking logic, inventory checks, and reservation creation/cancellation. This is where concurrency matters.

  • Payment Service: Integrates with payment gateways. Updates the reservation status.

  • Notification Service: Sends emails and push notifications.

  • Search Service: Manages Elasticsearch9 integration for hotel discovery.

Data Layer

  • PostgreSQL: Primary transactional store. ACID guarantees10.

  • Redis: Cache for hot data.

  • Elasticsearch: Search functionality (full-text, geospatial, filtering).

Why This Architecture?

Once services and boundaries are clear, the next step is defining how clients and services interact…

At this scale, a pure monolith or a full microservices setup would be suboptimal.

A single monolith simplifies transactions but becomes hard to scale and deploy independently. Full microservices with separate databases introduce distributed transactions and consistency problems that don’t exist at this traffic level.

This design uses service-level separation with shared transactional data for tightly coupled domains (reservations + inventory). It maintains deployment flexibility while preserving strong consistency where it matters most.

Each service owns its domain and scales independently.

Hotel Service might need 10 instances for search traffic, while Reservation Service only needs 3 since booking TPS is low.

Critical decision:

Reservation and inventory data live in the same database.

This lets us use local ACID transactions instead of distributed transactions. We have service-level separation at the application layer, but shared data for tightly coupled entities.

This is pragmatic.

Distributed transactions add massive complexity for minimal benefit here. The alternative (separate DBs with saga patterns or 2PC) is overkill when you can keep related data together.

Alternative:

Split reservations and inventory into separate databases and coordinate with Saga patterns11 or Two-Phase Commit12 (2PC).

2PC provides strong consistency but adds latency, blocking, and failure complexity. A coordinator failure can stall the system.

Saga patterns avoid locking but introduce eventual consistency13, compensating actions, and complex failure handling. This is risky for user-facing booking flows where “eventually consistent” means angry users.

At ~17 write TPS, the added complexity is not justified… Local ACID transactions are simpler, safer, and faster.


API Design

RESTful APIs for all operations:

Hotel APIs (Admin)

  • GET /v1/hotels/{id} - Get hotel details

  • POST /v1/hotels - Add a new hotel (admin only)

  • PUT /v1/hotels/{id} - Update hotel info (admin only)

  • DELETE /v1/hotels/{id} - Remove hotel (admin only)

Room Type APIs (Admin)

  • GET /v1/hotels/{id}/rooms/{id} - Get room type details

  • POST /v1/hotels/{id}/rooms - Add room type (admin only)

  • PUT /v1/hotels/{id}/rooms/{id} - Update room type (admin only)

  • DELETE /v1/hotels/{id}/rooms/{id} - Delete room type (admin only)

Reservation APIs

  • GET /v1/reservations - Get the user’s reservation history

  • GET /v1/reservations/{id} - Get specific reservation details

  • POST /v1/reservations - Create a new reservation

  • DELETE /v1/reservations/{id} - Cancel reservation

Search API

  • GET /v1/search

  • Parameters: location, checkIn, checkOut, guests, beds, priceRange

  • Returns: available hotels and room types

Critical Detail for Reservations

POST /v1/reservations request includes an idempotency key14:

This reservationId is generated on the frontend and prevents double bookings when users click submit many times.

APIs define behavior, but the data model determines whether the system can enforce correctness.

Let’s keep going!


Data Model

Here’s a critical insight:

This post is for paid subscribers

Already a paid subscriber? Sign in
Hayk's avatar
A guest post by
Hayk
I help fullstack developers break out of the mid-tier trap and scale into multi six-figure remote careers.
Subscribe to Hayk
© 2026 Neo Kim · Publisher Privacy
Substack · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture