DrawLintDrawLint.ai

Airline Reservation System — system design by FierceOtter34

Lean Hire

Reviewed by 6 specialized AI reviewers. Explore the diagram and the full per-section feedback below.

Loading diagram…

Hire SignalLean Hire

The candidate demonstrates strong architectural judgment on the hardest part of the problem—the correctness of booking under concurrency—and shows good familiarity with production patterns like outbox, OCC, replicas, and idempotency. The main gap is senior-level rigor in turning assumptions into concrete capacity, HA, and API/domain design decisions; this is good but not fully complete.

✅ Good

Different consistency priorities by workflow

The design correctly distinguishes between read-heavy flight search/ticket info and the booking path, prioritizing availability for search while requiring stronger durability/consistency for ticket booking. That is an appropriate NFR split for this problem.

warning

NFRs are not measurable

The section mentions goals like 'low latency', 'scalability', and 'durability' but does not define concrete targets such as p95/p99 search latency, booking API latency, uptime SLA, or recovery objectives. For a senior-level design, specify measurable targets like search p99 < 200ms, booking confirmation p99 < 1s, availability 99.9%+ for search and 99.99% for booking data durability, plus RPO/RTO.

warning

Consistency model is only partially specified

Saying 'availability > consistency' for search and 'durability and consistency' for booking is directionally correct, but it does not explicitly choose a consistency model. A senior answer should state that search results and seat info can be eventually consistent or read-after-refresh, while seat reservation/booking must use strong consistency or serializable guarantees to prevent overselling.

warning

Targets are not tied to stated scale assumptions

The assumptions provide enough numbers to derive expected load, such as roughly 50M searches/day and 1M bookings/day with 500K peak concurrent users, but the NFRs do not translate those into throughput or capacity expectations. Tie latency and availability goals to these assumptions, for example expected peak QPS for search and booking, and define what level of spike the system should absorb.

info

Availability requirement is incomplete

The section states availability preference for search but does not define explicit availability expectations for each user-facing flow, including past bookings. Add per-flow SLAs, such as search availability versus booking history availability, so tradeoffs are clear and testable.

warning

Core booking concept is missing

The listed nouns do not include a Booking entity, even though 'book tickets' and 'see past bookings' are explicit core flows. Ticket alone is not enough to clearly model a user's purchase/history record. Add Booking as a first-class entity that connects User to one or more Ticket(s) for a Flight.

warning

Relationships between entities are not defined

The design lists entities but does not describe how they relate. At Senior level, the core relationships should be explicit, such as Flight 1:N Seat, Flight 1:N Ticket, User 1:N Booking, and Booking 1:N Ticket. Defining these relationships is necessary to show the domain model supports flight browsing, ticket booking, and booking history.

info

Entity set is too thin for the full core flow

User, Flight, Seat, and Ticket are relevant nouns, but the model is incomplete for the stated requirements because it does not fully represent the lifecycle from selecting a flight to recording a completed booking. Expand the entity model to cover all concepts directly involved in the required user journey.

warning

Peak QPS estimates are inconsistent and not derived methodically

The section mixes average and peak numbers without a clear derivation. For example, 50M searches/day is about 580 searches/sec on average, but then jumps to 100K search/sec from 500K concurrent users with no session behavior, request rate, or peak factor calculation. Similarly, 1M bookings/day is about 12 bookings/sec average, but 5K bookings/sec peak is asserted from '1% books' without explaining over what time window. Derive peak QPS explicitly using assumptions such as peak-hour traffic concentration, searches per active user session, and booking conversion rate.

warning

Missing end-to-end capacity chain beyond QPS

For senior-level capacity work, the calculations should continue from DAU to storage, database growth, and bandwidth. This design stops at rough search/booking QPS and does not estimate how many booking records, flight-seat inventory reads/writes, or past-booking reads must be stored and served over time. Add record size assumptions and project daily and yearly storage for bookings, flight metadata, and any seat availability state, plus network throughput for search and booking responses.

warning

Concurrency assumption is not translated into realistic workload

Stating 500K concurrent users is useful, but concurrency alone does not imply 100K search/sec or 5K booking/sec. A concurrent user may be idle, browsing, or reading past bookings. To make the numbers credible, convert concurrency into active request rates using assumptions like requests per active session per minute and traffic split across search, booking, and booking-history reads.

warning

No validation that calculated load matches the stated business scale

The design does not reconcile traffic with the domain numbers. With 50K flights/day and 200 seats/flight, total daily seat supply is about 10M seats/day, while bookings are 1M/day. That implies only a fraction of inventory is sold, which is plausible, but the capacity section should use these numbers to estimate inventory read amplification and booking write contention. Tie the workload back to the actual flight and seat counts so the scale assumptions feel grounded.

warning

No component sizing or justification by scale

Senior-level capacity review expects the numbers to inform infrastructure choices, but this section does not map the estimated QPS to datastore throughput, cache hit expectations, partitioning needs, or replication scale. Even at a rough level, explain what throughput the search path and booking path must sustain and how many instances/shards are needed under the stated peak assumptions.

✅ Good

Core flight discovery and booking flows are covered

The routes include flight search, flight detail lookup, seat viewing, ticket creation, and ticket retrieval, which maps well to the stated requirements of viewing available flights, booking tickets for a flight, and seeing past bookings.

✅ Good

Mostly resource-oriented REST structure

Using /flights, /flights/:flightId, and /flights/:flightId/seats follows a clear resource hierarchy that makes the API intuitive and easy to evolve.

warning

Booking endpoint is not scoped to the flight resource

POST /tickets works, but for this domain the booking action is more naturally tied to a specific flight, such as POST /flights/:flightId/tickets or POST /bookings. This makes the API clearer, reduces duplicated identifiers in the body, and better reflects the relationship between flights and booked seats.

warning

Primary entity modeling is inconsistent

The requirements talk about booking tickets and viewing past bookings, but the API exposes only /tickets without a clear booking resource. If a booking can contain one or more tickets, introduce a dedicated /bookings resource and return booking history from GET /bookings. If ticket is the true primary entity, make that explicit and keep naming consistent across the API.

warning

No pagination on list endpoints

GET /flights and GET /tickets return collections but do not show pagination controls. At the stated scale, these endpoints should support limit/cursor or page/pageSize parameters and include pagination metadata to avoid large responses and improve latency.

warning

Missing filtering for past bookings endpoint

GET /tickets by itself is underspecified for the requirement to see past bookings. It should be scoped to the current user and ideally support filters such as status or date range, for example GET /bookings?userId=...&from=...&to=... or infer the user from auth and return only that user's history.

warning

Error handling and status codes are not defined

The design does not specify how failures are represented. Define standard HTTP responses such as 200 for reads, 201 for successful booking creation, 400 for invalid input, 404 for unknown flight/seat, 409 for seat already booked, and 500 for server errors, with a consistent error body.

info

Request and response schemas need more structure

The ticket creation body is incomplete and ambiguous for booking semantics. Specify exact field names, types, and whether multiple seats can be booked in one request. Also define response payloads so clients know whether POST /tickets returns a single ticket, multiple tickets, or a booking confirmation.

⭐ Excellent

Correct booking flow with transactional reservation and outbox

The design uses an all-or-nothing transaction to reserve the seat, create a pending ticket, and write a payment event to an outbox before publishing via CDC. This is a strong architecture choice for booking systems because it prevents seat oversell while also avoiding dual-write inconsistencies between the database and message broker.

✅ Good

Concurrency control for seat booking

Using seat versioning with OCC for updates is a good fit for preventing double booking under concurrent purchase attempts. It directly addresses the core correctness risk in ticketing systems.

✅ Good

Search/read path separated with Elasticsearch and replica

Offloading flight discovery to Elasticsearch and introducing a database replica for read-heavy access is a good high-level scaling pattern for the stated search-heavy workload.

✅ Good

Idempotency considered for booking/payment initiation

The UUID-to-status store and idempotent payment request handling show good awareness of retry safety, which is important for client retries and payment gateway interactions.

warning

Core service connectivity is underspecified

The main flight service is not explicitly connected to Elasticsearch, Redis, or Postgres in the diagram, and the ticket service is not explicitly connected to the primary booking database for writes. The intended flow can be inferred from annotations, but at senior level the HLD should clearly show which service owns which datastore and how requests traverse the system end-to-end. Add explicit arrows from API Gateway to Flight Service and Ticket Service, and from those services to their backing stores.

warning

Single primary database is an obvious SPOF for bookings

The design shows one Postgres primary with a replica, but no failover strategy, multi-AZ deployment, or leader promotion path. For 5M DAU and 1M bookings/day, losing the primary would halt booking. Add managed HA Postgres or explicit primary-standby failover across zones, and clarify how services reconnect after failover.

warning

Redis usage is too narrow for the stated read volume

Redis is only shown near ticket booking/idempotency, while flight search, flight details, and seat availability are likely the dominant read paths at 50M searches/day. Without caching hot flight metadata and seat maps, the search and detail path may put unnecessary pressure on Elasticsearch and the database. Add cache-aside or short-TTL caching for popular flight queries, flight detail pages, and seat availability snapshots.

warning

Polling-based booking status can become expensive at peak concurrency

The client polls every 1-2 seconds for ticket status. At 500K peak concurrent users, this can create a large amount of avoidable read traffic on the gateway and ticket service. If polling is retained, responses should be served from Redis/status cache with aggressive TTLs and backoff. Alternatively, use server push or longer polling intervals after payment initiation.

info

Cleanup cron for blocked seats may not scale smoothly

A periodic cron that scans and releases blocked tickets every 10 minutes can create bursty load and delayed seat recovery. A more scalable pattern is to store reservation expiry timestamps and release seats incrementally via delayed jobs, partitioned workers, or indexed expiry scans.

info

Message broker and payment service redundancy are not shown

The async architecture is good, but the diagram does not indicate replicated broker partitions, consumer groups, or multiple payment service instances. At this scale, these components should be horizontally scalable and fault tolerant. Clarify that the broker is clustered and consumers are stateless and replicated.

Want this kind of feedback on your own design?

Draw your architecture for Airline Reservation System and get an instant hire/no-hire signal from 6 specialized AI reviewers — free to start.