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 の数を見て確かめる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲