On Scenarios That Will Not Happen · @radekmie’s take on IT and stuffOn Scenarios That Will Not Happen<br>By Radosław Miernik · Published on 31 May 2026 · Comment on RedditTable of contents<br>IntroBackgroundA bit of luxuryEverything breaksClosing thoughtsIntro<br>While planning the data model for a new functionality, you can always hear two completely different stories. One comes from the “business” people, who focus on happy paths and only care about the majority of the users. The second one comes from the “technical” people1, who are responsible for making sure it will work for all users and every single edge case they may come up with.At some point, the decision must be made; ideally within the allocated budget. But what if there’s not enough time or other resources to cover all edge cases? “It won’t happen!”, says the first group. “But what if it will!?”, screams the other. In that case, most teams will do whatever the leader wants, so I guess it’s… Background<br>Today’s example will revolve around hotel bookings, so let’s start with them. At its core, we have a start and end date, a customer ID, and a list of categories assigned to it. In reality, there’s much more to it, but we won’t need it today.type HotelBooking = {<br>startDate: Date;<br>endDate: Date;<br>customerId: string;<br>categories: HotelBookingCategories;<br>};<br>Now, the categories are what we have to talk about. First of all, they have many origins – it can be a room type (e.g., “junior suite”), a reserved parking spot (e.g., “garage”), or whether breakfast or dinner is included (e.g., “breakfast only”). Secondly, they are used both for display (e.g., on the list of today’s bookings) and for calculation (e.g., planning kitchen inventory). Lastly, there are both extremely popular categories that most bookings have (e.g., room type) as well as one-of-a-kind ones (e.g., “Valentines 2014 Special”).That was discussed by the entire team, and everyone agreed that it’s perfectly fine to represent it as a list of identifiers of the category:type HotelBookingCategories = string[];<br>This setup worked well for roughly two years, and everything was good. Sure, some users complained that they see duplicated categories, but once we told them that the system won’t magically unify Junior Suite and Jr. Suite. They went with only one and that was it.A bit of luxury<br>As time went on, more and more automation was based on the categories. If you have ever worked with software being used by nontechnical people, you know what kind of crazy workarounds they tend to come up with… And so they did.You see, some hotels have spas. Usually, guests cannot use it daily, but once or twice during their stay. But it doesn’t play well with the structure we have, as a Spa Included category will be shown every day, not just once.After some further discussions, we decided to change it slightly and introduce categories by date, i.e., an additional list of date-specific categories:type HotelBookingCategories = {<br>categories: string[]; // Old.<br>categoriesByDate: { // New.<br>date: Date;<br>categories: string[];<br>}[];<br>};<br>No migration was needed (yay!), and it was fully backward-compatible (i.e., we could revert the code at any time without losing the past data). However, we realized that in every single place where we do something with the categories, we have to pass the desired date now. This would be tedious and easy.But then we thought it could be even easier. We decided to use the newly added categoriesByDate field exclusively in some places, e.g., on the display. The data model stayed the same, but the API returned categoriesByDate with the “global” categories added to it for every date of the booking2.Everything breaks<br>Two months later, we got a strange ticket – for some hotel, the new display logic slowed down significantly. Some dates took so long to display that the browser assumed the website had crashed.After a brief investigation, we’ve found the culprit: some hotel bookings were one full year long. Yes, that means 365 copies of all ~15 packages. Multiply it by a few tens of such bookings, and you end up with over a hundred thousand packages to process.Remember the edge cases discussion we had? “How long a hotel booking could be?” was a sane question, but we all assumed that, according to our real-life experiences, it would not be more than a month. If only I’d remembered my own On Histograms in Decision Making from a year before!In the end, we decided to handle both categories and categoriesByDate in all places, making the code slightly more complex but way more performant. We took this chance to refactor it further, so the final diff added roughly 80 lines (including types but excluding tests).Closing thoughts<br>Our team was once again humbled by the crazy edge cases our lovely users create unknowingly. I agree, we could have prevented that by checking the maximum length of a hotel booking stay, but… Well, we didn’t.Next month, instead of writing something new, I have to spend time reading my own texts from...