Walk-in queues vs slot booking — pick your poison
Indian clinics need walk-in queues. Western clinics need slot booking. They are not the same problem. Here's the model we built that makes both feel native in the same product.
If you build a clinic-management product and you only sell into one country, you can pick a queue model and stop thinking about it. If you sell into India and the West simultaneously — which we do — you discover that the basic primitive of "how does the next patient get seen" is wildly different across markets, and that the difference cascades into about a dozen other product decisions.
This post is about that. Why walk-in queues and slot bookings are different problems, what we got wrong trying to unify them too early, and the model we ended up with.
The two cultures
In a typical Indian primary-care clinic — and a fair chunk of secondary care — the dominant flow is:
- Patient walks in, takes a token.
- Patient sits, waits, gets called.
- Doctor sees them; the consult ends; the next token is called.
- Repeat for ~50 to 80 patients across an OPD shift.
In a typical European or US primary-care clinic:
- Patient calls (or books online) for a slot — say, 10:30am Tuesday.
- Patient arrives at 10:25, checks in.
- Doctor sees them at 10:30 (give or take 5 minutes).
- Repeat for ~12 to 20 patients across a clinical session.
These are not regional preferences in some superficial way. They're shaped by demand density, payer model, transit infrastructure, and patient expectation. An Indian doctor in a tier-2 town who sees 70 patients a day cannot run on slots — the booking calendar would explode and the no-show penalty would be unbearable. A Dublin GP who sees 16 patients a day cannot run on walk-ins — the patients would just be standing in the corridor for an hour and a half.
What we tried first (and abandoned)
The natural first instinct is to abstract: "a queue is just an ordered list, and a slot booking is just a queue with timestamps." So our v1 had one model — the appointment — with optional time fields. Walk-ins were appointments with start_time = NULL. Bookings were appointments with a real start_time.
This worked, sort of, until it didn't. The product failed in three ways:
Logic became case-heavy. Every screen that touched the queue had to fork: "if start_time is null, sort by check-in time; else sort by start_time" — and the rules for "what if a walk-in arrives at 10:25 and there's a 10:30 booking" had to be repeated in five places. The code rotted.
The UX got muddy. A walk-in clinic doesn't want to see slot grids in their FD app — slots are noise. A slot-booking clinic doesn't want to see token numbers — tokens are noise. Trying to design one screen that did both gracefully meant doing both badly.
Reporting was a mess. "Average wait time" means something different in walk-in (time from check-in to consult) vs slot booking (time past slot to consult). Putting both into one number was meaningless.
What we ended up with
We split the model. The clinic now picks a booking mode at setup time:
- Walk-in mode — primary flow is tokens. Bookings exist but are a secondary path.
- Slot mode — primary flow is slots. Walk-ins exist but are a secondary path.
- Hybrid mode — both first-class. The flow merges them at runtime.
The mode shapes the UI, the analytics, the reminders, and the patient app. Walk-in clinics see the queue as the primary surface; slot clinics see the calendar; hybrid clinics see a merged timeline with clear "Booked" and "Walk-in" badges.
Underneath, the data model is unified — every visit has a kind field — but the rules for ordering, conflict resolution, and timing are encapsulated in a per-mode strategy class. That sounds enterprise-y but it's not; it's three classes, ~200 lines each.
The hybrid case
The interesting case is hybrid. Many of our pilot clinics — especially urban Indian clinics with a mix of repeat patients (who book) and walk-ins (who arrive) — wanted both. The rules we landed on:
- Bookings hold their slot. Your 10:30 patient is seen at 10:30, not at 10:42 because two walk-ins arrived in between.
- Walk-ins fill the gaps. If the 10:30 booking is running 8 minutes early, the 10:25-arrived walk-in slips in for an 8-minute consult.
- Walk-ins displace late bookings. If the 10:30 booking is 15 minutes late and the next walk-in has been waiting 35 minutes, the walk-in goes first. The booking gets a soft "you're past your slot, you're now in queue" message in the patient app.
- En-route is a special status. If the booked patient's phone says they're 4 minutes away from the clinic, the queue holds the slot for them even if they're 2 minutes past the slot time.
None of this is rocket science. It's just the kind of rule-set that has to be made explicit rather than left to the FD's intuition, because once you have multiple FDs across multiple shifts, intuition diverges and patients get visibly inconsistent treatment.
The rules above sound bureaucratic on paper. In the clinic, they feel obvious: "of course the booked patient is seen at their slot; of course we don't make walk-ins wait forever; of course if you're nearby we'll wait for you." The work was making the software match the obvious behaviour, instead of imposing a different one.
What this enabled downstream
Once the booking mode was explicit, a bunch of other product decisions became cleaner.
Patient app. A walk-in patient sees "you're #4 in queue, ~28 min wait" with a real-time updating ETA. A booked patient sees "Your slot is 10:30am; please arrive by 10:25." Hybrid patients see whichever one matches their visit. One screen template, two data sources.
FD home. Walk-in mode FD home leads with the queue. Slot mode FD home leads with the calendar. Hybrid mode shows a merged timeline. Same code, different default views.
Analytics. Wait time is computed per mode and reported separately. Walk-in clinics see "avg wait from check-in: 22 min". Slot clinics see "avg delay past slot: 4 min". Hybrid clinics see both. Comparing across modes is meaningless and the dashboards stop trying to.
No-show handling. A walk-in can't no-show — they either showed up or didn't, and we know from check-in. A slot booking can no-show, and the rule is clean: 2 hours past slot with no check-in = automatically marked no-show, slot freed.
What we'd do differently
If we were starting again, we'd skip the unification phase entirely and start with the per-mode model. The "elegance" of one unified model was a mirage; in practice the two flows are different enough that imposing a single shape on them costs more than it saves.
The general lesson — and we keep relearning it — is that premature abstraction is more expensive than well-named duplication. Two well-encapsulated 200-line strategy classes are easier to reason about than one 700-line case-studded one.
One more wrinkle: regional variation within India
Even within India, the picture is more textured than "everyone walks in." Specialist clinics — dermatologists, fertility clinics, niche cardiologists — increasingly run on slots, even in tier-2 cities. The pattern correlates roughly with consult length: anything over ~15 minutes per patient drifts toward slots, anything under stays walk-in. Our software doesn't care; the clinic picks a mode at setup.
We also see partial hybrid: morning OPD is walk-in, afternoon procedures are slotted. We support this with shift-level mode overrides, which is one of those features that nobody asked for until they did and then everyone wanted it.
Why this matters beyond MediSero+
If you're building any product that crosses geographic markets — not just clinical software — there's a high chance the basic flow primitive in your domain is wired differently in different places. The instinct to unify is strong (it feels like good engineering) but it's often wrong. The cleaner answer is to model the explicit difference and let each market's flow feel native.
We're testing this principle in two more places — billing flows (cash-first vs card-first vs insurance-first) and consent flows (explicit-each-time vs umbrella-at-onboarding). Stay tuned.
If you want to see the queue in action, the doctor app is at /for-doctors and the FD product is at /for-front-desk. If you've thought about this problem differently, write to hello@medisero.com.