nginx: SSE(ストリーミング応答)は proxy_buffering を切る
nginx はアップストリームの応答を既定でバッファしてから返すので、Server-Sent Events や逐次出力のレスポンスが「まとめてドサッと」届く。手元では滑らかなのに本番だけ遅く見えるときは、まずここを疑う。
どんな時に気にする?
- SSE・チャンク転送でトークンや進捗を逐次返す API(LLM のストリーミング、ログのライブ表示など)
- ローカルでは 1 つずつ流れるのに、nginx を挟んだ本番では数秒おきに固まって届く
- 最初の 1 バイトが届くまでの時間(TTFB)だけが本番で悪い
対処(どちらか)
- nginx 側でストリーミングするパスだけバッファを切る
nginx
location /api/stream { proxy_pass http://app; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_buffering off; # 応答を溜めずにすぐ流す proxy_cache off; proxy_read_timeout 1h; # 長時間つなぎっぱなしの接続が 60 秒(既定)で切られないように } - アプリ側から、そのレスポンスだけバッファしないよう指示する
ts
// Hono / Express など、どのフレームワークでもヘッダーを足すだけ c.header("Content-Type", "text/event-stream"); c.header("Cache-Control", "no-cache"); c.header("X-Accel-Buffering", "no"); // nginx がこのレスポンスだけバッファしないnginx の設定を触れない環境(共用のリバースプロキシなど)ではこちらが楽。
注意点
gzip onが効いていると、圧縮のために溜められて同じ症状になることがある。text/event-streamはgzip_typesに入れない。- nginx の手前に CDN やロードバランサがある場合、そちら側のバッファリングも確認する(nginx だけ直しても治らないことがある)。
proxy_buffering offをserver全体に付けると、普通の API でも遅いクライアントに nginx のワーカーが引きずられる。ストリーミングのパスに限定する。
出典
- @amitsinha__07 · 2026-10-20
- nginx ドキュメント(proxy_buffering / X-Accel-Buffering): nginx.org