Back to Home
Business Systems

Supabase vs Convex for a Booking System: The Rules That Decide

Choose a booking-system backend by testing double bookings, payments, cancellations, staff access and recovery. A practical Supabase vs Convex guide.

Callum Holt5 October 20268 min read
Booking SystemsSupabaseConvexBusiness Automation

Contents

The decision starts with the booking rules

Supabase and Convex can both support a booking system. Choose between them by working through the appointment rules, existing data, staff tools and operating responsibilities. A live calendar alone does not prove that either implementation can prevent a double booking. Supabase is a candidate when the business wants PostgreSQL, SQL reporting and connections to systems built around relational data. Convex is a candidate when the application team wants to express transactional booking logic in TypeScript and keep connected screens reactive. The platform choice still leaves cancellation policy, payment handling and customer access to design. This guide uses an illustrative service business with appointments, a deposit and a staff calendar. It is an architecture exercise, not a claim about client results or a ready-to-run booking application. If a standard booking product meets your requirements, use that before funding a custom build. A custom system becomes useful when the scheduling rules or connected workflows are the part off-the-shelf software cannot handle.

Write down what consumes the capacity

Define the thing that becomes unavailable when a booking is accepted. It might be a staff member, a room, a piece of equipment or several of those together. A lesson can require both an instructor and a vehicle. A class consumes places rather than an entire room slot. These models need different conflict rules. In our example, a visit occupies a technician for the service duration plus a travel buffer. Store the customer, technician, start and finish times, status and payment reference. Keep the scheduling time zone explicit. A customer travelling interstate must not accidentally change an appointment by viewing it in a different zone. List which statuses consume capacity. A confirmed booking normally does. A cancelled booking normally does not. A temporary hold consumes capacity only until its expiry. Treat the expiry check as part of the booking decision, rather than trusting the calendar display to remove a hold in time. Use plain business examples to test the model: two adjoining visits, an appointment that crosses closing time, a staff absence, and a reschedule that would overlap another booking. Agree on those answers before choosing components.

Prevent two customers claiming the same slot

Reading an available slot and then inserting a booking in a separate operation creates a race. Both customers can see availability before either insert finishes. The final availability check and the booking write must belong to one controlled decision. PostgreSQL documents range types and exclusion constraints for preventing overlapping reservations on the same resource. For a Supabase design, evaluate a database constraint or a transactional server operation that enforces the agreed capacity rule. Customer access rules remain separate from that conflict rule. A permission policy does not, by itself, prevent two permitted customers booking the same time. Convex mutations commit their database writes together and provide consistent reads. Its concurrency documentation explains how conflicting transactions are handled. A Convex design should check the relevant resource and time range and create the reservation in the same mutation, using queries that cover the actual overlap rule. Separate client calls do not acquire that guarantee simply because each call uses Convex. The design implication is the same in both cases: protect the decision where data is committed. A disabled booking button is useful feedback, but it cannot enforce capacity across multiple browsers. Sources: PostgreSQL range and reservation constraints, Convex concurrency control and Convex mutation transactions.

Keep payment and booking status separate

A payment provider and your booking database are separate systems. Plan for one to succeed while the other is temporarily unavailable. Use an internal booking ID to connect the reservation, payment attempt and later provider events. An illustrative lifecycle is: available slot, temporary hold, payment pending, confirmed booking. A failed payment can release the hold. A late payment callback needs a defined resolution if the hold has expired and someone else now owns the slot. Do not quietly create an overbooking to reconcile a successful payment. Stripe documents retries and duplicate webhook deliveries. Verify the webhook signature and process an event so that repeating it cannot repeat a charge-related business action. An idempotency key on an outgoing request and duplicate-event handling on incoming callbacks solve different parts of the problem. Stripe says keys can be removed after at least 24 hours; your booking record needs its own lasting references and checks. Show staff an exception when money and booking status disagree. They need enough context to resolve it under the business's policy. Avoid telling the customer that a browser redirect proves everything is complete. Sources: Stripe webhook delivery and Stripe idempotent requests.

Give customers and staff different views of the same booking

A customer should be able to see the booking they are entitled to access. Staff might need a calendar, contact details and permitted changes. A manager might need refunds or roster controls. Write those roles down without relying on a shared administrator account. Supabase documents Row Level Security for controlling access to database rows. In a booking design, relate the authenticated customer to the permitted booking records. Privileged server credentials require a separate review of what each endpoint lets the caller do. For Convex, put authentication and authorisation checks in the functions performing reads and changes. Neither approach replaces a role test. Test with two customer accounts and distinct staff roles. Attempt to read another customer's booking using its ID. Attempt to cancel a booking using an unauthorised account. Attempt to open an attachment without permission. Keep the expected outcome in the project acceptance checklist. Do not put private booking details in reminder URLs or analytics events. Send people to an authenticated view when the message needs sensitive context. Collect the information the appointment needs, rather than using a booking form as a general customer dossier. Source: Supabase Row Level Security.

Make rescheduling, cancellations and reminders agree

A reschedule is a capacity change. Check the destination slot before releasing the original booking, and define the result if the move cannot be completed. Retain an audit record so staff can explain the history to the customer. Reminders should use the current booking record when they run. If a customer moves an appointment after a reminder is queued, a job containing the old date can send a convincing but incorrect message. Store the booking reference and check its current status, time and reminder history before sending. Convex documents scheduled functions and the relationship between scheduling and mutations. Whatever scheduling service a Supabase design uses needs an equivalent review of retries, monitoring and cancellation. The practical requirement is a reminder that tolerates an interrupted worker and does not send twice when a job is repeated. Include a daily exception view for appointments with unresolved payments, failed messages or conflicting status. Choose a person responsible for that view. A system can report an error accurately and still fail operationally if nobody owns the response. Source: Convex scheduled functions.

A comparison worksheet for the actual business

Use these prompts with the owner and the person building the system. Existing records: Does the booking need to sit beside an existing PostgreSQL database, reporting process or CRM? If so, assess the cost of duplicating those records before moving them. Live interaction: Do several staff members need to see changes as they work? Test the actual update behaviour and conflict feedback, rather than choosing from a feature label. Team capability: Who can change the scheduling rules after launch? A SQL team and a TypeScript team may reasonably prefer different designs. Include the maintenance skills the business can retain. Operating cost: Model realistic customers, database activity, storage, notifications and third-party requests using current vendor pricing. Include monitoring and support. This guide deliberately does not turn a vendor's cheapest plan into a project estimate. Exit and recovery: Identify what can be exported, how attachments and identities are handled, and how the team would restore service after a failed release. Ask for a recovery exercise using test data before launch. For the general platform features, read the Convex and Supabase comparison. If staff also need a dashboard and customers need a portal, the Bubble and Retool comparison addresses that interface decision.

The launch checklist should include a failure rehearsal

Before accepting the system, rehearse these cases using test records: two people book the same slot at once; a payment succeeds after the hold expires; the same webhook arrives again; a customer cancels while a reminder is queued; a staff member loses access; and a connection fails halfway through an update. For each case, document the customer message, the final booking state and the staff recovery action. A test passes when the workflow produces an understandable result, not merely when the server returns a success code. The handover should identify the account owners, roles, booking rules, payment connection, reminder process and exception owner. Keep a copy of the acceptance checklist with the operating instructions. That document makes later changes safer because a new developer can understand why a rule exists. If you want help with the design, scope your booking system with the resource being booked, the cancellation rules and the tools already in use. Those details are more useful for an initial scope than a preferred database name.

Frequently asked questions

Can Supabase prevent double bookings? Yes, a PostgreSQL design can enforce suitable capacity rules through constraints or transactional operations. The implementation must account for the resource, overlapping time ranges and statuses that consume capacity. Does Convex prevent double bookings automatically? Convex provides transactional mutations and concurrency control. The application still needs to check the right availability rule and create the booking within the same mutation. A live calendar or separate client operations are insufficient. Should a small business build its own booking system? First test existing booking products against the business's real rules. A custom build is worth considering when scheduling constraints, connected systems or customer workflows cannot be handled adequately by those products.

Build around the appointment rules

Bring the resource being booked, the payment and cancellation rules, and the systems already involved. We can scope the workflow and handover.

Scope your booking system