{
  "slug": "serializable-snapshot-isolation",
  "term": "Serializable Snapshot Isolation",
  "aliases": [
    "SSI"
  ],
  "definition": "Serializable Snapshot Isolation (SSI) is a concurrency-control technique that adds read-write antidependency tracking to snapshot isolation and aborts transactions to prevent nonserializable committed histories.",
  "note": "PostgreSQL 18 uses SSI for SERIALIZABLE, while REPEATABLE READ remains snapshot isolation. [postgres-isolation]\n\nAn rw-antidependency points from a transaction that reads a version or predicate result to a concurrent transaction whose write would change that result but is absent from the reader's snapshot. A snapshot-isolation serialization cycle needs two consecutive rw-antidependencies, but the pair need not form a cycle. PostgreSQL uses commit-order and read-only refinements; false positives remain. [ports-ssi]\n\nPostgreSQL SIReadLock entries track possible conflicts without blocking writers or causing deadlocks themselves. However, ordinary update locks can still wait. [postgres-isolation]\n\nOn SQLSTATE 40001, retry the complete transaction, including its query and value decisions; another retry may also fail. [postgres-retry]\n\nSERIALIZABLE READ ONLY DEFERRABLE may wait for a safe snapshot, then runs without SSI serialization failures or its normal tracking overhead. This does not prevent other errors. [postgres-transaction] When relying on SSI alone for application consistency, all relevant writes and consistency-sensitive reads must use SERIALIZABLE; changing only a reporting transaction does not upgrade lower-isolation writers. [postgres-consistency]\n\nSSI is a serializability mechanism. Check real-time precedence separately for the specific system and API; SSI's name alone does not establish strict serializability. [ports-ssi] [herlihy-wing]",
  "status": "shipping",
  "advantages": [
    {
      "text": "Committed serializable transactions can preserve cross-row invariants without blocking predicate-read locks.",
      "citationIds": [
        "postgres-isolation"
      ]
    }
  ],
  "limitations": [
    {
      "text": "A serialization failure is not proof that an actual dependency cycle was present; conservative detection can produce false positives.",
      "citationIds": [
        "ports-ssi"
      ]
    },
    {
      "text": "Retries are part of the application contract, not a guarantee of completion within a fixed number of attempts.",
      "citationIds": [
        "postgres-retry"
      ]
    },
    {
      "text": "PostgreSQL SERIALIZABLE reads from permanent user tables remain provisional until successful commit, including ordinary read-only transactions. SERIALIZABLE READ ONLY DEFERRABLE obtains a safe snapshot before returning data. This concerns serialization anomalies, not freshness or all errors.",
      "citationIds": [
        "postgres-isolation",
        "postgres-transaction"
      ]
    },
    {
      "text": "Sending a notification after commit still leaves a crash gap before delivery. A transactional outbox records the pending event in the same transaction as the data change; a separate process sends committed events, and duplicate delivery requires idempotent handling.",
      "citationIds": [
        "aws-outbox"
      ]
    },
    {
      "text": "Predicate-lock coverage depends on the query plan. Sequential scans take relation-level coverage; memory-driven promotion to coarser coverage can increase serialization failures without introducing writer-blocking locks. PostgreSQL's max_pred_locks_per_transaction sizes shared tracking capacity, not a hard allowance for each transaction.",
      "citationIds": [
        "postgres-isolation",
        "postgres-lock-memory"
      ]
    }
  ],
  "related": [
    "snapshot-isolation",
    "serializability",
    "write-skew",
    "strict-serializability"
  ],
  "supersedes": [],
  "supersededBy": [],
  "firstSeen": null,
  "lastSeen": null,
  "citations": [
    {
      "id": "aws-outbox",
      "title": "AWS Prescriptive Guidance: Transactional outbox pattern, dual writes and duplicate messages.",
      "url": "https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/transactional-outbox.html",
      "accessed": "2026-10-30"
    },
    {
      "id": "ports-ssi",
      "title": "Dan R. K. Ports and Kevin Grittner. Serializable Snapshot Isolation in PostgreSQL. PVLDB 5(12), 1850-1861 (2012), sections 3.1-4.3 and 5.4.",
      "url": "https://vldb.org/pvldb/vol5/p1850_danrkports_vldb2012.pdf",
      "accessed": "2026-10-30"
    },
    {
      "id": "postgres-isolation",
      "title": "PostgreSQL 18: Transaction Isolation, sections 13.2.2-13.2.3.",
      "url": "https://www.postgresql.org/docs/18/transaction-iso.html",
      "accessed": "2026-10-30"
    },
    {
      "id": "postgres-retry",
      "title": "PostgreSQL 18: Serialization Failure Handling, section 13.5.",
      "url": "https://www.postgresql.org/docs/18/mvcc-serialization-failure-handling.html",
      "accessed": "2026-10-30"
    },
    {
      "id": "postgres-transaction",
      "title": "PostgreSQL 18: SET TRANSACTION, DEFERRABLE snapshot acquisition.",
      "url": "https://www.postgresql.org/docs/18/sql-set-transaction.html",
      "accessed": "2026-10-30"
    },
    {
      "id": "postgres-consistency",
      "title": "PostgreSQL 18: Data Consistency Checks at the Application Level, section 13.4.1.",
      "url": "https://www.postgresql.org/docs/18/applevel-consistency.html",
      "accessed": "2026-10-30"
    },
    {
      "id": "hesela-consistency",
      "title": "Hesela: Storage consistency, SSI dependency tracking.",
      "url": "https://hesela.com/analyses/storage-consistency-ordering/#ssi-dependencies",
      "accessed": "2026-10-30"
    },
    {
      "id": "herlihy-wing",
      "title": "Herlihy and Wing. Linearizability: A Correctness Condition for Concurrent Objects. ACM TOPLAS 12(3), 1990, section 3.3.",
      "url": "https://cs.brown.edu/~mph/HerlihyW90/p463-herlihy.pdf",
      "accessed": "2026-10-30"
    },
    {
      "id": "postgres-lock-memory",
      "title": "PostgreSQL 18: Lock Management, predicate-lock capacity and granularity promotion.",
      "url": "https://www.postgresql.org/docs/18/runtime-config-locks.html",
      "accessed": "2026-11-10"
    }
  ],
  "updated": "2026-11-10"
}
