Methodology
BuilderProof Editorial Team16 min read63 views

Concurrent-Write Safety Posture: A Proposed Axis for What AI App Builders Emit When Two Writes Collide (August 2026)

A candidate BuilderProof benchmark axis that scores whether the code AI app builders emit stays correct when two writes to the same record overlap. Rubric, four posture levels, a reproduction protocol, and an open call for comment.

Minimalist blueprint illustration of two overlapping request paths converging on a single database record, the second arrow covering the first, representing a lost update from concurrent writes
Minimalist blueprint illustration of two overlapping request paths converging on a single database record, the second arrow covering the first, representing a lost update from concurrent writes
On this page

An AI app builder will happily generate a booking form, an inventory counter, a "claim this seat" button, and a checkout. Every one of those works perfectly in the preview, because the preview has exactly one user in exactly one tab. The question this axis proposes to measure is what the emitted code does when two writes to the same row overlap: whether one silently overwrites the other, whether the same submit lands twice, and whether anyone ever finds out. We are not scoring builders today. We are publishing a candidate axis, its rubric, its posture levels, and a reproduction protocol, and opening all of it for comment before it enters the composite.

Quick Answer

Concurrent-write safety posture is a proposed BuilderProof benchmark axis, drafted August 20, 2026, that scores whether the code an AI app builder emits stays correct when two writes to the same record overlap in time. It is measured from the exported project, not from the preview: does the generated write path use a transaction or an atomic conditional update, or does it read a row into client memory, mutate it in JavaScript, and write the whole object back a second later. The rubric weights six signals: atomic write boundaries, elimination of client-side read-modify-write, uniqueness enforced in the schema rather than by a pre-check query, idempotency of retried mutations, conflict detection and surfacing, and retry discipline on serialization failure. The failure mode it targets is the lost update, where two correct-looking requests both succeed and one user's change disappears with no error anywhere. The cohort under consideration is the five commercial builders we already track across the August axis series: v0, Lovable, Bolt.new, Replit, and Base44. This page is an axis proposal open for community edits, not a leaderboard.

BuilderProof is an independent, community-editable benchmark for AI app builders. This post proposes a new axis, defines how it would be scored, and cites primary sources WebFetched on August 20, 2026. It does not score any builder on this axis yet, and it does not crown a winner.

v0 Lovable Bolt.new Replit Base44

Why concurrent-write safety deserves its own axis

Every other axis we have proposed this month asks whether a single request is handled correctly. This one asks whether two requests, each individually correct, are still correct together. That is a different property, and it is the one that survives contact with real users.

The canonical guidance is old and settled. PostgreSQL, the database under most of what these builders emit, states in its own documentation that "Read Committed is the default isolation level in PostgreSQL," and that at that level "two successive SELECT commands can see different data, even though they are within a single transaction, if other transactions commit changes." It is explicit that this default "is not sufficient for all cases," and that at stricter levels "applications using this level must be prepared to retry transactions due to serialization failures." The PostgreSQL transaction isolation documentation has said this for two decades. None of it is controversial. The open question is whether AI app builders apply any of it in the code they generate.

There is a reason to suspect they might not, and it is structural rather than a criticism of any vendor. A model optimizing for a preview that works has no gradient toward concurrency correctness, because the preview is single-user by construction. A lost update is invisible in the loop that trains, prompts, and rewards the generator. Nothing in a one-tab demo distinguishes a transaction-wrapped write from a read-modify-write round trip. Both look identical, and both are green.

The failure is not hypothetical in ordinary software either. In April 2026, freeCodeCamp filed and fixed a lost-update race condition in its challenge submission API, where rapid submissions from multiple tabs caused the second request to read progress data before the first had finished writing, silently discarding the first submission. The code carried a TODO acknowledging the need to "prevent concurrent completions of the same challenge by using optimistic concurrency control." The fix was a version check against an existing updateCount column, a retry on conflict, and replacing a full-array overwrite with an atomic push. That is a mature, heavily reviewed open-source codebase written by humans. The point is not that AI builders are worse. The point is that this failure class is easy to ship and hard to see, which is exactly what a benchmark axis is for.

What "concurrent-write safety posture" means here

The axis scores the emitted artifact, not the platform's marketing and not the chat experience. Specifically it asks, of the untouched export:

When two clients act on the same record at overlapping times, does the generated code guarantee that both effects are either correctly combined or explicitly refused, or does it allow one effect to disappear without an error?

That definition deliberately covers three distinct real-world shapes:

  1. The lost update. Two users open the same record, both edit different fields, both save. The second save writes a whole object built from a stale read, and the first user's change is gone. Nobody sees an error.
  2. The double submit. One user clicks submit twice, or a flaky network causes the client to retry. Two rows appear where one was intended, or one payment is taken twice.
  3. The oversell. Two users claim the last seat, the last ticket, or the last unit of stock. A pre-check query said one was available for both of them, because both checks ran before either write.

All three are the same underlying defect: a decision made from a read that was already stale by the time the write landed.

One finding worth stating plainly

There is a specific reason this matters more for AI-generated apps built on a hosted data API than for a conventional server-rendered app, and it is a property of the data layer rather than of any vendor's model quality.

Several of these builders emit a client that talks to a PostgREST-style HTTP data API. PostgREST's own documentation states that "every request to an API resource runs inside a transaction," and that "every transaction uses the PostgreSQL default isolation level: READ COMMITTED." Read carefully, that is a guarantee about one request. It says nothing about two. The PostgREST transactions reference is precise on this point, and the precision is the finding: a single request is atomic, so a single UPDATE is safe, but the common generated pattern of select the row, change a field in JavaScript, then send the whole object back is two separate requests, and therefore sits inside no transaction at all. The transactional guarantee the platform advertises does not extend across the gap where the defect lives.

This means an AI builder can emit code that is idiomatic, passes review, uses the recommended client library exactly as documented, and still loses updates by construction. It also means the fix is usually cheap and local: move the mutation into a single atomic statement, add a conditional predicate on the version the client actually read, or put the multi-step logic behind one server-side function so the whole sequence lands in one request. Cheap, local, and almost never done unless someone asks for it.

The proposed rubric

Six signals, weighted to 100. Every signal is scored from the exported code and the emitted schema, so any reader with the same export can check the score and dispute it.

Scroll to see more

SignalWhat we measureWeight
Atomic write boundariesWhether a mutation that touches more than one row, table, or statement is wrapped in a single transaction or a single server-side function call, rather than issued as a sequence of independent requests that can interleave25
Read-modify-write eliminationWhether counters, totals, arrays, and toggles are updated with an atomic or conditional statement, rather than read into client memory, mutated in JavaScript, and written back as a whole object20
Uniqueness enforced in the schemaWhether "this must not exist twice" is expressed as a database constraint, rather than as a SELECT that checks for an existing row immediately before inserting one20
Idempotency of retried mutationsWhether a mutation that is delivered twice, by a double click or a network retry, produces one effect rather than two, via an idempotency key, a natural dedupe key, or an upsert on a unique constraint15
Conflict detection and surfacingWhether a stale write is detected at all, via a version column, an updated_at predicate, or a returned row count of zero, and whether the interface tells the user their change did not apply12
Retry discipline on serialization failureWhether the emitted code handles the documented failure path of stricter isolation, retrying on a serialization error rather than surfacing a raw 500 or swallowing it8

Two weighting decisions are worth arguing about, and we would rather argue about them now than after the axis ships.

Why atomic write boundaries carry the most weight. Everything else is a mitigation. A transaction or a single server-side function is the primitive that makes the other five signals unnecessary in the first place, and its absence is what turns a routine two-step operation into a race.

Why conflict surfacing is weighted lower than detection-free correctness. A build that never loses an update scores better than a build that loses updates loudly. Detection is a fallback for cases where a conflict is genuinely a user decision, such as two people editing the same document. It is not a substitute for correctness on a counter.

The four posture levels

Scores roll up into a posture level, so the axis can be read at a glance without collapsing the detail.

Level 0, Unguarded. Multi-step writes issued as independent requests. Counters read and written back from the client. Uniqueness checked by a preceding query. No conflict detection anywhere. Lost updates and double submits are reachable by two ordinary users doing ordinary things.

Level 1, Client-guarded. The interface disables the submit button while a request is in flight, and may debounce input. Real defensive work, and it removes the most common accidental double submit. It does nothing for two different users, two tabs, or a retried request that the client never saw fail. This is where a well-prompted build tends to land.

Level 2, Constraint-backed. The schema carries the invariants: unique constraints on natural keys, non-negative checks on quantities, foreign keys that actually cascade. Multi-step writes are wrapped or pushed server-side. Duplicate inserts fail at the database rather than succeeding twice. The database becomes the arbiter instead of the client.

Level 3, Conflict-aware. Everything in Level 2, plus stale writes are detected explicitly by version or timestamp predicate, refused rather than applied, returned to the interface as a conflict, and handled with a retry or a merge prompt rather than a generic error toast. Retried mutations are idempotent by key.

We expect the honest distribution across the cohort to cluster at Levels 0 and 1, for the structural reason given above. We will publish whatever we find, including a result that contradicts that expectation.

How to reproduce it

The protocol is written so that a reader can run it without us, which is the point of a community-editable benchmark.

  1. Build the same app on each builder from a fixed prompt. The prompt describes a seat-booking app with limited inventory, an editable profile, and a counter. It does not mention concurrency, transactions, locking, or race conditions. Asking for the safeguard would measure prompt compliance, not default posture.
  2. Export the project untouched. No manual edits, no follow-up prompts, no "make it production ready" pass. The axis scores what the builder emits by default.
  3. Read the write path for every mutating surface. For each one, classify: single statement, transaction or server-side function, or multi-request read-modify-write.
  4. Read the emitted schema. Record which invariants exist as constraints and which exist only as application code or only as a comment.
  5. Score the six signals from the code and the schema. Cite file and line for every point awarded or withheld, so disagreements are about the artifact rather than about impressions.
  6. Publish the exports and the rubric worksheet so a reader can re-score them and dispute any cell.

A dynamic verification pass, firing overlapping requests at a deployed instance and checking whether both effects survive, is the natural companion to this and would turn a static reading into a measured result. That pass requires paid accounts across the cohort and a controlled deployment for each. It is not part of this proposal, and we will not publish numbers we have not produced.

What the vendor documentation currently says

Because the axis will first be read from the emitted artifact, we deliberately have not run a full documentation survey yet. Two spot checks are worth recording, both read on August 20, 2026, and both stated as observations rather than as scores.

The Base44 entities overview documents full CRUD through the SDK, schema flexibility, real-time updates, and security rules. It does not mention transactions, atomic updates, optimistic concurrency, version fields, or unique constraints. The Lovable Supabase integration page describes edge functions in detail, including that "you don't write these functions yourself," and likewise does not mention transactions, atomic updates, optimistic concurrency, version columns, unique constraints, or race conditions.

Documentation silence is not evidence that a generated app is unsafe. It means a prospective user cannot verify the safeguard from the vendor's published material, which is a fact about the documentation surface and nothing more. It is also entirely normal: concurrency control is a property of the code and the schema, not usually of a getting-started guide. We record it here only because it is one more reason the axis has to be scored from the export.

How this relates to our existing axes

This axis is adjacent to several published ones, and the boundaries matter enough to state.

Our API-design consistency axis includes a sub-criterion on idempotency and method safety. That one is about HTTP semantics: whether GET is free of side effects and whether PUT and DELETE are repeatable in the protocol sense. This axis is about the data layer underneath: whether two overlapping writes preserve both intentions. A generated API can be perfectly RESTful, answer 405 with a correct Allow header, and still lose an update on every concurrent edit. The concepts share a word and almost nothing else.

Idempotency in the sense this axis uses it is the operational one, and the reference implementation is well known. Stripe's documentation describes saving "the resulting status code and body of the first request made for any given idempotency key," so that "if a connection error occurs, you can safely repeat the request without risk of creating a second object or performing the update twice," with keys retained for at least 24 hours and accepted on all POST requests. The Stripe idempotent requests reference is the model an emitted checkout would be scored against, since a double-charged customer is the highest-consequence version of the double submit.

The input-validation axis asks whether a single request carries acceptable data. This axis assumes both requests are perfectly valid and asks what their combination does. The database-migration-safety axis covers correctness of the schema as it changes over time; this one covers correctness of writes against the schema as it stands. The state-handling axis covers what the interface shows during and after a write; a conflict that is never detected has no state to show, which is why detection sits in this rubric rather than that one.

What we are not claiming

We are not claiming that any builder in the cohort loses updates. We have not scored this axis, and the proposal exists precisely so the rubric can be attacked before any number is attached to a vendor name.

We are not claiming that Level 3 is the right target for every generated app. A personal expense tracker with one user does not need optimistic concurrency, and a rubric that punishes its absence there would be measuring ceremony rather than correctness. What the axis measures is whether the builder's default posture matches the app it was asked to build. A seat-booking app and a single-user notes app should not receive the same posture for the same code.

We are not claiming this is the most important axis. It is a specific, currently unmeasured property, and the argument for it is that its failures are silent, which means no amount of ordinary user testing surfaces them.

Limitations and open questions

The single-tab measurement problem cuts both ways. If the defect is invisible in a preview, it is also hard to demonstrate in a screenshot. A static read of the export is verifiable and cheap, but it measures the shape of the code rather than an observed failure. We consider that an honest limitation of a documentation-and-artifact benchmark, not a hidden weakness.

App-appropriateness is a judgment call. Deciding that a booking app needs Level 2 while a notes app does not introduces a subjective step into an otherwise mechanical rubric. One option is to fix the prompt so that inventory is always in scope, removing the judgment entirely. We lean that way and would like the argument against it.

Prompt sensitivity is a confound here, more than on other axes. A build asked for "a booking system that must never double book" would plausibly score two levels higher than the same builder asked for "a booking system." Our fixed-prompt discipline holds the prompt constant, but the gap between default posture and prompted posture may be the more useful number, and we do not yet measure it.

The weights are a first draft. In particular, the 8 points on retry discipline may be too generous for a cohort whose emitted code rarely raises the isolation level in the first place, in which case the signal is measuring the absence of a problem that was never created.

Corrections, counterexamples from real exports, and rubric edits are welcome. The methodology behind all of this, including how axes enter the composite, is documented in our benchmark methodology.

References

B

Written by

BuilderProof Editorial Team

The BuilderProof lab publishes reproducible, community-editable benchmarks and methodology proposals for AI app builders. Axes are scored from documentation-derived rubrics and open to public revision.

Cite this benchmark

Plain text
BuilderProof Editorial Team. "Concurrent-Write Safety Posture: A Proposed Axis for What AI App Builders Emit When Two Writes Collide (August 2026)". BuilderProof, August 2026. https://www.builderproof.org/benchmarks/concurrent-write-safety-posture-axis-proposal-august-2026.
BibTeX
@misc{builderproof-concurrent-write-safety-posture-axis-proposal-august-2026,
  title  = {{Concurrent-Write Safety Posture: A Proposed Axis for What AI App Builders Emit When Two Writes Collide (August 2026)}},
  author = {{BuilderProof editorial team}},
  year   = {2026},
  month  = {aug},
  howpublished = {\url{https://www.builderproof.org/benchmarks/concurrent-write-safety-posture-axis-proposal-august-2026}},
  note   = {BuilderProof, builderproof.org}
}

Frequently asked questions

Do AI app builders handle concurrent writes safely?

It is largely unmeasured as of August 2026. A generated app is normally validated in a single-user preview, where overlapping writes never happen, so the failure class is invisible in the loop that produces the code. Concurrent-write safety posture is a proposed BuilderProof axis to measure exactly this from the untouched export rather than from the preview.

What is concurrent-write safety posture?

It is a proposed BuilderProof benchmark axis that scores whether the code an AI app builder emits stays correct when two writes to the same record overlap in time. It weights six signals: atomic write boundaries, elimination of client-side read-modify-write, uniqueness enforced in the schema, idempotency of retried mutations, conflict detection and surfacing, and retry discipline on serialization failure.

What is a lost update in a generated app?

A lost update happens when two clients read the same record, each changes something, and each writes the whole object back. The second write is built from a stale read, so it overwrites the first user's change. Both requests succeed, no error is raised anywhere, and the only evidence is that an edit quietly disappeared.

Does a hosted Postgres data API prevent race conditions automatically?

Only within one request. PostgREST documents that every request to an API resource runs inside a transaction at the PostgreSQL default isolation level, READ COMMITTED. That makes a single statement atomic, but the common generated pattern of reading a row, mutating it in JavaScript, and sending the whole object back is two separate requests and is therefore covered by no transaction at all.

Has BuilderProof scored builders on this axis yet?

No. This page is an axis proposal, published August 20, 2026, containing the rubric, the posture levels, and the reproduction protocol. No builder has been scored on it and no numbers are attached to any vendor. The proposal is open for community correction before the axis enters the composite.

Methodology

API-Design Consistency of Emitted Routes: A Proposed Axis for Whether an AI Builder's Endpoints Agree With Each Other (August 2026)

A candidate BuilderProof benchmark axis that scores whether the HTTP surface an AI app builder emits is internally coherent across every endpoint: one error shape, uniform status-code semantics, one addressing scheme, consistent collection semantics, and a machine-readable contract. Divergence-based scoring, four documented postures, a probe-sweep protocol, and an open call for comment.

21 min read62
Methodology

How We Benchmark AI App Builders: The BuilderProof Methodology v1

BuilderProof methodology v1.1: the published rubric, brief OQ-7, environment standards and weights used to score AI app builders on output quality, speed, deploy quality and agency suitability. The four June 2026 result sets were withdrawn on August 21, 2026 as placeholder data, so the lab currently publishes method, not scores.

11 min read180