Katkat

Design a Concurrent Appointment Booking System

Garner HealthSoftware Engineer · Technical Screen

Last updated

Design a concurrent healthcare appointment scheduling system that prevents double booking, supports fast availability searches, and ensures reliable notifications and state auditability.

Scenario

A healthcare navigation platform allows patients to search for doctor availability across specialties and locations, book appointments, and manage cancellations or reschedules. During peak hours or when high-demand specialists open their calendars, multiple users frequently race to book the exact same slot. The platform must guarantee that no slot is double-booked, even under network retries and high concurrent load, while keeping availability searches fast and appointment state transitions fully auditable.

Requirements

Functional Requirements

  1. Availability Search: Patients can search available appointment slots by provider, specialty, geographic region, and date range.
  2. Booking & Hold: Patients can secure an appointment slot with immediate confirmation. Network retries must be idempotent.
  3. Cancellation & Rescheduling: Patients or providers can cancel an appointment or move it to a different open slot.
  4. Asynchronous Notifications: Trigger confirmation, reminder, and cancellation notifications (email/SMS) without adding latency to the booking transaction.
  5. Audit Trail: Every state transition (AVAILABLE, HELD, BOOKED, CANCELLED) must be permanently recorded with timestamps and actor metadata.

Non-Functional Requirements

  • Zero Double-Booking: Strict consistency on slot reservation. Two concurrent requests for the same slot must never both succeed.
  • Low Latency Search: P99 read latency < 150 ms for availability searches.
  • Idempotency: Clients passing the same idempotency key must receive identical responses without creating multiple bookings.
  • Scale:
    • 50,000 active healthcare providers.
    • 5,000,000 active patients.
    • Read/Write ratio: ~50:1 (Search: ~1,500 QPS peak; Booking/Modifications: ~50 QPS peak).

What to Cover

  1. API Design: Define the core endpoints for search, booking, cancellation, and rescheduling (including headers and payload structures).
  2. Data Model & Concurrency Control: Detail the database schema, slot representation (pre-materialized vs. dynamic), and your strategy for preventing race conditions (e.g., optimistic locking, pessimistic locking, conditional updates, or distributed locks).
  3. System Architecture: Diagram or describe the services, datastores, caching layers, and message buses.
  4. Reliable Asynchronous Processing: Detail how notifications and audit records are generated reliably following a booking commit (e.g., Transactional Outbox pattern).
  5. Trade-offs & Edge Cases: Discuss edge cases like handling expired holds, partial failures during rescheduling, and search cache invalidation.

Hints

Hint 1

Consider whether slots should be pre-materialized as distinct database rows with status flags, or computed dynamically against busy intervals.

Hint 2

Evaluate using database-level unique constraints or conditional atomic updates (`UPDATE slots SET status = 'BOOKED' WHERE id = ? AND status = 'AVAILABLE'`) rather than distributed locks to prevent double-booking with minimal overhead.

Hint 3

Use the Transactional Outbox pattern to atomically commit appointment state changes and queue notifications, avoiding distributed two-phase commits.

Follow-up questions

  • How would you implement a 10-minute temporary slot hold (e.g., while a patient fills out insurance info) that automatically expires without requiring a polling cron job?
  • If availability search traffic spikes to 50,000 QPS, how would you cache slot availability in Redis while minimizing the frequency of users seeing stale, already-booked slots?
  • How would you ensure atomicity during a reschedule operation where the patient cancels slot A and books slot B, especially if reserving slot B fails?