Contended transactions

In Fauna, every query is an ACID-compliant transaction. Contention occurs when multiple transactions try to access the same data at the same time and at least one transaction attempts to write to it.

Causes of contention

  • Write contention (most common):

    Occurs when a transaction reads or writes to a document, or reads an index entry, and that document or index entry is concurrently being written to by another transaction.

  • Stale schema cache (less common):

    Occurs when a change in database schema is detected during transaction execution. The transaction is retried against the latest schema.

Manage retries for contended transactions

Fauna detects contention and automatically retries contended transactions. These retries occur within Fauna and don’t require action by the client. Retries consume additional read, write, and/or compute operations and add transaction latency.

If you’re using the Fauna Core HTTP API, you can use the X-Max-Contention-Retries HTTP header to control the number of retry attempts:

curl -X POST \
  'https://db.fauna.com/query/1' \
  -H 'Authorization: Bearer <FAUNA_SECRET>' \
  -H 'Content-Type: application/json' \
  -H 'X-Max-Contention-Retries: 5' \
  -d '{
    "query": "Product.all()"
  }'

The Fauna client drivers include configuration options for the X-Max-Contention-Retries header:

Error handling

If a contended transaction exhausts retries, the Core HTTP API returns a runtime error with a 409 HTTP response and a contended_transaction error code:

{
  "error": {
    "code": "contended_transaction",
    "message": "Transaction was aborted due to detection of concurrent modifications to <DOCUMENT>"
  }
}

Fauna’s client drivers include classes for contended transaction errors:

How to minimize contention

Depending on your use case, occasional contention may be unavoidable. However, you can follow these best practices to minimize contention.

Use strict serialization only when needed

Fauna uses strict serialization, or linearization, for all read-write transactions. By default, read-only transactions are serializable but not strictly serialized.

If you’re using the Core HTTP API, you can use the X-Linearized HTTP header to opt-in to strict serializability for read-only transactions:

curl -X POST \
  'https://db.fauna.com/query/1' \
  -H 'Authorization: Bearer <FAUNA_SECRET>' \
  -H 'Content-Type: application/json' \
  -H 'X-Linearized: true' \
  -d '{
    "query": "Product.all()"
  }'

The Fauna client drivers also include configuration options for the X-Linearized header:

While it provides the strongest level of consistency, strict serialization can increase the likelihood of contention. Only opt-in for strict serialization on read-only transactions if required for your use case.

Avoid concurrent schema changes

Concurrent schema writes in the same database can cause contended transactions, even if the changes affect different resources. This includes schema changes made using:

A schema change triggers a transaction that validates the entire database schema. To avoid errors, perform schema changes sequentially instead.

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!