動画で読む
まず結論 — 「アプリ無改修」をどこまで信じるかが導入判断の核
PgDog は Postgres の前に挟むだけで水平スケールを足す、と謳う Rust 製の接続プロキシ(アプリと DB の間に立つ中継役)です。2026 年 6 月に Basis Set や YC などから 550 万ドルを調達したと資金調達の告知で発表し、本番群で毎秒 200 万クエリをさばくと書いています。売り文句は「同じ Postgres の前にプロキシを置くだけで水平にスケールする」。つまりアプリのコードを書き換えずに、シャーディング(データを複数台に分割する手法)まで足せるという主張です。
ただ運用者として最初にやるべきは、この「無改修」を額面どおり受け取らないことです。プーリングだけなら確かに無改修に近い。けれどシャーディングまで踏み込むと、無改修で済む場面と、クエリの書き方や ID 設計に手が入る場面がはっきり分かれます。どこまでが本当に無改修で、どこから自分のアプリ側に影響が出るのか。その線引きこそが導入判断の本題です。
PgDog が一度に引き受ける三つの仕事
PgDog は接続プーリング・シャーディング・ロードバランシングという別々の三つを 1 プロセスで引き受けます。混ぜて理解すると判断を誤るので、まず分けて押さえます。GitHub の README と公式ドキュメントを読むと、この三層がそれぞれ独立して効くことが分かります。
プーリングは PgBouncer と同じトランザクション単位のプーリング(接続を取引ごとに使い回す方式)が基本です。違いは、PgDog が SET 文や startup option を自分で解釈してセッション状態を保つ点にあります。PgBouncer のトランザクションモードで SET 系が暴れた経験がある人には、ここが地味に効きます。セッションモードも持っているので、状態を握り続けたいアプリにも倒せます。
シャーディングは、ハッシュ・リスト・レンジ・スキーマの四方式を備えます。既定はハッシュで、シャーディングキー(分割の基準にする列)でハッシュを取って行を振り分けます。キーを含むクエリは 1 台に直行し、キーが無いクエリは全シャードに投げて結果をメモリ上で組み立てます。ロードバランシングは round-robin / random / least-active の三戦略で、書き込みはプライマリへ、読み取りはレプリカへ、というルーティングをクエリを解析して自動でやります。ヘルスチェックで不調なホストを自動的に外す挙動もあり、この「壊れたものを黙って外す」発想は、以前書いた Linear の同期エンジンを読んだ記事 で触れた、速さは仕掛けの積み重ねだという話と地続きです。
導入する / しないの判断軸 — まず「シャーディングが要るのか」を分ける
判断の出発点は「自分が解きたいのはどのスケール問題か」を一段分けることです。スケールと一括りにすると過剰投入します。実際には接続数・読み取り量・書き込みと総容量の三つは別問題で、PgDog が本領を出すのは三つ目だけです。
接続数が苦しいだけなら、プーラーで足ります。PgBouncer や PgCat で十分なことも多く、そこに PgDog を入れる理由は SET の扱いやすさくらいです。読み取りが苦しいなら、レプリカを増やしてロードバランシングで散らすのが先で、これもシャーディングは要りません。書き込みスループットと総データ量が単機の限界に当たって初めて、シャーディングが選択肢に乗ります。MongoDB や DynamoDB が選ばれる理由の多くは「Postgres のスケール問題」だ、と PgDog 側は言いますが、その問題に当たっていない段階でシャーディングを足すのは、要らない複雑さの前借りです。
私はこの手の判断を、入れる前に「やめる条件」を先に決める癖で捌いています。始める前にやめ方を決める運用 に書いたとおりで、シャーディングなら「書き込み TPS がこの線を超えたら入れる、超えないうちは入れない」を先に紙に書く。勘で「そろそろ要りそう」と入れない。判断を測定に寄せる話は 測ってから自動化する記事 と同じ枠組みです。新しい道具が来ても、入れる/入れないの決め方は変わりません。
運用上の落とし穴 — cross-shard とバージョンの若さ
落とし穴は二つあります。一つはクロスシャードクエリ(複数シャードにまたがる問い合わせ)の挙動、もう一つはプロダクトの若さです。どちらも「無改修」の幻想を冷ます現実です。
クロスシャードは、シャーディングキーを含まないクエリが全シャードに展開され、結果が PgDog のメモリ上で組み立てられる仕組みです。多くのケースは動きますが、サブクエリや CTE(共通テーブル式、WITH で名前を付ける一時的な問い合わせ)は全シャードで同一に実行され、集計やソートの一部にはクロスシャード文脈での制約が残ります。ここを知らずに「キーの無い重い集計」を投げると、全台にファンアウトして遅い、という事故に直結します。私が検証環境で踏んだのも近い話で、シャーディングキーを WHERE に入れ忘れた COUNT を 1 本投げただけで、4 シャード全部に同じクエリが飛び、ローカルの単機なら数ミリ秒の照会が体感で跳ね上がりました。原因はプロキシではなく、キーを書き忘れた自分のクエリです。「無改修」と言われても、クエリにキーを乗せる規律はアプリ側の宿題として残るわけです。
もう一つはバージョンの若さです。執筆時点の最新は v0.1.43 で、まだ 0.1 系です。GitHub スターは伸びていて Docker pull も 140 万超とはいえ、メジャー前のプロダクトを基幹 DB の前段に挟む重さは正直に見積もるべきです。ライセンスが AGPL-3.0 である点も、社内利用なら問題なくても配布形態によっては法務確認が要ります。二相コミット(2PC、複数 DB を 1 つの取引として確定する仕組み)でクロスシャードの整合を取れるのは強みですが、整合の代償としての遅延も込みで見ておく。動いている本番に黙って挟む道具ではありません。
私ならどう入れるか — 段階導入の順序を決めておく
結論を先に言うと、私なら一度に全部は入れません。プーラー → 読み取りレプリカのロードバランシング → シャーディングの順で、効果と可逆性の高いものから段階的に入れます。
最初はトランザクションプーリングだけを差し込み、接続数の頭打ちを緩める。ここは可逆性が高く、外すのも簡単です。次に読み取りが苦しければレプリカを足してロードバランシングに乗せる。ここまではアプリへの影響がほぼ無く、まさに無改修の領域です。シャーディングは最後で、しかもステージングで「キー無しクエリ」を棚卸ししてから入れます。状態を一箇所に寄せる/散らすの設計判断は、以前 durable workflow の状態を SQLite に置く案を読んだ記事 でも引っかかった論点で、散らした瞬間に「全体を一度に見る」コストが上がる。シャーディングはその典型です。
余談ですが、PgDog という名前を最初に見たとき、私は一瞬 PgBouncer の親戚かと早合点しました。実際にはプーラーの顔をしたシャーダーで、力点はシャーディング側にあります。名前の犬っぽさに反して、扱いは番犬というより、放すと全シャードへ一斉に走っていく猟犬に近い。キーという首輪を付け忘れると、こちらの想定より遠くまで走ります。
よくある質問
- PgDog と PgBouncer は何が違いますか?
- PgBouncer は接続プーリングに特化したプロキシですが、PgDog はプーリングに加えてシャーディングとロードバランシングを 1 プロセスで担います。プーリングはどちらもトランザクション単位ですが、PgDog は SET 文や startup option を自分で解釈してセッション状態を保つ点が異なります。
- 本当にアプリのコードを変えずにシャーディングできますか?
- プーリングと読み取りレプリカへの分散までは、ほぼ無改修で入ります。ただしシャーディングでは、クエリにシャーディングキーを乗せないと全シャードへファンアウトして遅くなるため、キーを書く規律はアプリ側に残ります。完全な無改修ではない、と見ておくのが安全です。
- クロスシャードのクエリはどこまで動きますか?
- シャーディングキーを含まないクエリは全シャードに展開され、結果が PgDog のメモリ上で組み立てられます。多くは動きますが、サブクエリや CTE は全シャードで同一に実行され、集計やソートの一部に制約が残ります。重い集計をキー無しで投げると全台にファンアウトする点に注意が必要です。
- 本番に導入する前に確認すべきことは何ですか?
- 執筆時点で v0.1.43 とメジャー前である点、ライセンスが AGPL-3.0 である点、そして二相コミットによる整合の代償としての遅延を見積もることです。私ならプーラー、レプリカ分散、シャーディングの順に可逆性の高いものから段階導入し、シャーディング前にキー無しクエリを棚卸しします。