2026年5月26日
2026年5月26日
Nginxのupstream keepaliveの設定方法|バックエンドとの接続を再利用する
Nginx をリバースプロキシやロードバランサーとして使うと、Nginx はクライアントからのリクエストごとにバックエンド(アプリケーションサーバーや PHP-FPM)へ接続します。upstream の keepalive を設定すると、使い終わった接続を閉じずに保持し、次のリクエストで使い回せるようになります。接続のたびに必要な TCP の接続処理(バックエンドが HTTPS なら TLS の接続処理も)が減り、バックエンド側に TIME_WAIT の接続がたまるのも抑えられます。
この記事の内容は、2026年10月時点の Nginx の公式ドキュメント(stable 1.30.6、mainline 1.31.8)で確認しています。
keepalive の数値は「秒数」ではない
最初に、間違えやすい点を整理します。upstream ブロックの keepalive に書く数値は、接続を保持する秒数ではなく、各ワーカープロセスが保持するアイドル接続の上限数です。
| ディレクティブ(upstream 内) | 意味 | 既定値 |
|---|---|---|
keepalive 数 |
各ワーカーが保持するアイドル接続の最大数。超えると古いものから閉じる | 1.29.7 以降は 32 local。それより前は未設定(保持しない) |
keepalive_timeout 時間 |
アイドル接続を閉じるまでの時間 | 60s(1.15.3 以降) |
keepalive_requests 数 |
1本の接続で処理するリクエストの上限 | 1000(1.19.10 より前は 100) |
keepalive_time 時間 |
1本の接続を使い続けられる時間の上限 | 1h(1.19.10 以降) |
keepalive は、ワーカーが開く接続の総数を制限するものではありません。数を大きくしすぎると、バックエンドが新しい接続を受け付ける余裕がなくなるため、バックエンドの同時接続数の上限より十分小さくします。
クライアント(ブラウザー)と Nginx の間の keepalive は、http・server ブロックに書く keepalive_timeout(既定 75 秒)など別の設定です。この記事で扱うのは、Nginx とバックエンドの間の keepalive です。
バージョンで既定値が違う
Nginx 1.29.7(2026年3月リリース)で、次の既定値が変わりました。
- upstream の
keepaliveが既定で有効になった(keepalive 32 local;) proxy_http_versionの既定値が1.0から1.1になった- プロキシ先に
Connectionヘッダーを既定で送らなくなった
そのため、1.29.7 以降(stable では 1.30 系)では、upstream ブロックを使う HTTP のプロキシは追加の設定なしで接続が再利用されます。一方、Ubuntu 24.04 の標準パッケージは 1.24、Debian 13 は 1.26(どちらも2026年10月時点)で、この変更より前のバージョンです。これらでは次の手順の設定が必要です。
使っているバージョンは次のコマンドで確認できます。
nginx -v
設定方法(HTTP のバックエンド)
1.29.6 以前で upstream keepalive を使うには、次の3つがそろっている必要があります。
- upstream ブロックに
keepaliveを書く proxy_http_version 1.1;を書く(HTTP/1.0 では接続を使い回せない)proxy_set_header Connection "";でConnection: closeを送らないようにする
設定例です(/etc/nginx/conf.d/backend.conf など、http ブロックの中で読み込まれる場所に置きます)。
upstream backend {
server 192.0.2.11:8080;
server 192.0.2.12:8080;
keepalive 16; # 各ワーカーが保持するアイドル接続の上限数(秒数ではない)
keepalive_timeout 60s; # アイドル接続を閉じるまでの時間
keepalive_requests 1000; # 1本の接続で処理するリクエストの上限
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1; # 1.29.7 以降は既定値なので省略可
proxy_set_header Connection ""; # 1.29.7 以降は不要
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
least_conn や ip_hash、hash などラウンドロビン以外の振り分け方法を使う場合、1.29.6 以前では keepalive より前の行に書く必要があります。
upstream backend {
least_conn; # 振り分け方法は keepalive より前に書く
server 192.0.2.11:8080;
server 192.0.2.12:8080;
keepalive 16;
}
1.29.7 以降で、既定の 32 から数を変えたい場合だけ keepalive を書きます。keepalive 0; と書くと、upstream への keepalive を無効にできます。
PHP-FPM(FastCGI)で使う場合
FastCGI のバックエンドでは、upstream の keepalive に加えて fastcgi_keep_conn on; が必要です。これは 1.29.7 以降も同じです。
upstream php_fpm {
server unix:/run/php/php8.3-fpm.sock;
keepalive 8;
}
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.php;
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php_fpm;
fastcgi_keep_conn on;
}
}
ソケットのパスは PHP のバージョンと OS で変わります(例は Ubuntu 24.04 の PHP 8.3)。
PHP-FPM の子プロセスは、1本の接続を処理している間はその接続に専念します。Nginx が保持しているアイドル接続の分だけ子プロセスがふさがるため、keepalive の数は「ワーカー数 × keepalive」が pm.max_children より十分小さくなるようにします。子プロセスが足りなくなると、新しいリクエストが待たされます。
設定を反映して確かめる
# 設定の文法を確かめてから反映する
sudo nginx -t
sudo systemctl reload nginx
接続が再利用されているかは、ss コマンドで確かめます(バックエンドのポートが 8080 の場合)。
# Nginx のサーバーで:バックエンドとの確立済み接続
# keepalive が効いていれば、リクエストが止まっても keepalive_timeout の間は接続が残る
ss -tn state established '( dport = :8080 )'
# バックエンドのサーバーで:TIME_WAIT の接続数(1行目は見出し)
# keepalive が効いていなければ、リクエスト数に応じて増える
ss -tn state time-wait '( sport = :8080 )' | wc -l
keepalive が効いていない場合、接続はリクエストのたびに閉じられます。HTTP/1.0 で接続を先に閉じるのは通常バックエンド側なので、TIME_WAIT はバックエンド側にたまります。Nginx 1.24(ワーカー1つ)で試すと、keepalive の設定なしで50回リクエストした後はバックエンド側に50本の TIME_WAIT が残り、設定ありでは確立済みの接続が1本残るだけでした。Nginx 1.30 では、keepalive を何も書かなくても設定ありと同じ結果になりました。
TIME_WAIT が減らない場合は、proxy_http_version や Connection ヘッダーの設定が抜けていないかを見直します。エラーは /var/log/nginx/error.log か journalctl -u nginx で確認できます。
注意事項
- バックエンドのアイドルタイムアウト:バックエンド側が接続を閉じるまでの時間が Nginx の
keepalive_timeoutより短いと、バックエンドが閉じた直後の接続を Nginx が使おうとしてエラーになることがあります。バックエンド側を長めにするか、Nginx 側のkeepalive_timeoutを短くします keepalive_requestsを大きくしすぎない:公式ドキュメントでは、接続ごとに確保したメモリを解放するために定期的に接続を閉じる必要があり、大きすぎる値はメモリ使用量の増加につながるとしていますlocalパラメーター(1.29.7 以降):既定のkeepalive 32 local;では、保持した接続を別のlocationとは共有しません。localを外すと、同じバックエンドへの接続を location をまたいで使い回せます
リバースプロキシの基本設定はNginxでリバースプロキシを設定する方法、PHP-FPM との連携はNginxとPHP-FPMの設定方法で説明しています。
まとめ
- upstream の
keepaliveの数値は、各ワーカーが保持するアイドル接続の上限数。秒数はkeepalive_timeoutで指定する - 1.29.6 以前は、
keepaliveに加えてproxy_http_version 1.1;とproxy_set_header Connection "";が必要 - 1.29.7 以降は HTTP のプロキシで既定で有効。OS 標準パッケージ(Ubuntu 24.04・Debian 13)はそれより前のバージョン
- PHP-FPM では
fastcgi_keep_conn on;が必要で、保持する数はpm.max_childrenとの兼ね合いで決める - 効果は
ssで、Nginx 側に残る確立済みの接続と、バックエンド側のTIME_WAITの数を見て確かめる