
【PostgreSQL】max_connections の上限に達した際のエラー "too many clients already" を再現してみた
PostgreSQL では max_connections で同時接続数の上限が決まっており、
これを超えると新規接続が FATAL: sorry, too many clients already エラーで拒否されます。
今回はこの状況を再現してみました。実際にやることは以下です。
max_connectionsの値を変更- 接続数を上限まで埋める
pg_stat_activityで状況確認- 新規接続時にエラーが発生することを確認
pg_terminate_backendで特定の接続を終了- 新規接続ができるようになることを確認
(前提準備) PostgreSQL インストール
検証のための実行環境は EC2(AL2023)にインストールした PostgreSQL を使用しました。
EC2 に PostgreSQL をインストールする手順としては下記をご参照ください。
PostgreSQL 17.10 を利用し、検証していきます。
[ec2-user@ip-xx-xx-xx-xx ~]$ sudo -u postgres psql
psql (17.10)
Type "help" for help.
postgres=# SELECT version();
version
---------------------------------------------------------------------------------------------------------------
PostgreSQL 17.10 on x86_64-amazon-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
(1 row)
現状確認
まず pg_stat_activity ビューを用いて、検証前の状態を確認します。
pg_stat_activityはサーバプロセス毎に、そのプロセスの現在の活動に関連する情報を表示する1行を持ちます。
下記より、現在は 6 プロセス動いている状態です。
また、backend_type が client backend となるプロセスは 1 件のみであることが分かります。これがクライアント接続になります。
(この client backend プロセスが max_connections の上限に影響します。その他の autovacuum launcher や checkpointer などは PostgreSQL 内部プロセスであり、影響しません。)
postgres=# SELECT pid, usename, state, backend_type, query_start FROM pg_stat_activity;
pid | usename | state | backend_type | query_start
------+----------+--------+------------------------------+-------------------------------
2834 | postgres | active | client backend | 2026-08-05 00:38:07.754132+00
2827 | | | autovacuum launcher |
2828 | postgres | | logical replication launcher |
2823 | | | checkpointer |
2824 | | | background writer |
2826 | | | walwriter |
(6 rows)
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
1
(1 row)
クライアントから接続を増やすと `client backend` が増える
ちなみにターミナル B から以下のように新規接続をしてみます。
$ sudo -u postgres psql -d postgres
psql (17.10)
Type "help" for help.
postgres=#
その後、ターミナル A で改めて pg_stat_activity を確認すると、下記のように client backend が増えます。
postgres=# SELECT pid, usename, state, backend_type, query_start FROM pg_stat_activity;
pid | usename | state | backend_type | query_start
------+----------+--------+------------------------------+-------------------------------
2834 | postgres | active | client backend | 2026-08-05 01:05:40.604094+00
3635 | postgres | idle | client backend |
2827 | | | autovacuum launcher |
2828 | postgres | | logical replication launcher |
2823 | | | checkpointer |
2824 | | | background writer |
2826 | | | walwriter |
(7 rows)
以上より、backend_type = client backend はクライアントからの接続に対応していることが確認できました。
max_connections の変更
検証のため、max_connections の値をデフォルトの 100 から 10 に書き換えます。
max_connections (integer)
データベースサーバに同時接続する最大数を決定します。 デフォルトは典型的に100接続ですが、カーネルの設定が(initdbの過程で)それをサポートしていない場合、もっと少なくなることがあります。 このパラメータはサーバ起動時のみに設定可能です。
-- デフォルトでは 100 接続
postgres=# SHOW max_connections;
max_connections
-----------------
100
(1 row)
postgres=# exit;
postgresql.conf ファイルを編集し、max_connections の値を 10 に書き換えます。
$ sudo vi /var/lib/pgsql/data/postgresql.conf
# vim の使い方メモ
# 1. /max_connections と入力してEnter → 該当行にジャンプ
# 2. その行で数値を書き換え
# 3. :wq と入力してEnter → 保存して終了
# 以下のように書き換え
max_connections = 10
# 10接続になったかの確認
$ sudo cat /var/lib/pgsql/data/postgresql.conf | grep 'max_connections'
max_connections = 10 # (change requires restart)
パラメータを反映させるために PostgreSQL サーバーを再起動します。
$ sudo systemctl restart postgresql
再起動後、改めて PostgreSQL サーバーに接続し max_connections が 10 になっていれば OK です。
postgres=# SHOW max_connections;
max_connections
-----------------
10
(1 row)
10接続した時にどうなるか確認する
max_connections=10 の状態で、実際に接続を埋めていきます。
検証前は以下の通り、client backend は自分が接続する 1 接続のみの状態です。
postgres=# SELECT pid, usename, state, backend_type, query_start FROM pg_stat_activity;
pid | usename | state | backend_type | query_start
------+----------+--------+------------------------------+------------------------------
5347 | postgres | active | client backend | 2026-08-05 01:32:22.39425+00
2827 | | | autovacuum launcher |
2828 | postgres | | logical replication launcher |
2823 | | | checkpointer |
2824 | | | background writer |
2826 | | | walwriter |
(6 rows)
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
1
(1 row)
続いて、ターミナル B で 9 本の接続をバックグラウンドで一括生成します。
BEGIN でトランザクションを開始した状態のまま pg_sleep(600) を実行し、接続を 600 秒間占有させます。
末尾の & によって各コマンドをバックグラウンドで実行しているため、9 本の接続をほぼ同時に作ることができます。
$ for i in $(seq 1 9); do
sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
done
# 実行結果
[1] 5410
[2] 5411
[3] 5412
[4] 5413
[5] 5414
[6] 5415
[7] 5416
[8] 5417
[9] 5418
# jobs コマンドで確認 -> 9 プロセスあり
$ jobs
[1] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[2] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[3] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[4] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[5] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[6] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[7] Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[8]- Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
[9]+ Running sudo -u postgres psql -d postgres -c "BEGIN; SELECT pg_sleep(600);" &
上記実行後、ターミナルA から pg_stat_activity を確認します。
下記の通り、接続が満杯(client backend が 10 本)になりました。
postgres=# SELECT pid, usename, state, backend_type, query_start FROM pg_stat_activity;
pid | usename | state | backend_type | query_start
------+----------+--------+------------------------------+-------------------------------
5483 | postgres | active | client backend | 2026-08-05 01:34:38.423142+00
5457 | postgres | active | client backend | 2026-08-05 01:34:38.373395+00
5347 | postgres | active | client backend | 2026-08-05 01:35:03.564196+00
5445 | postgres | active | client backend | 2026-08-05 01:34:38.341128+00
5450 | postgres | active | client backend | 2026-08-05 01:34:38.355533+00
5463 | postgres | active | client backend | 2026-08-05 01:34:38.388967+00
5480 | postgres | active | client backend | 2026-08-05 01:34:38.410182+00
5481 | postgres | active | client backend | 2026-08-05 01:34:38.417854+00
5462 | postgres | active | client backend | 2026-08-05 01:34:38.388401+00
5477 | postgres | active | client backend | 2026-08-05 01:34:38.419452+00
2827 | | | autovacuum launcher |
2828 | postgres | | logical replication launcher |
2823 | | | checkpointer |
2824 | | | background writer |
2826 | | | walwriter |
(15 rows)
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
10
(1 row)
この状態で、ターミナルBからさらに接続を試みてみます。
すると下記のエラーとなり、接続ができません。
$ sudo -u postgres psql -d postgres
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: sorry, too many clients already
pg_terminate_backend 関数を用いて client backend プロセスを 1 つ削除し、接続を 9 つにします。
postgres=# SELECT pg_terminate_backend(5445);
pg_terminate_backend
----------------------
t
(1 row)
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
9
(1 row)
pg_terminate_backend ( pid integer, timeout bigint DEFAULT 0 ) → boolean
バックエンドが指定したプロセスIDを持つセッションを終了させます。
再度、ターミナル B から新規接続を試みます。下記の通り、今度はエラーなく接続ができました。
$ sudo -u postgres psql -d postgres
psql (17.10)
Type "help" for help.
postgres=#
ターミナル A から確認した結果 client backend の数も 10 に戻ったことがわかります。
postgres=# SELECT pid, usename, state, backend_type, query_start FROM pg_stat_activity;
pid | usename | state | backend_type | query_start
------+----------+--------+------------------------------+-------------------------------
5483 | postgres | active | client backend | 2026-08-05 01:34:38.423142+00
5457 | postgres | active | client backend | 2026-08-05 01:34:38.373395+00
5347 | postgres | active | client backend | 2026-08-05 01:42:32.214567+00
5638 | postgres | idle | client backend |
5450 | postgres | active | client backend | 2026-08-05 01:34:38.355533+00
5463 | postgres | active | client backend | 2026-08-05 01:34:38.388967+00
5480 | postgres | active | client backend | 2026-08-05 01:34:38.410182+00
5481 | postgres | active | client backend | 2026-08-05 01:34:38.417854+00
5462 | postgres | active | client backend | 2026-08-05 01:34:38.388401+00
5477 | postgres | active | client backend | 2026-08-05 01:34:38.419452+00
2827 | | | autovacuum launcher |
2828 | postgres | | logical replication launcher |
2823 | | | checkpointer |
2824 | | | background writer |
2826 | | | walwriter |
(15 rows)
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
10
(1 row)
終わりに
今回は接続数の上限に達した際の挙動と、その対処方法を検証してみました。
検証してみて以下が把握できました。
max_connectionsの上限に達すると、新規接続はFATAL: sorry, too many clients alreadyエラーで拒否されるpg_stat_activityでbackend_type = client backendの件数を確認することで、現在の接続数を把握できる- 原因となっている接続は
pg_terminate_backendで強制終了させることができ、これにより新規接続を受け入れられる状態に復旧できる
実務でも「DBに繋がらない」という相談を受けた際、まず pg_stat_activity で状況を確認するのが第一歩になります。
本記事がどなたかのお役に立てば幸いです。
参考情報







