I considered event sourcing for SlotTurf's payment flow. Here's why I didn't use it.
When I was designing SlotTurf's payment and booking flow, I looked at event sourcing. Payment systems are the canonical use case every transaction mutates state, you want a full audit trail, and bugs are expensive. It seemed like a fit.
I ended up with CRUD. Here's what I actually considered.
CRUD stores current state. You query the bookings table and get what's true right now.
Event sourcing stores the sequence of changes that produced that state. Instead of a bookings row with status: confirmed, you have a stream of events SlotReserved, PaymentInitiated, PaymentConfirmed, BookingConfirmed and you derive the current state by replaying them.
The audit trail argument is real. With event sourcing, you can reconstruct exactly what happened and when. With CRUD, once you update a row, the previous state is gone unless you built a separate history table.
Razorpay already owns the payment audit trail. Every transaction, failure, retry, and webhook is logged on Razorpay's side with timestamps I can query. Building my own event store for payments would be duplicating infrastructure that a production-grade payment processor already maintains.
The booking state machine is simple. A slot goes available β pending β confirmed or rolls back to available on payment failure. That's four states and three transitions. Event sourcing earns its complexity when you have many state transitions with business logic at each step. This isn't that.
Read models add overhead I didn't need. Event sourcing typically pairs with CQRS you maintain separate read models because replaying an event stream on every query is slow. For SlotTurf's query patterns (get available slots, get user bookings), a straightforward Postgres query is faster to write and faster to run than maintaining read models.
What I did use: PostgreSQL transactions with SELECT FOR UPDATE to lock slot rows during booking, and server-side Razorpay signature verification before writing any booking record. That handles the correctness and audit requirements without event sourcing's overhead.
Financial systems where Razorpay doesn't own the transaction log internal ledgers, wallet systems, anything where you're the source of truth for money movement. Collaborative editors where you need to reconstruct document state from individual keystrokes. Systems with complex domain logic where each state transition has real business meaning.
The pattern is worth understanding. I'll probably use it eventually. For SlotTurf's scope, it was the wrong tool.