Engineering

Booking logic is where no-code breaks first

Two guests hit Book on the same room for the same weekend, four seconds apart. Both see it free. Both pay. That outcome is not a flaw in your form validation, and tightening the form will not remove it. It follows from how the platform runs your logic, and it is the first place a no-code build stops being able to help you.

The gap between checking and writing

A booking workflow does two things. It reads availability, then it writes a reservation. Everything depends on what can happen between those two moments. PostgreSQL's default isolation level, Read Committed, gives each query a snapshot from the instant that query began, so the documentation warns that two successive SELECT commands can see different data even inside a single transaction if another transaction commits in between. A workflow builder does not give you the single transaction to begin with. Each step is its own round trip.

So the second guest's availability check runs against a picture of the world taken before the first guest's row existed. It comes back free. Four seconds later the write lands with nothing in its way. The window is narrow, which is exactly why the bug survives every manual test you run and then surfaces on the weekend your marketing finally worked.

What the database will do for you if you let it

PostgreSQL ships a constraint built for this shape of problem. Store the booked period as a range type, add EXCLUDE USING GIST (room WITH =, during WITH &&), and the engine rejects the second insert on its own with "conflicting key value violates exclusion constraint". There is no workflow step to get right and no availability check to race. Overlapping rows stop being storable.

When the operation spans more than one table, say a hold, a deposit charge and a confirmation, you can run the whole thing at Serializable isolation and let Postgres abort the loser with SQLSTATE 40001. The manual is blunt about the price: applications using this level must be prepared to retry transactions due to serialization failures. That retry is a small piece of code you own and can test. I like this part, because you can point fifty concurrent requests at one room in CI and assert that exactly one of them wins.

The queue workaround runs into the platform's own limits

The standard fix is to funnel every write through one backend workflow so requests process in order. It works until it meets the platform's rate limits. Airtable allows 5 requests per second per base and answers the sixth with a 429 you must wait 30 seconds to clear, with monthly ceilings of 1,000 calls on Free and 100,000 on Team. Webflow's Data API gives 60 requests per minute on Starter and Basic plans and 120 on CMS and above. Bubble's copy action caps at 100 entries and, past that limit, does nothing at all instead of failing loudly.

A queue that has to respect five writes a second gets deeper as the business grows, and deposits make it sharper still. A payment hold and a booking row need to commit or fail together. A workflow engine that cannot undo step three when step five fails will charge people for rooms they never got. When we moved Stay World Class off Webflow and Xano to Next.js, NestJS and Supabase, the interesting part was not the framework swap. It was a four stage ETL that mapped every legacy ID to a PostgreSQL UUID so nothing broke on the way over. Lighthouse went from 55.91 to 91 and LCP came down 77 percent, though the reason the work paid for itself was that booking rules finally lived somewhere they could be enforced.

When staying put is the right answer

If one person is booked at a time and volume is low, the race window almost never opens. A single instructor with a dozen slots a week can run on Airtable for years and lose nothing. The same goes for internal tools where the people booking sit in one room and can shout at each other. Those platforms were the correct choice when getting a first version live was the binding constraint, and for plenty of businesses that constraint has not changed.

The question worth asking is what a double booking costs you when it happens. If it is an apology and a refund, stay where you are. If it means a family arriving at a property somebody else is already sleeping in, you have outgrown check-then-write, and no amount of workflow tuning will get you a transaction the platform does not have.

Sources

Have a stack outgrowing itself?

Book a call and we'll walk you through how we'd approach your platform, priced fairly and estimated for real.