tcp_nopush 是 Nginx 配合 sendfile 优化大文件传输的 TCP 指令,通过延迟发送、合并报文减少小包,需启用 sendfile 且禁用 tcp_nodelay 才生效,对小文件、HTTPS 或高并发小请求效果有限。

tcp_nopush 是 Nginx 在 http 块(或 server、location 块)中可配置的 TCP 优化指令,主要用于提升大文件(如视频、ISO、安装包等静态资源)的分发效率,但它的作用机制常被误解。
tcp_nopush 的真实作用
它并不直接“加速传输”,而是配合内核的 TCP_NODELAY(即 Nagle 算法)做协同控制:
- 当
tcp_nopush on时,Nginx 会等待缓冲区填满一个完整的 TCP 报文段(或触发sendfile完成),再一次性将数据推送到内核发送队列,减少小包数量; - 这依赖于
sendfile启用(默认开启)——因为只有sendfile才能绕过用户态拷贝,让内核直接从文件页缓存构造 TCP 包; - 若禁用
sendfile或使用非零长度的proxy_buffering,tcp_nopush将失效或效果极弱。
在 http 块中正确启用的条件
全局开启需满足基础前提,否则可能无效果甚至适得其反:
- 确保
sendfile on;已在http或更外层启用(推荐放在http块); -
tcp_nopush on;可写在http块,对所有启用sendfile的响应生效; - 避免与
tcp_nodelay on;同时启用——二者逻辑冲突:tcp_nodelay强制立即发小包,tcp_nopush则延迟合并发包; - 仅对大文件有效:小文件(如
典型高效配置示例
适用于 CDN 边缘节点或大文件下载服务:
http {
sendfile on;
tcp_nopush on; # 启用报文合并
tcp_nodelay off; # 关闭 Nagle 干预(与 tcp_nopush 协同)
keepalive_timeout 65;
<pre class="brush:php;toolbar:false;">server {
listen 80;
location /downloads/ {
root /data/static;
# 自动触发 sendfile,无需额外设置
}
}}
需要留意的实际限制
该优化不是“开就变快”的银弹:
- 只影响内核发送队列组装阶段,不改变带宽、RTT 或磁盘 IO;
- 在高并发小请求场景下,
tcp_nopush on可能轻微增加首字节延迟(因等待填充); - HTTPS 场景下,由于 TLS 记录封装和加密开销,
tcp_nopush效果大幅减弱; - 现代 Linux 内核(≥5.10)已增强 TCP 自适应算法,部分场景下手动干预收益下降。











