Design problems
Booking & traffic spikesMediumSDE-2 30 min

Design doctor appointment booking (Practo)

Asked at
AmazonPracto

The interviewer asks

“Design a doctor appointment platform like Practo. Patients search doctors by specialty and location, see available slots and book an in-clinic visit or a video consultation. Doctors manage their schedules, often also taking walk-in patients and phone bookings at the clinic.”

What a strong answer looks like

A strong answer treats this as a two-sided booking system where the supply side is messy: doctors work across several clinics, change schedules often, run late, and the clinic's front desk also books patients by phone and walk-in. Schedules are stored as rules (weekly recurring sessions with exceptions) and materialised into slots for the next few weeks; booking claims a slot with an atomic conditional update and an idempotency key. The clinic's front desk uses the same inventory (through the platform's clinic software or a sync integration), so there is one source of truth per doctor-clinic calendar. Many Indian clinics run token queues rather than exact times, so the model supports both time slots and session tokens with a live 'current token' status. Search is Elasticsearch with geo, specialty and next-available slot. Reminders reduce no-shows. Health data is sensitive, so access control, consent and audit are first-class. Deep dives: schedule rules to slots, booking correctness with offline channels, token queues and delays, and privacy.

Concepts to mention

schedule rules materialised into slotsconditional update to claim a slotidempotency key on bookingone source of truth across online and desk channelsoffline clinic sync and conflict resolutiontoken queue mode with atomic incrementslive delay status in RedisCDC to Elasticsearch for next availablereminders and no-show handlinghealth data privacy and audit

1 Requirements

Functional

  • Search doctors by specialty, symptom, locality, language, fee and next available time; view profile, clinics, ratings.
  • See available slots per doctor per clinic for the next ~2-4 weeks; book in-clinic or video consult.
  • Doctors and clinic staff define weekly schedules, leaves, and slot length or token limits per session; block or reschedule slots.
  • Front desk books phone and walk-in patients in the same calendar.
  • Reminders (SMS/WhatsApp) before the visit; cancel and reschedule; live status of delays ('doctor running 30 min late', current token).
  • Pay online for video consults (and optionally prepay clinic fees); refunds for doctor cancellations.
  • Prescriptions and visit notes attached to the appointment (for video consults).

Non-functional

  • Scale: ~200k doctors, ~300k bookings/day, ~10M searches/day.
  • No double booking of a slot; token numbers unique per session.
  • Search p95 under 300 ms; booking p95 under 500 ms.
  • Availability 99.95% for booking; clinic software must work during internet outages (local mode, sync later).
  • Health data protected: encryption, role-based access, audit trail, consent (India's DPDP Act; ABDM standards if integrating health records).
  • Reminders sent at the right local time; no reminder to cancelled appointments.

Out of scope (say it out loud)

  • Video calling infrastructure (use a WebRTC provider).
  • Medicine delivery and lab tests.
  • Insurance claims.

2 Estimates

Doctors and calendars~200k doctors, ~300k doctor-clinic calendarsMany doctors practise at 2-3 clinics; each doctor-clinic pair is a calendar.
Slots materialised~150M slot rows300k calendars × ~25 slots/day × 21 days ≈ 160M; small rows, partitioned by calendar.
Bookings~300k/day ≈ 3.5/s avg, ~30/s peakMorning 9-11 am bookings and Monday peaks ~8x average.
Searches~10M/day ≈ 120/s avg, ~1k/s peakLook-to-book ~30:1.
Slot availability reads~2-3k/s peakEach search result page shows next available slots for ~10-20 doctors; served from cache.
Reminders~600k messages/day~2 reminders per booking (day before, 1-2 hours before).
Storage~50 GB slots, ~1 TB/yr recordsSlots ~300 bytes each; appointments and notes grow ~1 TB/year with attachments in S3.

3 API

EndpointWhat it does
GET/v1/doctors/search?specialty=&lat=&lng=&date=&lang=Ranked doctors with next available slot; Elasticsearch.
GET/v1/calendars/{doctor_clinic_id}/slots?from=&to=Free slots or token availability per session.
POST/v1/appointmentsBook {slot_id | session_id, patient_id, type}; Idempotency-Key; returns appointment and payment intent if prepaid.
POST/v1/appointments/{id}/rescheduleAtomically move to another slot (claim new, release old).
POST/v1/appointments/{id}/cancelCancel by patient or doctor; refund per policy.
PUT/v1/calendars/{id}/scheduleDoctor updates weekly rules, leaves and slot length; regenerates future slots.
GET/v1/sessions/{id}/liveCurrent token, delay estimate; SSE or poll.
POST/v1/clinic/syncClinic software pushes offline bookings and pulls online ones (cursor-based).

4 Data model

doctors / clinics / calendarsPostgres
doctor_idnamespecialtieslanguagesregistration_no; clinic_idlocation; calendar_id (doctor_id, clinic_id)feemode (slots|tokens)

Source for search via CDC to Elasticsearch.

schedule_rulesPostgres
calendar_idweekdaystart_timeend_timeslot_minutes or max_tokensvalid_fromvalid_totimezone; exceptions (date, type: leave|extra)

The doctor's intent. Small and edited often.

slotsPostgres partitioned by calendar_id (hash) and date
slot_idcalendar_idstart_atend_atstatus (OPEN|BOOKED|BLOCKED)appointment_idversion

Materialised from rules for a rolling 3-week window. Booking is a conditional update on one row.

sessions (token mode)Postgres + Redis
session_idcalendar_iddatestart_timemax_tokensissued_tokenscurrent_tokendelay_minutes

Token issue = atomic increment with limit; live status in Redis for frequent reads.

appointmentsPostgres
appointment_idpatient_idcalendar_idslot_id or (session_id, token_no)typestatuschannel (online|desk|phone)payment_ididempotency_key

Indexed by patient and by calendar-date for the clinic's day view.

search indexElasticsearch
doctor_idclinics (geo_point)specialtieslanguagesfeeratingnext_available_at

next_available_at updated by events when slots change, so 'available today' filters work.

medical recordsS3 (encrypted) + Postgres metadata
record_idappointment_idpatient_idtypes3_keyaccess_policy

Encrypted per object with KMS; access logged.

5 Architecture

CLIENTSEDGESERVICESASYNCDATAEXTERNALsync, desk bookingsclaim slottoken, delayrules changedslotsCDCnext availablepaymentPatient app / webClinic desk softwareAPI gatewaySchedule serviceDoctor search svcAppointment serviceClinic sync serviceSlot generatorKafka (appt events)Reminder schedulerPostgres (slots,appts)ElasticsearchRedis (live tokens)SMS / WhatsApp / pay
ClientEdge / gatewayService / workerQueue / streamCacheDatabase / storageAI / modelThird partyrequestasync (event / queue)

Hover a box to highlight its connections.

6 Request flows

Book a slot online

  1. 1Patient searches 'dermatologist near Koramangala, today'; Elasticsearch filters by geo, specialty and next_available_at ≤ today end, ranks by distance, rating and relevance.
  2. 2Patient opens a doctor and picks the 6:30 pm slot; the app sends POST /appointments with an Idempotency-Key.
  3. 3Appointment service runs: UPDATE slots SET status='BOOKED', appointment_id=? WHERE slot_id=? AND status='OPEN'; one row changed means success, else 'slot just taken' with alternatives.
  4. 4It inserts the appointment in the same transaction plus an outbox event; for video consults it creates a payment intent and confirms after payment.
  5. 5Events update the search index (next available), notify the clinic software, and schedule reminders.

Walk-in at the clinic during an internet outage

  1. 1Front desk software keeps a local copy of today's calendar and issues a booking locally, marked as pending sync.
  2. 2When the internet returns, it pushes pending changes with their local IDs; the sync service applies them as conditional updates.
  3. 3If an online patient booked the same slot meanwhile, the conflict is reported to the desk, which moves one patient to the next free slot or adds an overbook entry; the patient is notified.

Doctor running late

  1. 1Clinic staff mark 'doctor delayed 40 minutes' or advance the current token in the desk app.
  2. 2The appointment service updates live session status in Redis and emits an event.
  3. 3Patients with upcoming appointments that session receive a WhatsApp message with the new expected time; the app's live screen shows the current token.

7 Deep dives

From schedule rules to bookable slots

Doctors think in rules: 'Mon-Sat 10:00-13:00 at Clinic A, 15-minute slots; Tue/Thu 18:00-20:00 at Clinic B; on leave 20-25 Dec'. Store those rules as the source of truth and materialise slots for a rolling window (say 21 days) with a daily job and on every rule change. Materialised slots make booking simple: a slot is a row that can be claimed with one conditional update, and availability is a range query. Rule edits are the tricky part. When a doctor shortens a session that already has bookings, the generator must not delete booked slots; it marks them as conflicts and creates a task for the clinic to reschedule those patients, who are notified. Generate in the clinic's timezone (India has one, but the platform may expand), and make the generator idempotent by deriving slot IDs from (calendar_id, start_at), so re-running never creates duplicates. Leaves become BLOCKED slots, not deleted ones, keeping history clean. For doctors who take unlimited patients per session, skip slots and use the token model instead.

One calendar, many booking channels

The platform is not the only way patients book: the clinic receptionist takes phone calls and walk-ins, and some clinics use their own software. If these channels keep separate calendars, double booking is guaranteed. The design must make one inventory the source of truth per doctor-clinic calendar, which is the platform's slot table, and give every channel access to it. The clinic desk app (the platform's own practice software, as Practo does with its clinic product) books through the same API. For clinics using third-party software, a sync integration pushes and pulls bookings with cursors and idempotency keys. Clinics lose internet often, so the desk software works offline from a local copy and syncs later; conflicts are then possible and must be resolved explicitly, not silently overwritten: online bookings win by default and the desk sees the conflict. To reduce conflicts, doctors can reserve a share of slots for walk-ins and phone bookings, exposing only part of the session online.

Token queues and live delays

Many Indian clinics do not run exact appointment times: they run sessions where patients get token numbers and the doctor sees them in order. Supporting only fixed slots misses how most of the market works. In token mode, a session has max_tokens and issued_tokens; booking issues the next token with an atomic increment bounded by the limit (a conditional UPDATE issued = issued + 1 WHERE issued < max, returning the new value). The desk app advances current_token as patients go in. Live status is read far more often than it is written (patients refreshing 'how many before me'), so keep it in Redis and push changes via SSE or poll every 30-60 s. Estimate waiting time from the doctor's moving average time per patient in this session and recent days. Notify patients when they are ~3 tokens away, which lets them wait at home instead of a crowded waiting room. Late arrivals and emergencies break strict order; let the desk re-order, and show patients an estimate, not a promise.

Health data privacy and access control

Appointments reveal sensitive facts: a booking with a psychiatrist or an oncologist is health data even without notes. Treat the whole system accordingly. Encrypt data at rest and in transit, encrypt documents per object with KMS keys, and restrict staff access through roles: a clinic receptionist sees today's appointments for their clinic, not patients' histories; doctors see records only for patients who booked with them or consented to share. Log every read of medical records in an append-only audit log and review unusual access. Keep minimum data in notifications: 'Your appointment at 6:30 pm tomorrow' without the specialty. Under India's DPDP Act you need clear consent for each purpose, deletion on request (subject to medical record retention rules), and breach notification. If you integrate with the national health stack (ABDM, with ABHA health IDs), records are shared only through consent artefacts. Analytics and ranking must use de-identified data.

8 Trade-offs

Materialised slots vs computing availability on the fly

Computing free time from rules minus bookings at read time saves storage but makes booking harder (you must lock a time range, not a row) and search slower. Materialised slots cost ~150M small rows and a generator job, but give simple atomic booking and fast range reads. Choose materialised slots; use time-range constraints only where slot lengths vary.

Postgres for slots vs a NoSQL store

Booking needs conditional updates, transactions with the appointment row, and range queries by date. Postgres partitioned by calendar handles ~30 bookings/s trivially. A NoSQL store adds nothing here; the scale is moderate.

Allowing overbooking

Some doctors overbook on purpose because of no-shows (often 10-20%). Support it explicitly with a per-session overbook limit, rather than by bypassing constraints, so the system still knows what is promised.

9 Bottlenecks

Search freshness for 'available today'

If next_available_at is stale, patients click doctors with no free slots. Update it from booking events within seconds, and verify slots live when the profile opens. At 10x, batch index updates per doctor every few seconds.

Morning booking rush for popular doctors

Popular doctors' slots open at a fixed time and fill in minutes. Contention is per slot, so database row locks handle it; rate limit per patient and stop showing a slot as available as soon as it is claimed to reduce failed attempts.

10 Failure handling

Reminder service down

Reminders are scheduled jobs in a durable store; when the service recovers it sends overdue reminders only if the appointment is still in the future and not cancelled. Missing a reminder increases no-shows but breaks nothing.

Clinic offline for hours

Online booking continues against the platform calendar; the desk works locally. On reconnect, sync resolves conflicts explicitly. Optionally, stop online bookings for today's remaining slots when a clinic is offline for long, to reduce conflicts.

Payment succeeds but booking fails

For prepaid video consults, payment confirmation and slot claim are tied by the appointment's idempotency key. If the slot was lost, refund automatically or offer the next slot with the same doctor.

11 What impresses

  • Brings up walk-ins, phone bookings and token queues, which is how many Indian clinics actually run.
  • Separates schedule rules from materialised slots and handles rule edits that hit booked slots.
  • Designs clinic software for offline operation with explicit conflict handling.
  • Keeps next-available time in the search index fresh via events.
  • Treats even appointment metadata as sensitive health data.
  • Supports deliberate overbooking with limits instead of bypassing constraints.

12 Mistakes

  • Assuming the platform is the only booking channel.
  • Computing availability from rules on every search request.
  • Deleting booked slots when a doctor changes the schedule.
  • No reminders or delay notifications, leading to no-shows and crowded waiting rooms.
  • Putting the specialty or diagnosis in SMS reminders.
  • Over-engineering with distributed locks for a low-QPS booking path.

13 Follow-ups

Q1How do you support a doctor who works at three clinics with different slot lengths?
Q2How do you predict and reduce no-shows?
Q3How would you rank doctors in search without unfair bias toward paid listings?
Q4What changes when you add video consultations with prescriptions?
Q5How do you handle a doctor cancelling an entire day?
Q6How would you integrate with ABDM to share records with consent?

Saved on this device. Create a free account to keep it on every device.

Practise this with Sam

A real mock interview, out loud, with an honest scorecard. Free to start.

Start free