2026年7月22日
2026年7月22日
WordPressのNginxでsendfileとtcp_nopushを有効化して静的ファイル配信を効率化する
Nginxで sendfile on; と tcp_nopush on; を有効にすると、画像やCSS、JavaScriptなどの静的ファイルを、カーネル内で直接ソケットへ送り、パケットをまとめて送信できるようになります。この記事では、二つの設定が何をしているのか、WordPressのサイトでどこまで効果があるのか、設定の書き方と、有効になっているかの確かめ方を説明します。先に結論を書くと、多くの環境ではすでに有効になっており、HTTPSのサイトでは効果が限られる場面もあるため、「現状を確認して、必要なら有効にする」という進め方が適しています。
sendfileとtcp_nopushが何をするのか
sendfile
通常、Webサーバーがファイルを送るときは、ディスクから読んだデータをいったんアプリケーション(Nginx)のメモリにコピーし、それをネットワークのソケットへ書き込みます。sendfile on; にすると、Linuxの sendfile() システムコールを使い、ファイルからソケットへの転送をカーネル内で済ませます。ユーザー空間へのコピーが減るため、CPU使用量とメモリの使い方が軽くなります。Nginxの初期値は off です。
tcp_nopush
tcp_nopush on; は、sendfile を使っているときだけ効く設定で、Linuxでは TCP_CORK というソケットオプションを使います。レスポンスヘッダーとファイルの先頭を一つのパケットにまとめ、その後もパケットをできるだけ満杯にして送ります。小さなパケットが何度も送られるのを防ぎ、通信の効率を上げます。
tcp_nodelayとの関係
似た名前の tcp_nodelay は、逆に「小さなデータでも待たずにすぐ送る」設定で、初期値は on です。両方を有効にしても矛盾はなく、Nginxはファイル本体をまとめて送ったあと、最後のデータを遅らせずに送り出すよう両者を使い分けます。わざわざ tcp_nodelay off; にする必要はありません。
WordPressでの効果はどの程度か
正直に言うと、WordPressのサイトで表示速度を左右するのは、多くの場合PHPの処理時間とデータベースです。静的ファイルの配信はもともと速く、sendfile を有効にしてもページの表示時間が目に見えて縮むとは限りません。効果が出やすいのは次のような場面です。
- 画像や動画、ダウンロード用のファイルを大量に配信しており、サーバーのCPU使用率が高い
- アクセスが集中する時間帯に、静的ファイルの配信でもNginxのワーカーが忙しくなっている
もう一つ知っておきたいのが、HTTPSとの関係です。TLSで暗号化する場合、データはNginx(OpenSSL)が暗号化してから送るため、通常は sendfile() によるカーネル内転送が使われません。Nginx 1.21.4以降とOpenSSL 3.0以降、カーネルのTLS機能(kTLS)がそろった環境では、ssl_conf_command Options KTLS; でカーネル側に暗号化を任せ、HTTPSでも sendfile を使えるようになります。ただし対応する暗号方式やディストリビューションの設定に左右されるため、試すならステージングで確認してからにしてください。
また、Nginxの gzip でその場で圧縮して返すファイルは、圧縮処理を通るため sendfile を使いません。あらかじめ圧縮した .gz ファイルを返す gzip_static on; なら、ファイルをそのまま送れます。
現在の設定を確認する
多くのディストリビューションが配布する nginx.conf では、すでに sendfile on; が書かれています。まず、読み込まれている設定全体から該当する行を探します。
sudo nginx -T 2>/dev/null | grep -nE 'sendfile|tcp_nopush|tcp_nodelay|ssl_conf_command'
nginx -T はインクルードされたファイルも含めて表示するので、conf.d やサイトごとの設定で上書きされていないかも分かります。何も表示されなければ、初期値(sendfile off、tcp_nopush off、tcp_nodelay on)で動いています。
設定を書く
設定ファイルを変更する前にバックアップを取ります。http ブロックに書けば、すべてのサイトに適用されます。
# /etc/nginx/nginx.conf の http ブロック
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
sendfile_max_chunk 2m; # 1回の sendfile() で送る上限。1.21.4以降は2mが初期値
# ...(既存の設定)
}
sendfile_max_chunk は、大きなファイルを送る1つの接続がワーカーを長く占有しないようにする設定です。Nginx 1.21.4より前は上限なしが初期値だったため、古いバージョンを使っている場合は明示しておくと安心です。
あわせて、WordPressの静的ファイル向けの location を用意しておくと、キャッシュの指定とログの削減も同時にできます。
location ~* \.(?:css|js|jpe?g|png|gif|webp|avif|svg|ico|woff2?)$ {
try_files $uri =404;
expires 30d;
access_log off;
}
try_files $uri =404; は、存在しないファイルへのリクエストをPHPに回さずに404で返すためのものです。画像の差し替えでファイル名を変えない運用をしている場合、expires を長くすると古い画像が表示され続けるので、期間はサイトの運用に合わせて調整します。
書き終えたら、構文を確認してから再読み込みします。
sudo nginx -t && sudo systemctl reload nginx
有効になっているか確かめる
設定の行があるだけでは、実際に sendfile() が使われているかは分かりません。HTTPで配信している検証環境や、サーバー内部から curl で静的ファイルを取得しながら、ワーカープロセスのシステムコールを strace で観察します。
# ワーカーのPIDを調べる
pgrep -f "nginx: worker"
# 1つのワーカーを観察し、別の端末から静的ファイルを取得する
sudo strace -f -e trace=sendfile -p <ワーカーのPID>
curl -s -o /dev/null http://127.0.0.1/wp-includes/css/dashicons.min.css -H "Host: example.com"
ワーカーが複数ある場合、リクエストが観察していないワーカーに届くことがあります。その場合は -p を複数並べて全ワーカーを観察します。sendfile(...) の行が表示されれば使われています。HTTPSのリクエストで何も表示されない場合は、前述のとおりTLSのためにカーネル内転送が使われていないことが原因です。strace は本番サーバーで長時間動かすと負荷になるので、確認が済んだらすぐに止めてください。
効果を数字で見たい場合は、変更前後で同じ条件のベンチマークを取り、静的ファイル配信時のCPU使用率とスループットを比べます。ページ全体の表示速度は、PageSpeed InsightsなどでPHPやキャッシュの影響も含めて別に見てください。
つまずきやすい点
- 仮想マシンの共有フォルダ:VirtualBoxの共有フォルダや一部のネットワークファイルシステム上のファイルを
sendfileで配信すると、更新したファイルが反映されない、内容が壊れるといった不具合が知られています。ローカル開発環境でCSSの変更が反映されない場合は、その環境だけsendfile off;にして確認してください。 - 設定の上書き:
httpブロックで有効にしても、serverやlocationでsendfile off;と書かれていれば、そちらが優先されます。nginx -Tの結果で確認します。 - CDNの効果のほうが大きい場合がある:Cloudflareなどのキャッシュを使っていれば、静的ファイルの多くはオリジンまで届きません。オリジンの負荷を下げる目的なら、キャッシュの設定を見直すほうが効果的なこともあります。
まとめ
sendfileはファイルからソケットへの転送をカーネル内で行い、tcp_nopushはそのときにパケットをまとめて送る設定です。tcp_nodelayはonのままで問題ありません。- 多くの環境ではすでに有効です。
nginx -Tで読み込まれている設定を確認してから変更します。 - HTTPSでは通常カーネル内転送が使われず、Nginx 1.21.4以降とOpenSSL 3.0以降でkTLSを使える場合に限って効きます。その場で
gzip圧縮するファイルも対象外です(2026年10月現在)。 - 有効かどうかは
straceでsendfileの呼び出しを見て確かめ、効果は変更前後のCPU使用率で比べます。 - WordPressの表示速度にはPHPとキャッシュのほうが大きく効くため、ページキャッシュやCDNの設定とあわせて考えてください。