🐘 スタートアップのためのPostgresサバイバルガイド — 2万行未満はseq scanで瞬時、autovacuum 1時間超は調査、の実務閾値集
PostgresベースのタスクキューHatchetが運用知見を一挙公開しHN 499ポイント。接続プーリング・timestamptz常用・複合インデックスのORDER BY列は末尾・pg_repackまで、「困ってから調べる」を先回りする実務ガイドの要点と、HNで足された補足を整理する。
Postgresの運用知識は、困ったときに初めて検索する類のものだ。autovacuumという単語を真剣に読むのは、たいてい何かが詰まった夜になる。
そこを先回りしてくれるガイドが出た。PostgresベースのタスクキューHatchet(YC W24)の共同創業者Alexander Belangerが7月22日に公開した「The startup’s Postgres survival guide」。HNで499ポイント・218コメント。Postgresを限界まで酷使するのが商売の会社が、その運用ノウハウを閾値の数字ごと置いていった。
「いくつになったら動くか」が書いてある
この手のガイドは総論で終わりがちだが、これは判断の数字が具体的だ。拾っておきたいものを並べる。
2万行未満のテーブルにインデックスは(ほぼ)要らない。seq scanでほぼ瞬時に返るから、というのが記事の言い分。インデックスを貼る前にまず行数を見る、という順番が身につくだけで無駄なメンテナンスコストが減る。
autovacuumが1時間超走っていたら調査対象。放置の先にあるのはXID周回(トランザクションIDの使い果たし。Postgresが最悪書き込み停止する)で、HNでは「これはダッシュボードではなくPager通知に繋げ」という補足が入っていた。ブロート(死んだ行の膨張)の掃除にはpg_repackを挙げている。
複合インデックスではORDER BY対象の列を末尾に置く。WHEREで絞ってからソートに使う、というインデックスの読み進め方をそのまま列順にする話で、知っていれば当たり前、知らないとEXPLAIN ANALYZEとにらめっこするやつだ。ちなみに実行計画の可視化にはexplain.dalibo.comを勧めている。
スキーマ設計は迷いを消す断言型で、常にtimestamptz(タイムゾーンなしのtimestampを選ぶ理由は実務にほぼない)、主キー必須、低ボリュームなテーブルにはカスケード削除付きの外部キー。接続まわりはアプリ内プール(Goならpgxpool)+外部プーラーにPgBouncer。PgBouncerがSO_REUSEPORTで4倍になった話は先日書いた通りで、この layering は2026年でも定番のままだ。
コメント欄が続編になっている
499ポイント集めたガイドの常で、HNのコメント欄自体が増補版になっていた。時系列データのインデックスにはBRIN(ブロック単位の軽量インデックス)、IDにはUUIDv7。SELECT FOR UPDATEは分離レベルSERIALIZABLEでないと競合を防ぎきれないという渋い指摘もある。
面白かったのはバックアップ論争だ。pgBackRestでPITR(任意時点復元)を組む派と、「pg_dump+zstd+S3で十分」派が真っ向からぶつかっていて、どちらも一理ある。復元の練習をしたことがないバックアップは存在しないのと同じ、という点だけは両派一致していた。耳が痛い人は多いはずだ。
なおこの記事、Hatchetにとっては「Postgresで十分戦える」という自社製品の思想の宣伝でもある。ただ製品への誘導はほぼなく、内容は汎用だ。ポジショントークの中では最も実用的な部類だと思う。
日本語圏にこの「一気通貫」型はない
Qiitaにはautovacuumチューニングの定番記事が複数あるし、PgBouncer単体の解説も断片的にはある。ただ「接続プールからスキーマ設計、インデックス、バキューム、パーティショニングまでをスタートアップ視点で一枚に」という型の日本語記事は見当たらなかった。断片は揃っているのに地図がない状態で、これは翻訳ではなく編集の空白だ。
自分はといえば、業務OSのSoTをMarkdownファイルにして「DBを持たない」選択をした側の人間なので、このガイドを読みながら「持ったら持ったでこの覚悟が要るのか」と改めて思った。DBは強力だが、飼うと世話がある。あなたのプロジェクトの規模で、この世話は割に合っていますか。