Documentation menu
Core concepts

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.

json
{
  "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.

json
{
  "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.

ResourceBound
Operations per execute64
Request / response4 MiB each
Record value1 MiB
Collections256
Logical record data256 MiB
Mutation receipts100,000