tcp_nopush 必须与 sendfile 配合使用,本质是合并响应头与文件数据进同一 tcp 报文段以提升利用率;需同时启用 sendfile on、tcp_nopush on、tcp_nodelay off、gzip off,并确保 content-length 存在,仅适用于 nginx 直接服务静态文件场景。

tcp_nopush 不能单独用,它必须和 sendfile 配合才能起作用。它的本质不是“延迟发送”,而是让内核把 HTTP 响应头和文件开头的数据合并进同一个 TCP 报文段发出,从而减少小包、提高单包利用率。这个“合并”动作,只有在 sendfile 开启的零拷贝路径下才成立。
必须成对启用,缺一不可
-
sendfile on;:启用内核态直传,跳过用户态内存拷贝 -
tcp_nopush on;:依赖sendfile提供的连续数据流,触发报文合并
如果只开 tcp_nopush 而 sendfile 是 off,Nginx 日志会明确提示 tcp_nopush is ignored,配置实际无效。
关键配套设置不能漏
-
tcp_nodelay off;:显式关闭 Nagle 算法。tcp_nodelay on会强制立即发包,直接抵消tcp_nopush的攒包效果 -
gzip off;:压缩必须关掉。一旦开启 gzip,数据就得进用户态处理,sendfile自动禁用 - 响应头必须含
Content-Length:Nginx 需预知文件大小才能走sendfile路径;否则退化为chunked编码,优化失效
只在合适的地方启用
这个组合只对 Nginx 直接服务本地静态文件有效,比如:
- 用
root或alias指向磁盘路径 - 请求后缀匹配大文件类型(
.mp4,.zip,.jpg,.webp等)
不适用于:
-
proxy_pass代理的响应(除非设proxy_buffering off且上游返回Content-Length) - PHP/Python 动态生成内容
- 启用了
sub_filter、ssi、access_by_lua_block等内容改写模块
推荐按类型精细化配置
location ~* \.(jpg|jpeg|png|webp|gif|avif|svg)$ {
sendfile on;
tcp_nopush on;
tcp_nodelay off;
gzip off;
}
location ~ \.(mp4|webm|zip|iso|tar\.gz|dmg)$ {
sendfile on;
tcp_nopush on;
tcp_nodelay off;
gzip off;
sendfile_max_chunk 512k;
output_buffers 2 128k;
}
sendfile_max_chunk 512k 可防止单次传输过大阻塞事件循环;output_buffers 加大发送缓冲区,避免过早冲刷破坏合并效果。
不复杂但容易忽略











