BOOTING NEURAL FEED…
NEWSBOX v0.2 · NEON SPONSOR ↗
← WSZYSTKIE NEWSY
Tech & Dev 75% CONFIDENCE Dev.to Top 15 czerwca 2026 00:06

Optimistic concurrency is the whole design: event sourcing on Aurora DSQL

AUTHOR · Jonathan

Quorum is an incident command plane built on Amazon Aurora DSQL. The failover story lives in another post. This one is about a narrower question that turned out to be the foundation: when several responders write to the same incident at the same moment, across regions, during the worst minutes of an outage, how do you guarantee the record never forks into two conflicting truths. The answer is two design choices that are really one choice seen from two angles: event sourcing, and DSQL's optimistic concurrency control. Quorum is event-sourced across four tables. Every state change is an immutabl

Quorum is an incident command plane built on Amazon Aurora DSQL. The failover story lives in another post. This one is about a narrower question that turned out to be the foundation: when several responders write to the same incident at the same moment, across regions, during the worst minutes of an outage, how do you guarantee the record never forks into two conflicting truths. The answer is two design choices that are really one choice seen from two angles: event sourcing, and DSQL's optimistic concurrency control. The data model is append-only Quorum is event-sourced across four tables. Every state change is an immutable event appended to a log, not an in-place update. The current state of an incident is a fold over its events. There is no UPDATE incidents SET status = ... ; there is an acknowledged event, a note event, a resolved event, and the status you render is computed from them. The event's UUID is its primary key and its idempotency key at the same time. A retried write carrying the same UUID cannot double-apply: the insert collides on the primary key and becomes a no-op. That property sounds minor until you remember what kind of system this is. A tool designed to survive network failure retries writes constantly, and "the responder tapped resolve twice because the first response was slow" must not produce two resolutions. Append-only also suits the domain directly. For an incident system the audit trail is the product, not a side effect. "Who acknowledged this, at what time, and what did the timeline look like at 02:14" is a first-class question for the post-incident review and a compliance requirement in regulated environments. Event sourcing gives you that for free. It also gives DSQL a write pattern it likes, which matters more than you would expect. The stack, briefly TypeScript end to end. Kysely as a typed query builder rather than an ORM, because I wanted type safety without surrendering control of the SQL: on a distributed database the exact shape of a query has real consequences, and I did not want a query planner I could not see. Next.js App Router on Vercel for the front end and the server-side data access. DSQL as the database, reached over IAM using Vercel's OIDC federation to AWS, so there are no static database credentials anywhere in the system. DSQL uses a PostgreSQL parser, planner, and type system, so the dialect is largely compatible and the standard Postgres driver and Kysely work with minimal ceremony. The places it diverges are documented and worth reading before you design a schema: How Amazon Aurora DSQL differs from single-instance PostgreSQL . Optimistic concurrency, the core DSQL does not take row locks. A transaction reads a consistent snapshot, does its work, and the conflict check happens at commit time. When two transactions modify the same data, the one with the earliest commit time wins and the other receives a serialization error, the PostgreSQL SQLSTATE 40001 (DSQL also surfaces its own OC000 and OC001 codes), which the application is expected to retry. No locks are held for the duration of a transaction, and there are no deadlocks, ever. This is documented in Concurrency control in Aurora DSQL . So a DSQL application is not "write SQL and hope." It is "write SQL, catch the conflict, retry the whole transaction." Quorum wraps writes in a bounded retry with a small backoff. AWS's guidance is that the retried transaction should be idempotent, which closes a loop with the data model: the event UUID is already the idempotency key, so the retry is safe by construction rather than by hope. A subtlety the docs call out, and worth internalizing: SELECT ... FOR UPDATE is syntactically supported but does not block. It surfaces as a commit-time conflict instead. If you carry over a Postgres habit of serializing access to a hot row with FOR UPDATE , that path becomes a retryable conflict rather than a blocking wait, and a row everyone updates at once becomes a retry storm. The schema fix is

CZYTAJ ŹRÓDŁOWY ARTYKUŁ → WIĘCEJ Z TECH & DEV