tcp_nopush需与sendfile协同生效,核心是合并响应头与文件数据进同一tcp段以提升包利用率;仅对本地静态文件有效,须在location中显式启用并禁用gzip等冲突功能。

tcp_nopush 本身不单独起作用,它必须和 sendfile 协同才能实现大文件的 TCP 包合并发送。它的核心价值不是“延迟”,而是让响应头和文件开头数据尽可能塞进同一个 TCP 段里,减少小包数量、提升单包利用率。
必须同时启用 sendfile 和 tcp_nopush
sendfile 是基础:它让内核直接从磁盘复制数据到 socket,跳过用户态内存拷贝;tcp_nopush 则依赖这条零拷贝路径,才有机会把 HTTP 状态行、响应头和文件前段数据识别为连续流并合并发送。
- 在服务大文件的 location 块中,必须显式写明:sendfile on; 和 tcp_nopush on;
- 仅开 tcp_nopush 而 sendfile 为 off,Nginx 日志会提示 “tcp_nopush is ignored”
- 全局配置继承不可靠,必须在具体 location 中声明
只对真实静态文件生效
该优化只在 Nginx 直接读取本地磁盘文件时触发,不适用于任何需要用户态处理的场景。
- 支持的典型路径:用 root 或 alias 指向本地目录,且后缀匹配(如 .mp4、.zip、.iso、.jpg)
- 不支持的场景:proxy_pass 代理、FastCGI、Lua 处理、sub_filter、gzip 压缩、动态生成内容
- 常见误配:启用了 gzip on —— 此时 sendfile 自动禁用,tcp_nopush 彻底失效
配套参数必须严格对齐
tcp_nopush 的“攒包”行为需要内核有等待空间,而 tcp_nodelay 控制是否绕过 Nagle 算法。二者逻辑相反,必须协调。
- tcp_nodelay off;(默认即为 off):允许内核暂存数据,等待凑满 MSS 再发,使 tcp_nopush 有机会合并
- 若设为 on,则强制立即发包,直接抵消 tcp_nopush 效果
- 确保响应头含 Content-Length:Nginx 需预知文件大小才启用 sendfile 路径;对象存储或后端服务需返回明确长度,避免 chunked 编码
- 可选增强:设置 output_buffers 2 128k;,避免默认 2×32k 缓冲区过小导致提前冲刷
按文件类型精细化配置更安全
全局开启容易误伤 API、WebSocket、HLS 的 m3u8 等低延迟场景,应限定在明确的大文件上下文中。
- 视频资源示例:location ~ \.(mp4|webm|avi|mov)$ { ... }
- 安装包/镜像示例:location ~ \.(zip|iso|tar\.gz|dmg)$ { ... }
- 图片资源示例:location ~* \.(jpg|jpeg|png|webp|avif|gif)$ { ... }
- 每个 location 内建议同步关闭 gzip、设置 expires、加 Cache-Control 头











