Coming Soon to AppExchange - 2026

Preventing Double-Booking in Salesforce

Validation rules cannot see other records. That single limitation is why most Salesforce booking systems discover their conflicts a day late.

Published 21 July 2026 · MultiDatePick

Double-booking is not a data quality problem, it is a timing problem. By the time anything in standard Salesforce can tell you the room is taken, the user has already chosen it, filled in the rest of the form, and moved on.

Why the obvious tools do not work

Tool What it can do Why it is not enough
Validation rule Check fields on the record being saved Cannot query other records at all
Duplicate rule Match on field equality Overlap is not equality: 9-10 and 9:30-10:30 clash but do not match
Record-triggered flow Query and block on save Fires after the user committed; bulk-unsafe if written naively
Apex trigger Full control, correct overlap logic Still rejects at save, and now you own the code

Notice they all share the same shape: reject the user after the choice. Even the correct Apex solution produces "that slot is taken, please try again," which is a worse experience than never offering the slot.

Overlap is not equality

Worth stating plainly, because duplicate rules tempt people. Two bookings conflict when one starts before the other ends and ends after the other starts. A booking from 9:00 to 10:00 and one from 9:30 to 10:30 overlap by half an hour while sharing no identical field values. Any approach based on matching values will miss it every time.

Conflict and capacity are different problems

They get treated as one thing and they are not.

  • A conflict is two things competing for a resource that holds one. A room, an interviewer, a vehicle.
  • Capacity is a resource that holds several, where the question is not "is it taken" but "how many are left." A class with twenty seats, a shift needing four nurses, a desk zone with sixty spaces.

Treating a capacity resource as a conflict resource means you can never book the second person. Treating a conflict resource as capacity-of-one technically works but loses the counts you probably want to report on.

Three sensible behaviors, not one

"Block it" is not always right. When somebody selects twelve dates and two of them clash, rejecting the whole submission is hostile. Useful systems offer a choice:

  • Block: refuse the save and report the clash. Right when every date matters.
  • Skip: save the ten that are free, report the two that were not. Usually the humane default for bulk selection.
  • Allow: permit the overlap deliberately. Some businesses overbook on purpose.
Salesforce booking calendar showing capacity badges and conflict detection preventing double-booking on each slot
Live capacity counts on each slot, so the conflict is visible before anyone clicks.

The real fix is earlier, not stricter

Every mechanism above operates at save time. The fix is to move the check to selection time: query what already exists when the calendar loads, draw it onto the grid, and never offer a slot that is gone. Save-time validation still runs as a backstop for the genuine race condition where two people are looking at the same free slot, but it stops being the primary defense.

MultiDatePick reads existing records when the calendar renders, shows taken slots as taken, counts capacity with a live X/Y badge, and runs conflict detection again on save with block, skip, or allow behavior. Conflicts come back to Flow as bookingConflictDates alongside bookingSuccessCount, so a flow can tell the user exactly what happened.