Designing a Booking Calendar That Doesn't Break Under Load
One of the most technically demanding features I built at Holiday Caravans Direct (HCD) was the booking calendar. It sounds simple on the...
One of the most technically demanding features I built at Holiday Caravans Direct (HCD) was the booking calendar. It sounds simple on the surface — just show availability and pricing for holiday rentals — but in practice, it became a complex balancing act between performance, flexibility, and user experience.
From day one, I knew the calendar would be a bottleneck. It had to handle thousands of property listings, each with owner-defined pricing periods, exceptions, and manual overrides. Add to that both online and offline bookings — with a need to avoid conflicts — and it was clear a traditional approach wouldn't cut it.
A Two-Step Strategy
To optimise performance and prevent client devices from choking on data, I designed the calendar as a two-step process:
Step 1: Fetch Availability
This call returned a lightweight dataset: booked/unbooked ranges, with minimal detail.
It was highly cacheable and allowed the calendar to render quickly.
Step 2: Fetch Pricing for Selected Dates
Only when a user interacted with the calendar did we request pricing.
This kept API responses small and reduced pressure on the database.
It meant a bit more complexity in the front-end logic, but the performance benefits were undeniable. The calendar felt fast, even on mobile connections, and users weren't overwhelmed with data they didn't need yet.
Vue.js to the Rescue
I built the entire calendar component in Vue.js. Its reactive design made it easy to implement dynamic rendering, tooltips, date-range selection, and conditional styling — all essential for a usable booking experience.
I also took advantage of Vue's lazy-loading capabilities to only load logic-heavy components (like the pricing breakdown or quote calculator) when they were needed.
Balancing Business Rules
Performance aside, the system had to remain flexible for business logic:
Owners could set custom pricing windows
Manual overrides needed to reflect instantly
Offline bookings had to be blocked out but not quoted
This required a careful separation of pricing logic from availability logic, allowing each to evolve independently. And it made it possible to layer in new features — like discounts, deposits, or multi-week quotes — without ripping the whole thing apart.
Lessons Learned
This project taught me that performance isn't just a server concern — it's a user experience concern. By deferring complexity until it was needed, and designing API boundaries around actual user behaviour, I created something that felt lightweight but remained deeply capable.
Sometimes performance improvements aren't about what you serve — they're about what you don't serve. At HCD, I learned to make every request count.