A PostgreSQL UPDATE normally creates a new physical row version. That MVCC behavior can also require fresh index entries, even when an application changes only a small non-key field. Heap-only tuple updates, commonly called HOT updates, avoid that index work under specific conditions by keeping successive row versions on one heap page and retaining the existing index reference.
HOT is therefore a property of a particular update, not a permanent table mode. Whether an update qualifies depends on the columns it changes and the free space available on the heap page that contains the current row version.
An index can keep pointing at the chain root
An ordinary non-HOT update creates a new heap tuple and requires index maintenance so index lookups can reach the new version. With HOT, PostgreSQL can place the new tuple version on the same heap page and connect the old version to it as part of a HOT chain.
The existing index entry continues to identify the original page item. An index scan reaches that item and follows the chain inside the heap page to find the row version that is visible to its MVCC snapshot. The newer heap-only tuple does not need a separate entry in each ordinary index.
This distinction matters because an UPDATE in PostgreSQL is not an in-place replacement of arbitrary tuple data. A new row version still exists. HOT changes the index-maintenance path and permits more local cleanup; it does not remove MVCC versioning.
Indexed columns set an eligibility boundary
For current PostgreSQL releases, a HOT update requires that the update not modify columns referenced by non-summarizing indexes. BRIN, the summarizing index method in core PostgreSQL, is treated separately and may still need summary maintenance.
Consider a table with an index on account_id and mutable columns such as status_note and last_seen_at. An update that changes only those non-indexed columns can satisfy the column condition for HOT. Changing account_id cannot use the same optimization because the old index key can no longer represent the new row value.
The condition extends beyond simple index key declarations. Columns used by index expressions or predicates can affect whether PostgreSQL may safely retain existing index references. The central constraint is that an index whose search semantics depend on changed data cannot simply keep its prior representation.
This also creates a storage consequence for schema design. Adding an index can change the update behavior of rows even when query plans remain otherwise similar. A column that was previously free to change during HOT updates may become part of the index-maintenance boundary.
Page space decides whether the chain can continue
Unchanged indexed data is not sufficient on its own. PostgreSQL also needs enough free space on the same heap page to store the new tuple version. If the page cannot accommodate it, the new version must move elsewhere and the update cannot use the normal HOT path.
Table fillfactor influences this condition. A lower fill factor leaves part of each heap page unused during initial insertion, creating room that later updates may consume. That can increase the opportunity for HOT updates on tables whose rows are modified repeatedly.
The reserved space is not free. Lower fill factor means fewer initial tuples per page, so the table can occupy more pages. The useful setting therefore depends on update patterns, tuple size, access locality, and the value of preserving same-page update space. HOT eligibility is one concrete effect to consider rather than a reason to reduce fill factor indiscriminately.
Pruning shortens obsolete HOT chains
Repeated HOT updates can produce several physical versions connected through one page. PostgreSQL does not need to preserve every intermediate version forever. Once an old version can no longer be visible to any relevant snapshot, page pruning can remove tuple data from obsolete chain members and reuse their line pointers.
The chain root has a special role because indexes may still reference its page item identifier. During pruning, PostgreSQL can convert that root item into a redirect toward the oldest remaining member needed by active visibility rules. Dead intermediate members can then be reclaimed without rewriting every index that still refers to the chain through the root.
This local pruning behavior is one reason HOT affects more than the immediate cost of inserting index tuples. It gives the heap a way to discard obsolete intermediate versions without waiting for ordinary index cleanup to remove corresponding entries, because those intermediate HOT versions never received ordinary index entries in the first place.
Statistics expose the optimization at table level
PostgreSQL records update counters in statistics views such as pg_stat_all_tables and pg_stat_user_tables. n_tup_upd counts updated rows, while n_tup_hot_upd records updates performed through HOT. Recent PostgreSQL releases also expose n_tup_newpage_upd for updates whose new tuple version was placed on a different heap page.
These counters describe observed execution rather than eligibility in the abstract. A table can have many updates to non-indexed columns yet show a modest HOT count when its pages lack room for new versions. Conversely, sufficient page space does not help an update that changes data required by a non-summarizing index.
The counters are cumulative statistics and should be interpreted over a relevant observation interval. A ratio taken from old accumulated activity can obscure a recent change in indexing, row width, or fill factor.
HOT connects index design with heap layout
Indexes are often evaluated from the read side: which predicates they support, which orderings they provide, and whether they permit index-only access. HOT adds a write-side interaction. Indexing another mutable column can make some updates require fresh index entries, while heap page density determines whether otherwise eligible updates can remain local.
That interaction is specific rather than mysterious. PostgreSQL can retain an index reference only while the indexed representation remains valid, and it can form the HOT chain only while the next tuple version fits on the same page. Those two constraints make HOT a useful lens for examining update-heavy tables: index definitions and physical heap space participate in the same update path.