The room that was booked twice
Monday, just before nine. Two teams stand in front of the same meeting room, each holding a calendar confirmation. One team booked through the spreadsheet maintained by the front desk, the other through an invitation in their email program. Both routes lead to a "booking", but neither knows about the other. The scene is an everyday one, and it is a good example of why a booking system is more than a calendar with a form.
Suppose we are talking about a company with around forty employees. It has three meeting rooms, a measuring device that two departments need, a van and two specialists who visit customers. Each of these resources has its own habits. The measuring device sits in a colleague's calendar, the van is managed on a wall board, and the specialists are coordinated by phone.
This picture is typical of businesses that have grown organically. It works as long as one person has the overview. If that person is absent or the company grows, reliability collapses and follow-up questions pile up. Anyone who types "commission a booking system" into a search engine has usually reached exactly this point: the existing solution is not broken, but nobody trusts it any more.
A booking system is only as good as the sentence "This room is free". If that sentence is not true, no interface will help.
Why booking is harder than it looks
A single booking is trivial: resource, start, end, person. It gets difficult as soon as several people book at the same time, rules apply and time is no longer unambiguous. Three kinds of failure appear in almost every starting situation, and none of them can be fixed with better discipline.
The first is the double booking caused by concurrency. Two people see the same free slot, click within seconds of each other, and both requests go through because the check "is it free?" and the saving are two separate steps. The second is the double booking caused by dependencies: whoever books the van also needs a driver, and whoever books a room with a projector also blocks that device. The third is the vagueness of time itself, from daylight saving time to the time zone of a customer in another country.
On top of that come rules that are written down nowhere. May a booking still be cancelled on the same day? Are there buffer times for tidying up? May interns book equipment, and who approves exceptions? As long as these rules exist only in people's heads, no system can enforce them. The first part of the work is therefore not programming but writing things down.
- Concurrency: two requests for the same period are processed in parallel and both are confirmed.
- Dependencies: a booking needs several resources at once, and only one of them is free.
- Time: daylight saving time, time zones and recurring appointments produce unexpected results on individual days.
- Rules: deadlines, buffers and permissions are agreed verbally and applied inconsistently.
Rules first, then the form
Before any interface is built, it helps to condense the inventory into two questions: what is a bookable unit, and when does it count as occupied? That sounds trivial and is not. A room is one unit. A measuring device with its accessories might be one unit, or two. A person is bookable, but only within their working hours, and their vacation behaves like an occupation in functional terms.
From this clarification a simple model emerges. Every resource has a type, a capacity and opening hours. A booking occupies a time interval on one or more resources. Blocked times, maintenance and absences are also occupations, just with a different reason. Treating them alike simplifies the check enormously: the system only asks whether two intervals on the same resource overlap, regardless of why they exist.
The interesting decisions are made in this phase. Should there be buffer times, and do they belong to the booking or to the resource? How far in advance may a booking be made? Are there quotas per department? Every answer either costs programming effort later or saves it. That is why the rules belong on a single page that the business side and the technical side read together before the first line of code is written.
Figure · Where the effort of clarification lies in a booking project
- Conflict rules and concurrencyrelative priority
- Cancellation and deadlinesrelative priority
- Time zones, series, daylight saving timerelative priority
- Roles and approvalsrelative priority
- Analyses and reportsrelative priority
Buy or build: weighing the options and the path of a booking
Not every company should commission a booking system. For simple cases, such as meeting rooms without special rules, calendar tools and ready-made room booking are often enough. They are set up quickly, they are maintained and they cost no development time. Anyone who only wants to know whether room two is free at ten o'clock should start there. Standard software reaches its limits when resources depend on each other, when prices or approvals depend on rules, or when data needs to flow into existing systems. Then configuring and gluing things together begins, and the cost shifts from development to maintaining exceptions.
The third way is a custom build that deliberately starts small. We would build the core logic first, meaning resources, intervals, conflict checks and cancellation rules, and keep everything else simple at first. The interface can be plain in the beginning. In our experience, you only learn in operation which special requests are really needed and which merely sounded mandatory in conversation.
A rule of thumb: if your rules fit into one sentence, buy. If they fill a page and often deviate from the standard, a custom build pays off. And if you are unsure, do not build; first test a standard product with your real rules. The result quickly shows where the limit lies.
In daily use, users encounter a simple sequence: choose a resource, set a period, confirm. Behind it lies a chain of checks that should run in a fixed order. First permission, then the rules for the period, then availability, finally saving. What matters is that the last two steps are inseparably linked, so that no gap opens between the check and the entry.
For the interface, one principle applies: show only what is bookable, but never rely on it. Displaying free times is a convenience feature and may be out of date. The binding check happens when saving and has to deliver an understandable refusal, such as "The room was just booked by someone else, two alternatives are free". That absorbs the frustration a bare error message causes.
For bookings with several resources, such as a room plus equipment and a supervisor, the rule is "all or nothing". Either all parts are free and are occupied together, or the booking fails completely. Half bookings, where the room is reserved and the device is missing, are the source of the most annoying follow-up questions and can only be avoided with a shared transaction.
Figure · The path of a booking from click to confirmation
Request
Resource, period, person
Rule check
Permission, deadlines, opening hours, buffers
Reserve
Conflict check and entry in one transaction
Confirm
Email, calendar entry, approval if needed
Preventing conflicts in the database instead of hoping in the code
The most robust way to prevent double bookings is to make them impossible in the database system. A check in the application code alone is vulnerable: two parallel requests both read "free" and both write. There are three tools against this. First, locks, where the resource is reserved exclusively during the check. Second, higher transaction isolation levels, which reject colliding writes. Third, rules in the database itself.
With PostgreSQL there is an elegant variant: exclusion constraints on time ranges. You define that no two intervals on the same resource may overlap, and the database rejects every violation, no matter how many applications write to it. The principle can also be replicated in other systems, for example through a lock per resource and day. We would use the database as the final authority and the code only as a friendly first stage.
A small detail with a big effect is the definition of intervals. Time ranges are understood as half-open: the start counts, the end does not. This way a booking from 10 to 11 can be followed immediately by one from 11 to 12 without the system reporting a conflict. Anyone who does not define this experiences edge errors that appear only by chance and stay undiscovered for a long time.
Finally, a note on scaling: for businesses of this size the load is low, and the database-side solution is entirely sufficient. More complex constructions with queues or distributed locks only pay off at very high simultaneous volume, such as ticket sales. Introducing them too early swaps a solvable problem for one that is hard to operate.
Figure · Protection against double bookings on three levels
Interface
Shows free times, may be out of date, offers alternatives.
Application logic
Checks permissions, deadlines and rules, translates errors into understandable messages.
Database
Bindingly rejects overlapping intervals on the same resource.
Time zones, daylight saving time and recurring appointments: where calendars get tricky
Time is the area where seemingly clean systems silently deliver wrong results. The basic rule: points in time are stored unambiguously, for example as UTC, and converted to the resource's time zone for display. In addition, the system remembers the time zone as a name such as "Europe/Berlin", not as a fixed offset, because the offset changes with daylight saving time.
Daylight saving time creates two special cases. In spring the clock jumps from 2 to 3 a.m., and the hour in between does not exist. A booking at 2:30 a.m. is therefore invalid, and the system must reject or shift it. In autumn the hour between 2 and 3 a.m. occurs twice, and a time like 2:30 a.m. is ambiguous. In practice this rarely affects offices, but it does affect shift operations, maintenance windows and night-time equipment use.
Recurring appointments make this worse. A weekly booking "Mondays at 9 a.m." should still take place at 9 a.m. local time after the daylight saving change, not at 8 or 10. Series are therefore stored as a rule in local time and only resolved into concrete appointments when needed. Exceptions, such as a single rescheduled appointment, are separate entries that remain linked to the series.
If you work with customers or sites in other time zones, the system shows each person the time in their local time, but records the appointment itself in one time zone, namely that of the place where it takes place. An appointment in the Berlin meeting room is a Berlin appointment, even if someone in Lisbon books it.
- Store points in time as UTC, carry the time zone along as a name, never as a fixed offset.
- Store recurring appointments as a rule in local time and mark individual appointments as exceptions.
- Specifically test non-existent and duplicated times at the daylight saving changeover.
Cancellation, roles and calendars: the rules in daily use
Cancellation rules are a conflict between reliability and flexibility. Allowing rooms to be returned generously creates gaps that nobody fills any more. Setting strict deadlines creates phantom bookings that nobody releases. A proven middle way: free cancellation up to a deadline, afterwards release with a note and a documented reason. Whether fees apply is a business decision, and the system merely implements it.
A second relief comes from reminders and automatic releases. If a booking is not confirmed by a certain time or the room is not entered, the system can release it after a warning. That sounds harsh and in practice resolves many disputes, because it applies equally to everyone. What matters is that the rules are visible to all teams before they take effect.
Roles keep the set of rules readable. A simple model has bookers, people responsible for each resource, and administrators. Bookers reserve and cancel their own appointments. Responsible persons approve exceptions, such as longer occupations, and block times for maintenance. Administrators maintain resources and rules. Every change is logged with person and time, so that it is clear who changed what and when.
Calendar integration is where acceptance is created, because most people live in their calendar. Two routes are common. A simple subscription feed in iCalendar format brings bookings into Outlook, Apple Calendar or Google Calendar, but only in one direction. True synchronization via the interfaces of Google or Microsoft is possible, but it means access rights, error handling and maintenance. We would start with the feed and add two-way synchronization only where it is needed.
The best cancellation rule is the one everyone knows before booking and that the system applies without exceptions.
Figure · Resource management before and after the system
- Bookings live in a spreadsheet, emails and personal calendars.
- Who may approve what is decided case by case.
- Cancellations are reported by phone and entered late.
- Absences and maintenance are kept separate from bookings.
- Utilization is estimated, not analyzed.
What realistically improves and how you will notice
A booking system solves a clearly defined problem: it makes the statement "free" reliable and the rules consistent. That removes follow-up questions, corrections and arguments over occupations. How large the gain is depends on how much friction exists today. In a business with two rooms and little demand the effect stays small, and a simple solution would have been the more sensible choice.
The benefit can be measured with a few figures that you can already record beforehand. How often were there double bookings or complaints in a month? How much time does the secretariat spend on coordination and corrections? What share of booked but unused time is there, meaning bookings that nobody showed up for? If you note these values before the start, you can compare after three to six months instead of relying on impressions.
The analyses themselves are a side benefit. Utilization per resource, peak times, cancellation rate and share of short-notice changes show whether three rooms are enough or whether the measuring device becomes a bottleneck. These figures only come into existence through the system and allow decisions about purchases. They are only as reliable as the discipline with which bookings are made, which is why release rules and prompts play a big role in daily use.
What cannot be promised is how quickly employees get used to it. New systems rarely fail because of the technology, but because the old way remains easier. That is why it makes sense to switch off the old routes consistently rather than letting them run in parallel. If the spreadsheet remains allowed, the double booking remains too.
Lessons from comparable projects
First: the database is the place of truth. Calendars, emails and displays are copies, and the more clearly this is separated, the fewer synchronization errors arise. Second: rules belong in configuration, not in scattered conditions in the code. When deadlines, buffers and roles live in one place, they can be changed without risking functionality.
Third: edge cases should be collected before the start and captured as test cases. A booking across midnight, an appointment on the day of the clock change, a series with a deleted single appointment, a simultaneous request by two people. Anyone who checks these cases automatically notices regressions immediately and can keep developing the system without worry. These are the tests we would give up last.
Fourth: the first release should be small. A version with resources, booking, cancellation, roles and calendar feed covers most of the need. Prices, approval chains and two-way synchronization can be added once operation shows that they are necessary. That lowers the risk and shortens the time to first benefit.
- Keep resources, absences and maintenance on a shared timeline.
- Define time ranges as half-open and anchor the conflict check in the database.
- After launch, bindingly switch off the old booking routes, otherwise the double booking persists.
- Maintain rules as configuration and secure edge cases with automated tests.
Figure · A possible project timeline
- 1
Weeks 1 to 2
Clarify the rules, record resources, collect edge cases.
- 2
Weeks 3 to 6
Build core logic, database rules, booking, cancellation and roles.
- 3
Week 7
Calendar feed, notifications, first analysis.
- 4
Week 8
Pilot with one team, switch off the old routes there.
- 5
From week 9
Rollout to everyone, operation, analysis and adjustments.
Conclusion: write down the rules first, then build
A booking system is worthwhile when your resources depend on each other, your rules go beyond the standard and the reliability of occupancy matters in daily work. It is not mandatory for every business, and sometimes a well-maintained calendar is enough. The benefit does not come from technology, but from finally having a single, reliable answer to the question of what is free when.
The next step is small and costs nothing. Write your resources and the ten most important rules on one page: who may book, until when cancellation is possible, which times are blocked, what applies to exceptions. Often this sheet alone shows whether a standard product is enough or whether a custom build makes sense. We are happy to go through it with you and give a clear assessment.
To put the effort in context: after this clarification a first framework for scope and duration can be named, not before. Anyone who promises a fixed price in advance has not yet seen the edge cases. We name a range as soon as the rules are in place, and openly separate what belongs to the core from what can follow later.
One last note concerns operation. A booking system is not a project that disappears after handover: resources are added, rules change, calendar providers adapt their interfaces. So plan from the start who maintains the rules, who collects feedback and how backups and updates are handled. That costs little if clarified early, and a lot if it is noticed only after a room has been double-booked for the third time.
Frequently asked questions
When is it worth commissioning a booking system?
When standard software does not reflect your rules: resources depend on each other, approvals and deadlines differ by team, or data should flow into existing systems. For simple room bookings without special features, calendar tools are often enough. A test with a standard product and your real rules quickly shows where its limit lies.
How can double bookings be reliably prevented?
Most reliably in the database. A check in the application code alone is not enough, because two simultaneous requests can both read "free". Locks, suitable transaction isolation or exclusion constraints on time ranges ensure that intervals on the same resource cannot overlap, regardless of the route used to book.
How does a booking system handle time zones and daylight saving time?
Points in time are stored unambiguously, usually in UTC, and additionally given the name of the time zone. Recurring appointments are stored as a rule in local time so that "Mondays at 9 a.m." stays that way after the clock change. Non-existent and duplicated times on the changeover day have to be handled and tested specifically.
Can a booking system work with Outlook or Google Calendar?
Yes, in two ways. A calendar feed in iCalendar format shows bookings in common calendars, but read-only. Two-way synchronization via the providers' interfaces is possible, but requires access rights, error handling and ongoing maintenance. Often the feed is enough at first.
Which cancellation rules make sense?
That depends on the business. Free cancellation up to a deadline, followed by release with a note, is common. In addition, unconfirmed bookings can be released automatically after a warning. What matters is that the rules are visible before booking and apply equally to everyone. Fees are a business decision, not a technical one.
How long does development take and what does it cost?
A reliable figure is only possible after the rules have been clarified. A small core with resources, booking, cancellation, roles and calendar feed can be built in a few weeks. Scope, number of resources, special rules and interfaces determine the range. We recommend starting small and expanding after the pilot operation.