{
  "aliases": [
    "XID wraparound"
  ],
  "status": "unknown",
  "advantages": [],
  "limitations": [],
  "supersedes": [],
  "supersededBy": [],
  "firstSeen": null,
  "lastSeen": null,
  "updated": "2026-10-18",
  "slug": "transaction-id-wraparound",
  "term": "Transaction ID wraparound",
  "definition": "Transaction ID wraparound is the reuse of low counter values after a finite transaction identifier passes the end of its numeric range.",
  "note": "Normal 32-bit transaction identifiers use modular ordering. Without limiting the age of retained row versions, an old insertion identifier can eventually appear to be in the future. Freezing preserves old committed rows without relying on their original identifier's normal ordering. [c1]\n\nAn epoch distinguishes successive cycles when retained with the low identifier. A 64-bit full identifier contains both components, while its 32-bit form loses the epoch. Identifier assignment order need not match transaction-start order. [c2]\n\nThe same low number alone cannot distinguish generations from different cycles. Comparing counters after restore also requires a trustworthy identity and history. [c3]",
  "related": [
    "serial-number-arithmetic",
    "write-ahead-log",
    "lost-write"
  ],
  "citations": [
    {
      "id": "c1",
      "title": "PostgreSQL 18 documentation: preventing transaction ID wraparound failures",
      "url": "https://www.postgresql.org/docs/18/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND",
      "accessed": "2026-10-18"
    },
    {
      "id": "c2",
      "title": "PostgreSQL 18 documentation: transactions and identifiers",
      "url": "https://www.postgresql.org/docs/18/transaction-id.html",
      "accessed": "2026-10-18"
    },
    {
      "id": "c3",
      "title": "Hesela: ordering storage generations across counter wrap",
      "url": "https://hesela.com/analyses/storage-generation-counter-wraparound/",
      "accessed": "2026-10-18"
    }
  ],
  "provenance": [
    "These lifecycle and epoch details describe PostgreSQL 18; other transaction and journal formats require their own rules. [c1] [c2]"
  ]
}
