Documentation menu
Transactions & retries
One ordered request owns validation, durable commitment and atomic publication.
On this page
An ordered, atomic batch
An execute request contains requestId and operations. Operations observe earlier staged changes in the same request. Schema, revision, uniqueness and object-link validation apply before the database publishes the complete candidate. A rejected transaction publishes none of its changes.
{
"requestId": "project-title-v1",
"operations": [
{
"op": "query",
"qql": "UPDATE projects SET title = :title WHERE _key = :key AND _revision = :revision",
"bindings": {
"title": "Ready for review",
"key": "first-project",
"revision": "use-current-record-revision"
},
"expectedCount": 1
}
]
} Keep the exact intent
Successful mutations store their request identity, resource requirements and response in a durable receipt. An identical retry checks the caller’s current permissions and returns the original result and revision without executing the query again, even after restart. Reusing the identity with different operations is a conflict. A rejected write does not consume its request identity.
A timeout, interrupted connection or outcome_unknown response can leave commitment uncertain. Keep the original request and resolve it after recovery. The TS client submits once and never silently replaces the ID. Embedded callers must drop all handles and reopen after outcome_unknown.
Resolve historical outcomes
Supported historical receipts retain their original outcomes when query admission rules change. Legacy receipt recovery derives the original resource requirements, including empty loop bodies and joins, and checks them against current permissions. It never executes the old mutation again or repairs previously rounded numbers.
Fresh requests still use the current parser and limits. Rewriting storage preserves receipt identity and results in the new versioned format. Older binaries cannot read the new receipt formats; changing the binary back is not a supported downgrade.
Inspect execution work
A server advertising execution_profile accepts profile: true on the transaction request. Studio exposes this as Include execution profile. The transaction runs normally, including writes, and returns scan/reuse, join, sort and aggregate counters with the scalar access paths it opened.
The bounded path inventory reports omissions explicitly. Counters describe the execution used for the result; they exclude commit waits, index construction and discarded speculative work. Profiling does not run the query again or force an index cardinality scan. Keep the option unchanged when resolving an uncertain request: a receipt returns the original profile.
{
"requestId": "inspect-project-order",
"profile": true,
"operations": [
{
"op": "query",
"qql": "SELECT title FROM projects SORT title LIMIT 10",
"bindings": {}
}
]
} Check the change you intend
Typed replace and delete require the current opaque revision. QQL expectedCount is a precondition: a mismatch rejects the entire request. UPDATE and DELETE count affected rows; SELECT counts returned rows after LIMIT. LIMIT 1 checks existence and cannot establish uniqueness.
Current admission limits
These are admission limits, not a complete process-memory budget. Receipt retirement, public storage policies and full cold/saturation acceptance remain open.
| Resource | Bound |
|---|---|
| Operations per execute | 64 |
| Request / response | 4 MiB each |
| Record value | 1 MiB |
| Collections | 256 |
| Logical record data | 256 MiB |
| Mutation receipts | 100,000 |