PostgreSQL Field Guide

PostgreSQL 17 features and upgrade notes

PostgreSQL 17 (GA 2024-09) highlights — streaming I/O, failover replication slots, pg_createsubscriber, MERGE RETURNING, JSON_TABLE, incremental backup — with upgrade notes

PostgreSQL 17 reached GA on 2024-09-26 and is supported until 2029-11-08. As of this review date the current minor is 17.10; see the version and support policy for the live support snapshot. Every feature claim below is checked against the PostgreSQL 17 release notes.

Streaming I/O framework

PostgreSQL 17 introduced a streaming I/O interface for sequential reads. Instead of issuing one block request at a time, the executor can keep a stream of read requests in flight, which improves the performance of sequential scans and related bulk reads. PostgreSQL 18 builds directly on this framework for its asynchronous I/O subsystem, so the work done in 17 is the foundation for the larger I/O gains in PostgreSQL 18.

Logical replication: failover slots and pg_createsubscriber

  • Replication slots can survive failover. The replication protocol gained a failover property, and sync_replication_slots lets a standby synchronize failover-enabled logical slots, so logical subscribers can keep streaming after the publisher fails over to a standby.
  • pg_createsubscriber converts a physical standby into a logical replica. This is the standard tool for turning a streaming-replication copy into a logical subscriber, and it is a practical path for low-downtime major-version migration.

MERGE: WHEN NOT MATCHED BY SOURCE and RETURNING

PostgreSQL 17 extended MERGE with WHEN NOT MATCHED BY SOURCE actions and a RETURNING clause (including the merge_action() function, which reports which DML action each row took):

MERGE INTO target USING source ON source.id = target.id
WHEN MATCHED AND target.deleted = false THEN
  UPDATE SET ...
WHEN NOT MATCHED THEN
  INSERT ...
WHEN NOT MATCHED BY SOURCE THEN
  DELETE
RETURNING merge_action(), *;

Together these make MERGE usable for full synchronization workloads, not only upserts.

JSON_TABLE

PostgreSQL 17 added the SQL-standard JSON_TABLE() function, which projects JSON data into a relational rowset:

SELECT * FROM JSON_TABLE(jsonb_col, '$.items[*]' COLUMNS (
  id bigint PATH '$.id',
  name text PATH '$.name'
)) AS t;

This removes a class of hand-written jsonb_to_recordset and lateral-extraction queries when JSON documents need to be joined, filtered, or aggregated as rows.

Incremental backup with pg_basebackup

PostgreSQL 17 added incremental file-system backup. pg_basebackup --incremental produces a backup containing only the blocks changed relative to a previous backup's manifest, and pg_combinebackup reconstructs a full backup from a full plus incremental chain:

pg_basebackup --incremental=/path/to/backup_manifest -D ./backup_inc

For large databases this shortens backup windows and reduces backup storage, at the cost of a combine step during restore.

Configurable SLRU buffer pools

The SLRU caches behind subtransactions, commit timestamps, and related subsystems are now individually sizable through settings such as subtransaction_buffers and commit_timestamp_buffers, and by default they scale with shared_buffers. Previously these caches were fixed-size and could become a contention point under heavy concurrency.

Also in PostgreSQL 17

  • COPY ... ON_ERROR ignore skips malformed input rows instead of aborting the whole copy. (PostgreSQL 18 later added REJECT_LIMIT to bound how many rows may be discarded.)
  • PostgreSQL 17 removed the old_snapshot_threshold setting, the adminpack contrib extension, and several other long-deprecated pieces — check the release notes if you migrate from a much older major.

Upgrade notes for PostgreSQL 17

  • A major upgrade requires pg_upgrade, dump/restore, or logical replication; the data directory is not compatible across majors. pg_createsubscriber (above) is the logical-replication route introduced in this version.
  • Read the release notes for every major you cross, not only the target version.
  • Monitoring queries may need updates: PostgreSQL 17 renamed several pg_stat_statements timing columns (for example blk_read_time to shared_blk_read_time), and pg_stat_bgwriter lost its buffers_backend/buffers_backend_fsync columns (redundant with pg_stat_io).
  • Verify each extension's PostgreSQL 17 support separately; extensions carry their own versions and upgrade scripts.

Pin the minor, rehearse the major

Run the current 17.x minor in production and rehearse any major upgrade on a restored copy of real data before scheduling a cutover. The general checklist lives in the version and support policy.

Version path

Sources

Last updated on

On this page