
【PostgreSQL】接続1つあたりのメモリ消費量を free コマンドで確認してみた
PostgreSQLでは、接続数が増えるとメモリ消費も増えると言われています。
今回は実際にどれくらいメモリを消費するのか、1接続あたりの量を検証してみました。
具体的にやったことは以下です。
- EC2 (t3.micro) に PostgreSQL をインストール
- 接続を増やす前(0 接続時)に
free -hでメモリの内訳を確認 - pg_sleep 関数を用いて、常時接続を作成
- 接続数を増やしながら free -h でメモリ使用量の変化を確認
上記を実施し、最終的に 1 接続でどのくらいのメモリ消費が発生したのか求めてみます。(あくまで参考値)
いきなりまとめ
0接続、51 接続、100 接続と増やしていき利用可能なメモリ量を確認。
その結果、SELECT などの何も処理をしていない接続(pg_sleep のみ)でも 1 接続あたり 4.4〜4.6 MiB 程度の消費がなされることがわかりました。
| 接続数 | available | 差分 | 1接続あたり |
|---|---|---|---|
| 0 | 605Mi | - | - |
| 51 | 375Mi | -230Mi | 約4.5Mi |
| 100 | 161Mi | -214Mi | 約4.4Mi |
接続あたりのメモリ消費量の求め方
- 230 Mi / 51(接続) = 4.509...
- 214 Mi / 49(接続) = 4.367...
(前提準備) PostgreSQL インストール
検証のための実行環境は EC2(AL2023, t3.micro)にインストールした PostgreSQL を使用しました。
EC2 に PostgreSQL をインストールする手順としては下記をご参照ください。
[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)
ゼロ接続時のメモリ内訳を確認
free -h でメモリ内訳を確認します。
現在利用可能なメモリ量を示す available は 605 MiB となっています。
$ free -h
total used free shared buff/cache available
Mem: 912Mi 160Mi 429Mi 14Mi 322Mi 605Mi
Swap: 0B 0B 0B
free コマンドについて
free コマンドはシステム内のメモリ内訳を調べるコマンドです。man コマンドを参照。-h は人が読みやすいように表示してくれるオプションです。
$ man free
DESCRIPTION
free displays the total amount of free and used physical and swap memory in the system, as well as the buffers and
caches used by the kernel. The information is gathered by parsing /proc/meminfo.
...
available
Estimation of how much memory is available for starting new applications, without swapping. Unlike the data
provided by the cache or free fields, this field takes into account page cache and also that not all re‐
claimable memory slabs will be reclaimed due to items being in use (MemAvailable in /proc/meminfo, available on
kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as free)
...
-h, --human
Show all output fields automatically scaled to shortest three digit unit and display the units of print out.
Following units are used.
...
B = bytes
Ki = kibibyte
Mi = mebibyte
Gi = gibibyte
また、以下の外部記事もわかりやすいので、man コマンドの結果と併せて確認してください。
PostgreSQL 接続を増やす
ターミナルを 1 つ追加し(ターミナルBと呼ぶ)、そこから PostgreSQL の現在の状態を確認。
現状は接続が 1 つです。(クエリを実行している自分の接続のみ)
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
1
(1 row)
続いてターミナル A から、
pg_sleep(600) を使い、600 秒間スリープ状態を保つ接続を 50 個、
バックグラウンドで同時に作成します。
$ for i in {1..50}; do
sudo -u postgres psql -d postgres -c "SELECT pg_sleep(600);" &
done
ターミナル B から接続状況を確認
50接続増えたので、現在は 51 接続になっています。
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
51
(1 row)
接続を増やした後のメモリ内訳
51 接続を持っている状態で、ターミナル A からメモリ使用率に変化があったか確認。
その結果、available の値が 605MiB → 375 MiB に減少しました。
$ free -h
total used free shared buff/cache available
Mem: 912Mi 390Mi 184Mi 15Mi 338Mi 375Mi
Swap: 0B 0B 0B
さらに接続を増やす
PostgreSQL の max_connections のデフォルト値である 100 接続まで増やしてみましょう。
現在 51 接続既にあるので、49 接続増やします。
$ for i in {1..49}; do sudo -u postgres psql -d postgres -c "SELECT pg_sleep(600);" & done
ターミナル B から確認。100 接続になりました。
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
count
-------
100
(1 row)
メモリ内訳を確認します。available 値は 375 MiB → 161 MiB に減少しました。
$ free -h
total used free shared buff/cache available
Mem: 912Mi 603Mi 67Mi 15Mi 241Mi 161Mi
Swap: 0B 0B 0B
まとめ
結果は以下となりました。
| 接続数 | available | 差分 | 1接続あたり |
|---|---|---|---|
| 0 | 605Mi | - | - |
| 51 | 375Mi | -230Mi | 約4.5Mi |
| 100 | 161Mi | -214Mi | 約4.4Mi |
0 → 51接続の場合
差分: 605Mi - 375Mi = 230Mi
1接続あたり: 230Mi ÷ 51接続 ≒ 4.5Mi
51 → 100接続の場合
差分: 375Mi - 161Mi = 214Mi
1接続あたり: 214Mi ÷ 49接続 ≒ 4.4Mi
上記より、本検証では 1 接続あたり概ね 4.4〜4.5 MiB 程度のメモリを消費していることがわかりました。
余談ですが、100 接続で available が残り 161 MiB であることを踏まえると、単純計算で 130〜140 接続ほどで本値が 0 になりメモリが厳しくなる可能性がありますね(あくまで計算上の話)。
終わりに
今回の検証では、PostgreSQLの接続数がメモリに与える影響を確認しました。
- pg_sleep 関数のみを実行した接続でも 1 つあたり、約4.4〜4.5MiBのメモリを消費する
- max_connectionsのデフォルト値(100)まで接続すると、t3.microのような
小さいインスタンスではavailableが161MiBまで減少し、メモリの余裕が
ほとんどなくなることが確認できました
SELECT クエリなどを実行していない接続であっても、軽視できないメモリコストがあることがわかりました。
アプリケーション側でコネクションプーリング(PgBouncerやRDS Proxyなど)を活用し、不要な接続を残さない設計が重要だと言えそうです。
本記事がどなたかのお役に立てば幸いです。
参考情報






