【PostgreSQL】接続1つあたりのメモリ消費量を free コマンドで確認してみた

【PostgreSQL】接続1つあたりのメモリ消費量を free コマンドで確認してみた

PostgreSQL の接続数がメモリにどの程度の影響を与えるのか、実際に検証してみました。 何もしていない接続(pg_sleep 関数のみ)におけるメモリ消費量を明らかにします。
2026.08.27

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 をインストールする手順としては下記をご参照ください。

https://dev.classmethod.jp/articles/installing-postgresql-on-ec2-al2023/

[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 コマンドの結果と併せて確認してください。
https://milestone-of-se.nesuke.com/sv-basic/linux-basic/free-command/

PostgreSQL 接続を増やす

ターミナルを 1 つ追加し(ターミナルBと呼ぶ)、そこから PostgreSQL の現在の状態を確認。
現状は接続が 1 つです。(クエリを実行している自分の接続のみ)

ターミナル B
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
 count 
-------
     1
(1 row)

続いてターミナル A から、
pg_sleep(600) を使い、600 秒間スリープ状態を保つ接続を 50 個、
バックグラウンドで同時に作成します。

ターミナル A
$ for i in {1..50}; do
  sudo -u postgres psql -d postgres -c "SELECT pg_sleep(600);" &
done

ターミナル B から接続状況を確認
50接続増えたので、現在は 51 接続になっています。

ターミナル B
postgres=# SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';
 count 
-------
    51
(1 row)

接続を増やした後のメモリ内訳

51 接続を持っている状態で、ターミナル A からメモリ使用率に変化があったか確認。
その結果、available の値が 605MiB → 375 MiB に減少しました。

ターミナル A
$ 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 接続増やします。

ターミナル A
$ for i in {1..49}; do   sudo -u postgres psql -d postgres -c "SELECT pg_sleep(600);" & done

ターミナル B から確認。100 接続になりました。

ターミナル B
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など)を活用し、不要な接続を残さない設計が重要だと言えそうです。

本記事がどなたかのお役に立てば幸いです。

参考情報

https://dev.classmethod.jp/articles/installing-postgresql-on-ec2-al2023/
https://milestone-of-se.nesuke.com/sv-basic/linux-basic/free-command/

この記事をシェアする

関連記事