この記事は、PostgreSQL プロジェクトの公式ドキュメントと、各メジャー リリース後に公開された 2 つの技術分析、Microsoft Tech Community (Azure Database for PostgreSQL チーム) および Crunchy Data に基づいています。以下の図は当社が再現したベンチマークではありません。データがサードパーティから提供された場合は、その出典と日付とともにそれを示します。独自の測定に適用する方法論については、ベンチマーク方法論の柱を参照してください。
- Postgres 17 の主な利点は、VACUUM (TidStore 構造) のメモリのオーバーホールであり、これにより、約 1 GB の古い上限が削除されます。公式リリースノートによると、場合によってはメモリ使用量が最大 20 分の 1 に削減されるとのことです。
- Postgres 17 では、トランザクション スナップショットの計算における競合も軽減され、特にマルチコア ハードウェア上の同時実行性の高いインスタンスにメリットがあります。
- Postgres 18 (2025 年 9 月下旬) では、特に高遅延ストレージ向けに、いくつかのメジャー リリースで最も構造的なアーキテクチャの変更である非同期 I/O (AIO) が導入されています。
- Postgres 18 では、複数列 B ツリー インデックスでのスキップ スキャン、デフォルトで仮想生成された列、認証用の OAuth 2.0 サポートも追加されています。
- Aurabase は現在、実稼働環境で Postgres 16.15 を実行しています。これはコードで検証されています。遅延ではなく、CloudNativePG でのメジャー バージョン アップグレードの不可逆性に関連する文書化された選択です。
Postgres 16、17、18 で実際に何が変わるのか
3 つのバージョンは、単一の全体的なパフォーマンス数値によって区別されるわけではありません。それぞれがアーキテクチャの特定の点を修正し、毎回異なる対象者を対象としています。Postgres 17 では大規模なテーブル、Postgres 18 では高遅延ストレージです。以下の表は、各プロジェクトの詳細に入る前に、検証可能な事実をすべて日付とともに要約したものです。
| バージョン | PostgreSQL 16 | PostgreSQL 17 | PostgreSQL 18 |
|---|---|---|---|
| 発売日 | 2023 年 9 月 14 日 | 2024 年 9 月 26 日 | 2025年9月末 |
| 大きなテーブルでの VACUUM | 配列内のデッドタプル、メモリ上限 ≈ 1 GB | TidStore 構造 (基数ツリー)、上げ天井 | 17で導入された構造を継承 |
| 入出力 | 同期、ブロックごと | ANALYZEおよびシーケンシャルスキャンのためのストリーミングI/O | 汎用非同期 I/O (AIO)、構成可能な io_method |
| 同時接続数 | スナップショット計算に関する既知の競合 | 競合の減少 (GetSnapshotData の最適化) | 17 で導入された利点を継承 |
| 複数列の B ツリー インデックス | 先頭列がフィルタにない場合はスキャンを完了する | Postgres 16と同じ | スキップスキャン:部分スキャン可能 |
| 生成された列 | 保存のみ | Postgres 16と同じ | VIRTUAL が追加され、デフォルトの動作になります |
| 認証 | スクラム、LDAP、証明書 | Postgres 16と同じ | + OAuth 2.0 (RFC 8628、デバイスフロー) |
出典: PostgreSQL プロジェクトの公式リリース ノート (postgresql.org)。各メジャー リリース後に Microsoft Tech Community および Crunchy Data によって公開された分析と相互参照されています。 2026 年 8 月 24 日にアクセス。
VACUUM のメモリのオーバーホールは大きなテーブルにとって大きな変革をもたらします
Postgres 17 より前では、VACUUM はクリーンアップするデッドタプルのリストを maintenance_work_memのサイズの単純な配列に保存していました。問題は計算の速度ではなく、構造自体にありました。このテーブルは、それを超えてどれだけ構成しても、1 GB 付近で頭打ちになりました。約 1 億 7,800 万を超えるデッド行があるテーブルでは、VACUUM は複数のパスでループし、各パスでインデックス全体を再読み取りする必要がありました。
Postgres 17 は、この配列を TidStore と呼ばれる構造に置き換えます。これは、タプル識別子の保存に必要なスペースを大幅に圧縮する適応基数ツリーです。プロジェクトの公式リリースノートによると、古い構造に伴う人工的な天井がなければ、VACUUM によって使用されるメモリが場合によっては最大 20 分の 1 に削減されることが示されています。出典: PostgreSQL 17 公式リリース ノート、postgresql.org、2024 年 9 月 26 日。Microsoft Tech Community と Crunchy Data はそれぞれ、リリース直後にこの変更の技術分析を公開しました。どちらも、高い削除率または更新率を伴う、数億行のテーブルに対する具体的な関心を裏付けています。
このプロジェクトは主に、削除または更新率が高い大規模なテーブルという特定のシナリオでメリットをもたらします。 VACUUM は、利用可能なメモリが不足していたため、以前は複数のパスで実行されていました。小さなテーブル、または主に読み取り負荷の場合、ゲインはわずかなままであるか、目に見えないことさえあります。
高同時接続での競合の減少
2 番目の Postgres 17 プロジェクトは、トランザクション スナップショットの計算という、より慎重な点に触れています。 Postgres の MVCC 可視性ルールを適用するには、各クエリで他のトランザクションが進行中であることを知る必要があります。多数のコアとアクティブな接続を備えたマシンでは、この計算により共有内部構造で競合が発生しました。これは、プロジェクトの貢献者によって長い間文書化されてきたボトルネックです。
Postgres 17 では、この競合が軽減されます。この効果は主に、マルチコア ハードウェア上で同時にアクティブな接続が多数存在する、同時実行性の高いインスタンスで測定されます。同時実行負荷が低い場合、Postgres 16 との違いはわずかなままです。これはスケーラビリティ プロジェクトであり、分離されたリクエストごとのレイテンシーの削減ではありません。
この利点は接続プーラーに取って代わるものではなく、単に内部コストを削減するだけです。アクティブな接続の数がすでにボトルネックになっている場合は、メジャー バージョンは後回しになります。 max_connections チューニング ガイド および PgBouncer トランザクション モードの比較 では、この主題について詳しく説明しています。
非同期 I/O: ここ数年で最も重大なアーキテクチャの変更
2025 年 9 月末にリリースされた Postgres 18 は、より構造的な問題に対処しています。それまでは、Postgres ディスクの読み取りごとに、それを要求したプロセスがブロックされていました。新しい非同期入出力 (AIO) サブシステムにより、プロセスは複数の読み取りを並行して開始し、それぞれの読み取りを順番に待つのではなく、読み取りが完了するまで作業を続けることができます。
io_method パラメータは、この動作を制御します: worker (I/O 専用プロセス、デフォルト)、または Postgres がこのサポートを使用してコンパイルされた場合、Linux 上の io_uring です。シーケンシャル スキャン、ビットマップ ヒープ スキャン、および VACUUM は、特にローカル NVMe ではなく、ネットワーク ディスク、クラウド ボリュームなどの高遅延ストレージで最初に恩恵を受けます。
マネージド Postgres 製品を提供する PlanetScale は、この I/O の変更に焦点を当てた独自の Postgres 17 と 18 の比較を公開しました。これらは独自のインフラストラクチャでの測定値であり、私たちがここで独自に再現した数値ではありません。これは、普遍的なパーセンテージとしてではなく、その主題が実際の負荷でテストする価値があるというシグナルとして受け取ってください。
Postgres 18 の一般化された AIO は、単独の変更ではなく、Postgres 17 で開始されたプロジェクトを継続します。バージョン 17 ではすでにストリーミング I/O インターフェイスが導入されていましたが、ANALYZE と順次スキャンに限定されていました。 Postgres 18 は、これと同じロジックを、VACUUM やビットマップ ヒープ スキャンなど、より広い範囲の操作に拡張します。したがって、2 つのバージョンは、I/O に対する 2 つの別々の賭けとしてではなく、進行として解釈されます。
その他の重要な変更点
他の 3 つの Postgres 18 の変更は、実際のパフォーマンスに直接対処していないとしても、監視する価値があります。
複数列 B ツリー インデックスの スキップ スキャン を使用すると、クエリが先頭列でフィルターをかけない場合でも、Postgres で複合インデックスを使用できます。 Postgres 18 より前では、このシナリオではテーブルの完全なスキャン、または追加の専用インデックスの作成が必要になることがよくありました。
で生成された仮想列 (GENERATED ALWAYS AS (...) VIRTUAL) は、 STORED が指定されていない場合のデフォルトの動作になります。仮想列はディスクに書き込まれるのではなく読み取り時に計算されるため、ソース行が挿入または更新されるたびに書き込まれる量が削減されます。
Postgres 18 では、SCRAM、証明書、LDAP などの既存のメカニズムに加えて、認証側 (RFC 8628、デバイス フロー) で OAuth 2.0 のサポートがついに追加されました。すでに外部 OAuth/OIDC プロバイダーを介して ID を一元化している組織にとって重要なポイントです。
Aurabase が依然として Postgres 16 で実行される理由と、この選択を変えるものは何ですか
Aurabase では、テナントデータベースは現在、Postgres 17 ではなく 16.15 で実行されています。これはリポジトリで直接確認できます。参照 CNPG イメージ (docker/Postgres.CNPG.Dockerfile) は、ダイジェストによって固定された ghcr.io/cloudnative-pg/postgresql:16-standard-bookwormから始まり、共有層 (docker/Postgres.Dockerfile) と同じメジャー バージョンです。 2026 年 8 月 24 日に確認。
コードにはその理由も記載されています。 k8s_tenant.rs の修正コメントでは、以前のフォールバックが誤って postgresql:17.2を指していたことが説明されています。当時、標準イメージには pgvector が含まれないという理由が示されていましたが、検証の結果、誤りであることが判明しました。どちらのイメージにも、フリート クラスターで測定された pgvector: 17.2 では 0.8.0、16-standard-bookworm では 0.8.5 があります。
コメント自体に記載されている本当のリスクは別の場所にあります。CloudNativePG では、クラスターが作成された後のメジャー バージョンのダウングレードは禁止されています。 Postgres 17 で誤ってプロビジョニングされたフリートは元に戻せませんが、Aurabase でエンドツーエンドで検証されたものはすべて Postgres 16 で行われました。
これは Postgres 17 自体についての判断ではありません。これは運用上の慎重さのポリシーであり、エンドツーエンドの検証が完了するまで実稼働フリートをメジャー バージョンに切り替えないでください。同じ理由が、CloudNativePG または同等の Kubernetes オペレーターを介して Postgres を管理するすべてのチームに当てはまります。問題は、期待されるパフォーマンスの向上だけではなく、何か問題が発生した場合の復帰経路でもあります。
PostgreSQL ではメジャー バージョンのダウングレードは提供されていません。 pg_upgrade は一方向のみに移行し、CloudNativePG はオペレーターのレベルで同じ制約を適用します。元に戻す唯一の方法は、更新前からバックアップを復元するか、古いバージョンの新しいインスタンスから開始することです。
今すぐ Postgres 17 または 18 に移行する必要がありますか?
3 つの基準により、普遍的な数字を待たずに決定することができます。まず、最大のテーブルのサイズと変更率です。VACUUM がすでに複数のパスで実行されている場合は、Postgres 17 メモリ ワークサイトがこのケースに直接適用されます。次に、ストレージ: 低遅延のローカル SSD では、Postgres 18 の非同期 I/O はネットワーク ボリュームよりも提供されます。最後に、戻ります。大規模なダウングレードを禁止している事業者では、最初に使い捨て環境でテストすることは、オプションの予防策ではありません。
具体的には、Kubernetes オペレーターが管理するすべてのフリートに同じルールが適用されます。まずターゲット リリースでテスト クラスターをプロビジョニングし、次にその上で本番環境を表す負荷を再生します。リリース ノートを読むだけではなく、このテストがエンドツーエンドで検証された後にのみ、実際のクラスターに触れてください。この種の変更を吸収するために専用ベースと共有ベースのどちらを選択するかについての決定も考慮している場合は、記事 専用ベースと共有ベース でこの角度から検討します。
最もよく聞かれること
パフォーマンスは可逆性より重要です
Postgres 16、17、18 のいずれを選択するかは、単にどのバージョンが「速い」かということだけではありません。 Postgres 17 では、大規模なテーブルにおける実際の構造的な VACUUM 問題が修正され、高い同時実行時の競合が軽減されます。 Postgres 18 では非同期 I/O がさらに進化しており、一般化する前に実際の負荷とストレージでテストする必要があるアーキテクチャ上の変更です。
最も忘れられがちな基準はパフォーマンスではなく、可逆性です。 CloudNativePG のようなオペレーターでは、メジャー バージョンのアップグレードは後で取り消されません。実稼働フリートを切り替える前に、実際に問題となるのは、期待される利益だけではなく、テストが失敗した場合の復帰経路でもあります。このバージョンのアップグレードを準備している場合は、本番環境での Postgres チューニング チェックリスト に、メジャー バージョンの変更後に再検証する設定が詳しく記載されています。