calcom/cal.com
Scheduling and slots
Active contributors: Pedro, Hariom, Romit
Purpose
Slot computation is the math at the heart of Cal.diy: given an event type, an organizer's schedules, the busy times pulled from federated calendars, and any reservation locks held during in-progress bookings, return the candidate booking times that should be shown to the booker.
Where it lives
| Concern | Code |
|---|---|
| Slot generation | packages/features/slots |
| Schedule CRUD + queries | packages/features/schedules |
| Availability helpers | packages/lib/availability.ts, packages/features/availability |
| Out-of-bounds checks | packages/lib/isOutOfBounds.tsx |
| Date-override / interval limits | packages/lib/intervalLimits/, packages/lib/intervalTree.ts |
| Slot reservation (selected slots) | packages/features/selectedSlots |
| Travel schedule | packages/features/travelSchedule |
| Holidays | packages/features/holidays |
| OOO (out of office) | packages/features/ooo |
| Troubleshooter UI | packages/features/troubleshooter + apps/web/modules/troubleshooter |
Key abstractions
SchedulePrisma model — a recurring availability template (e.g., "Mon–Fri 9–5"). Has manyAvailabilityrows.AvailabilityPrisma model —(start, end, days[])row attached either to a Schedule or directly to an EventType.SelectedSlotPrisma model — pending in-progress booking; holds a slot for a few minutes so concurrent bookers don't both book it.getSchedule— the procedure exposed to the public booking page. Combines event-type rules + schedules + busy times + selected-slot locks → time slots.isOutOfBounds(packages/lib/isOutOfBounds.tsx) — applies the event type'sPeriodType(UNLIMITED / ROLLING / ROLLING_WINDOW / RANGE) to filter slots.IntervalTree(packages/lib/intervalTree.ts) — efficient interval arithmetic used to subtract busy intervals from availability.
How it works
graph TD
Request[Booker hits /[user]/[eventType]] --> GetSchedule[getSchedule procedure]
GetSchedule --> EventType[features/eventtypes loads EventType]
GetSchedule --> Schedules[features/schedules loads Schedule + Availability]
GetSchedule --> Busy[features/busyTimes via SelectedCalendar adapters]
GetSchedule --> Locks[features/selectedSlots active locks]
GetSchedule --> Holidays[features/holidays + features/ooo]
GetSchedule --> Travel[features/travelSchedule]
GetSchedule --> Slots[features/slots compute candidate slots]
Slots --> OutOfBounds[isOutOfBounds period rules]
Slots --> ReturnSlots[return Slot[]]Round-robin assignment
For round-robin event types, assignment happens after a slot is picked:
getLuckyUser(packages/features/bookings/lib/getLuckyUser/) chooses among hosts based onHost.priority,Host.weight, recent assignment history, and current availability.- The
Hostjoin table holds the configuration;HostGroupallows logical grouping (e.g., language-specific groups).
Slot reservation
When a booker opens a slot, the front end posts a "reserve" request that creates a row in SelectedSlot for ~5 minutes. Subsequent slot queries for the same time window honor that lock so two bookers can't simultaneously confirm the same slot. The lock is released on submit (booking is created and the lock is no longer needed) or expiry.
Schedules and overrides
The schedule editor under apps/web/modules/availability/ and packages/features/schedules/ lets a user define multiple schedules (e.g., "Work hours", "Weekend coaching") and pick one per event type. Date overrides handle holidays, conferences, and "I'm unavailable on this specific date".
Holidays and OOO
packages/features/holidays lets organizers import a holiday calendar. packages/features/ooo adds vacation entries that block availability across all event types for a date range.
Travel schedule
packages/features/travelSchedule adjusts availability for traveling organizers — temporarily set a different time zone for a window without rewriting the underlying schedule.
Troubleshooter
packages/features/troubleshooter + apps/web/modules/troubleshooter produce a UI that visualizes how slots are computed for a specific event type and date. The fastest way to debug "I have no slots" complaints. See debugging for the runbook.
Integration points
- Bookings consume slots indirectly (the booker has already picked one before submitting).
- Calendars feed busy times via
packages/features/busyTimes. - API v2 exposes a slots module (
apps/api/v2/src/modules/slots) for SDK consumers.
Entry points for modification
- Add a new availability constraint: extend
packages/features/slotsandpackages/lib/availability.ts. Add unit tests underpackages/features/slots. Verify with the troubleshooter UI. - Tweak round-robin selection: edit
packages/features/bookings/lib/getLuckyUser. - New schedule UI feature: schedule editor lives in
apps/web/modules/availability/+packages/features/schedules/components/.
Related pages
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.