Here’s the same style, but for a multi-provider booking marketplace like Booksy / Fresha / Treatwell.
Design a booking platform where many users can discover and book appointments with many service providers such as:
Cleaning
Home repair
Plumbing
Beauty
Massage
Tutoring
The platform must support provider schedules, time-slot availability, booking creation, and conflict prevention.
Search providers by service and location
View available slots
Book an appointment
Cancel or reschedule a booking
Define working hours
Block unavailable time
Manage services and durations
Accept or auto-confirm bookings
Many providers
Many concurrent users
Preventing double booking
Notifications for confirmation / cancellation
High availability
Low-latency availability lookup
Strong consistency for booking creation
Horizontal scalability
Idempotent booking requests
Support traffic spikes during peak hours
Candidates should arrive at something like this.
Users / Providers
│
▼
API Gateway
│
┌─────┼───────────────┐
▼ ▼ ▼
Search Service Availability Service Booking Service
│ │ │
▼ ▼ ▼
Search DB Cache + Slots DB Transactional DB
│
▼
Queue / Event Bus
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
Notification Service Calendar Sync Analytics/Audit
provider_id
service_types
location
rating
working_hours
booking_rules
provider_id
date
start_time
end_time
status: FREE / HELD / BOOKED / BLOCKED
booking_id
user_id
provider_id
service_id
start_time
end_time
status: PENDING / CONFIRMED / CANCELED
Search traffic is much higher than booking traffic.
So split into:
Search service for browse/filter/read-heavy workload
Booking service for correctness and transactions
Search can be eventually consistent.
Booking must be strongly consistent.
Two common ways:
Generate 15-min / 30-min slots ahead of time.
Pros:
Fast reads
Easy UI rendering
Cons:
More storage
Harder for flexible durations
Compute free intervals on read.
Pros:
More flexible
Less storage
Cons:
In interview, strong answer:
Use precomputed slots for next 30–60 days
Recompute on provider schedule change / cancellation
This is the most important part.
Two users may try to book the same provider/time at once.
Use a transactional booking DB with an atomic constraint.
Examples:
SQL transaction with unique constraint on (provider_id, start_time, end_time) or slot_id
Or lock selected slot row: SELECT ... FOR UPDATE
Flow:
User chooses slot
Booking service starts transaction
Verify slot still FREE
Mark slot BOOKED
Insert booking row
Commit
Only one request succeeds.
Real systems often place a short hold.
Example:
Slot becomes HELD for 5 minutes
User completes payment
Then booking becomes CONFIRMED
If timeout happens, hold expires back to FREE
This avoids users losing a slot during checkout.
Implementation:
Redis or DB hold record with expiration
Final confirmation still must go through transactional booking DB
Users may retry due to timeout or double-click.
Use:
idempotency_key
same request with same key returns same booking result
Without this, duplicates can happen even if slot conflict is protected.
Elasticsearch / OpenSearch / Postgres read replica
Good for:
location
category
text search
ranking
Postgres / MySQL
Good for:
transactions
row locks
unique constraints
strong consistency
Redis
Good for:
hot provider pages
availability cache
temporary slot holds
Because:
availability is read-heavy
booking is write-critical
they scale differently
Because booking correctness needs:
transactions
locking
uniqueness guarantees
This is usually stronger than trying to solve it only with NoSQL.
Need recomputation:
future free slots regenerated
existing confirmed bookings remain
conflicting future free slots removed
On cancellation:
booking marked canceled
corresponding slot reopened
event published to notifications / calendar sync
Solved by DB-level transactional guarantee, not by app memory.
Never rely on:
local mutex
cache-only lock
single instance logic
Because system is distributed.
read replicas
cache hot providers
geo indexes
separate search cluster
shard by provider_id or region if needed later
keep a single transactional boundary per provider schedule
queue async side effects only after booking commit
Search results can be slightly stale
Booking creation cannot be stale
Precompute improves UX
Dynamic logic improves flexibility
Holds improve checkout UX
But increase complexity and slot starvation risk
What happens if notification sending fails after booking is confirmed?
Good answer:
booking commit is source of truth
notification is async via queue
retry failed notifications separately
How do you prevent two users booking the same slot?
Good answer:
SQL transaction
lock row / unique constraint
one wins, one gets conflict
What if you have millions of providers?
Good answer:
shard search/index by geography
shard booking by provider region/provider_id
cache hot calendars
only precompute near-term slots
Where should payment happen?
Good answer:
usually hold slot first
process payment
confirm booking
or book then authorize depending on business model
How do you track provider/user actions?
Good answer:
append audit events for booking create/cancel/reschedule
async publish to audit log system
Strong candidate signals:
separates search from transactional booking
identifies double-booking prevention as core challenge
uses DB transaction / unique constraint
introduces holds, idempotency, and async notifications
explains tradeoff between fast reads and correct writes
Weak signal:
“just store bookings in Redis”
“check then insert” without transaction
“use cache lock only”
no strategy for concurrent booking
Design a booking marketplace similar to Booksy where many users can browse providers, view available time slots, and book services like cleaning or repair. The system should support provider schedules, cancellations, rescheduling, and notifications, while preventing double booking under high concurrency.
Clarify entities: users, providers, services, slots, bookings
Separate read path from booking path
Design provider schedule + slot model
Solve double booking with SQL transaction
Add hold flow, idempotency, notifications
Discuss scaling and failure cases
If you want, I can turn this into a full interview-ready answer with diagram + exact words to say aloud.