Reviewed by 6 specialized AI reviewers. Explore the diagram and the full per-section feedback below.
Loading diagram…
The candidate demonstrates good system design instincts, especially around consistency tradeoffs, read/write separation, and booking workflow correctness. The design is meaningfully structured and mostly aligned to the requirements, but there are important scale-related gaps in search, write scalability, and capacity rigor that keep it below a clear hire.
Correct consistency tradeoff for booking vs browsing
The design explicitly distinguishes booking from event browsing: stronger consistency for ticket booking and eventual consistency for browsing/search. That is the right non-functional split for this problem because overselling seats is more harmful than slightly stale event listings.
Latency target is stated
A concrete low-latency goal for event-facing flows is included. Even though it is broad, having an explicit latency target is better than leaving performance undefined and gives later design choices something to optimize against.
Scale assumptions are acknowledged
The NFRs reference the stated large-scale workload and also call out the celebrity/hotspot problem, which shows awareness that traffic will be highly skewed and that the system must handle flash-demand scenarios, not just average load.
Availability target is missing
The checklist requires basic NFRs to mention availability, but no explicit SLA/SLO is given for browsing/search or booking. Add concrete targets such as 99.9% or 99.99% availability, and ideally separate them by flow because booking may accept lower availability in exchange for stronger correctness.
Consistency requirement is not precise enough for booking
Saying 'Consistency >> Availability' is directionally correct, but it does not define the actual guarantee needed. Specify what must be strongly consistent, for example seat inventory updates and booking confirmation must be linearizable or protected by serializable transactions / conditional writes, while read models can lag.
Latency target is too broad across different operations
The stated '<< 200 ms' target is useful, but it appears to apply generally to 'events' without separating browse/search from booking. Booking often includes payment and contention, so define per-operation targets such as p95 browse/search latency and a separate booking confirmation target.
Scale numbers are somewhat ambiguous
The scale section mentions '100k events' and '10M booking' but the wording is unclear and mixes inventory size with traffic. Tighten this into measurable throughput assumptions like peak reads/sec, peak booking attempts/sec, and hotspot traffic for popular events so the NFRs can be validated more concretely.
Covers the main booking nouns
The entity list includes the core domain objects needed for the stated requirements: User for the actor, Event for discovery and viewing, and Ticket/Order for booking flow. This is a solid foundation for an event ticketing system.
Venue is appropriately modeled separately
Listing Venue as its own entity is a good choice because events are naturally associated with a location, and separating it from Event keeps the core domain model cleaner and more realistic.
Seat-related entity is missing
Given the assumptions explicitly talk about large numbers of seats per event, the core domain should include a Seat-related noun (for example Seat or Inventory) to represent what is actually being booked. Without that entity, the relationship between an event and the tickets being sold is underspecified. Add a Seat or equivalent inventory entity tied to Event/Venue and consumed by Ticket/Order.
Basic capacity numbers are too sparse
You included DAU and rough QPS, which is a good start, but the sizing is incomplete for this scale. For this problem, capacity should at least translate the assumptions into core traffic numbers for event views/searches and bookings, and ideally mention peak QPS rather than only average QPS. Add a simple breakdown such as searches/day, bookings/day, average QPS, and a peak multiplier (for example 3x-10x) so the rest of the design can be sized safely.
QPS math appears inconsistent with the stated assumptions
With 100M DAU and 10 searches per user per day, that is about 1B searches/day. Dividing by 86,400 seconds gives roughly 11.6K QPS, so the 12K QPS search estimate is in the right range. However, the booking number of 1.2K QPS is not justified from the assumptions shown. A 10:1 read:write ratio would imply about 1.2K writes only if all reads are searches and all writes are bookings, which should be stated explicitly. Also, event views are a separate functional requirement and may add substantial read traffic. Show the formula for each number so the reviewer can verify the logic.
Scale assumptions are not converted into storage or inventory volume
The assumptions mention event and seat counts, but the calculation section does not turn them into total inventory or storage estimates. Even rough numbers like total seats across all events and expected booking record volume would make the capacity planning more methodical. Add a back-of-the-envelope estimate for event metadata size, seat inventory size, and booking growth per day.
Peak traffic and hot-event behavior are not accounted for
At 100M DAU, average QPS alone is usually not enough because ticketing systems often see bursty demand around popular events. Even if your average search QPS is about 12K, peak could be much higher. Add a peak assumption and size for that number so the capacity plan stays in the right ballpark under realistic load spikes.
Core routes map directly to the requirements
The API includes a route to view an event, a route to search events, and a route to book tickets, which aligns cleanly with the stated functional requirements without adding unnecessary surface area.
Search API includes practical filtering and pagination inputs
Using keyword, date range, page size, and page number gives clients a usable search interface and shows good REST-style query parameter usage for a read endpoint.
Booking route mixes resource identity into the path awkwardly
POST /bookings/:eventId is not ideal REST structure because bookings are the primary resource being created, while the event is an attribute of that booking. A cleaner design would be POST /bookings with eventId and ticketIds in the body, or POST /events/:eventId/bookings if you want to scope bookings under an event.
No API to retrieve booking details after creation
The design returns only bookingId from the create call, but there is no corresponding GET /bookings/:bookingId route. Since booking is a primary entity created by the system, basic CRUD coverage is incomplete. Adding a read endpoint would let clients confirm booking status and display booking details.
Event details response is too heavy for seat-map delivery
GET /events/:eventId returns Event, Venue, Performer, and Ticket[] with all tickets used to render the seat map. Given the stated scale and up to very large seat counts, returning every ticket in the event details response can make the endpoint expensive and slow. A better API split would be GET /events/:eventId for event metadata and a separate seat inventory endpoint such as GET /events/:eventId/tickets or GET /events/:eventId/seats with filtering by section/availability.
Search response shape could be more explicit
GET /events/search returns Event[] but does not indicate whether total count, next page token, or page metadata is included. Adding pagination metadata makes the API easier for clients to use consistently, especially when browsing large result sets.
Read replicas and cache for read-heavy event traffic
Using read replicas behind the event/search path plus Redis cache is a solid high-level choice for the view/search requirements. It separates read traffic from booking writes and gives a reasonable path to scale popular event lookups.
Booking flow includes seat hold and cleanup
The design explicitly models seat status, versioning, and a cleanup job for held/failed bookings. That is a correct architectural pattern for ticketing systems because it prevents seats from being blocked forever and supports temporary reservation before payment completes.
Asynchronous communication service integration
Publishing booking-related events to a queue/pub-sub system and handling notifications asynchronously is a sensible decoupling choice. It keeps the booking path focused on the critical transaction while offloading non-blocking follow-up work.
Search architecture is incomplete for event discovery at stated scale
The search service is shown reading from a read replica and cache, but there is no dedicated search index or indexing pipeline. For keyword, location, and performer queries across a very large catalog, relying on Postgres replicas will not scale well and will limit relevance and latency. Add a search datastore such as Elasticsearch/OpenSearch/Solr and an async pipeline from the source of truth to keep the index updated.
Single primary database is a bottleneck for booking writes
All seat verification, holds, order creation, and cleanup appear to converge on one Postgres primary. With the stated assumptions, especially large seat inventory and concurrent booking spikes, this becomes a write hotspot and availability risk. Partition booking-related data by event or venue, or introduce sharding/partitioning for seat and order tables so booking load can scale horizontally.
Event and search service connectivity is not fully shown end-to-end
The user-facing flow is only partially connected in the diagram. Users are annotated with GET endpoints, but there are no explicit connections from Users/API Gateway to Event Service, Search Service, or Booking Service. This makes the end-to-end request path ambiguous. Add those edges so the architecture clearly shows how each functional requirement is served.
Duplicate services create ambiguity in component ownership
The diagram contains duplicate Event Service and Search service nodes without clear distinction, and only one of each appears connected meaningfully. This makes it unclear whether these are replicas, separate tiers, or accidental duplicates. Consolidate them or label them explicitly as horizontally scaled instances behind the load balancer.
Queue choice is weak for durable booking events
Redis pub/sub is not ideal as the primary backbone for critical booking event propagation because plain pub/sub does not provide strong durability or replay guarantees. If communication or downstream processing must not miss booking events, use a durable queue/stream system such as Kafka, SQS, RabbitMQ, or Redis Streams with explicit consumer tracking.
No clear failover story for core stateful components
Read replicas improve read scale, but the design does not show redundancy/failover for the primary Postgres or Redis components. This is an operational readiness gap rather than a functional blocker in the diagram. Add primary-standby database failover and highly available cache/queue deployment to improve resilience.
Draw your architecture for Ticket Booking System and get an instant hire/no-hire signal from 6 specialized AI reviewers — free to start.