Discussion about drafts causing overwriting of backend updates in Sanity
You've identified the problem correctly – this is a classic race condition where editors publishing drafts can overwrite backend updates. The good news is that Sanity has built-in mechanisms to prevent exactly this scenario.
The Solution: Use ifRevisionID for Optimistic Locking
The best way to prevent your backend updates from being overwritten is to use optimistic locking with the ifRevisionID parameter in your backend mutations. Here's how it works:
When your backend updates a document, it should:
- First fetch the current document (including its
_revfield) - Apply your changes using a
patchmutation withifRevisionIDset to the current_revvalue
// Example using the JS client
const doc = await client.getDocument(documentId)
await client
.patch(documentId)
.set({ yourField: newValue })
.ifRevisionID(doc._rev) // Only apply if revision matches
.commit()If someone else (an editor or another backend process) has modified the document in the meantime, the mutation will fail with a 409 Conflict HTTP status code. Your backend can then:
- Fetch the updated document
- Reapply your changes with the new data
- Retry with the fresh
_rev
Why This Works
According to the transactions documentation, Sanity uses exclusive locks during transactions to provide repeatable read isolation. However, the pattern you're experiencing (read-then-write cycles) doesn't have the same isolation guarantees unless you use optimistic locking.
The ifRevisionID parameter ensures that your mutation is only accepted if the document hasn't changed since you read it. This prevents the "lost update" anomaly you're experiencing where one writer's changes overwrite another's.
Additional Considerations
For your editors: You mentioned encouraging them to discard drafts – while that could help, it's not a reliable solution since it depends on human behavior. The technical solution with ifRevisionID is much more robust.
Draft vs Published: Remember that in Sanity, drafts and published documents are separate (drafts have the drafts. prefix). When an editor publishes a draft, it's essentially copying the draft over the published document. If your backend is updating the published document while a draft exists, publishing that draft will indeed overwrite those changes unless you use ifRevisionID.
Eventual Consistency: Be aware that Sanity has eventual consistency for queries (though transactions themselves are strongly consistent). If your backend relies on GROQ queries to determine what to update, there could be a small delay before changes are visible to queries.
This approach will ensure your backend updates are never silently overwritten, and you'll have clear error handling when conflicts occur.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.