关键在于tcp_nopush与tcp_nodelay按路径分工:tcp_nopush需sendfile启用且仅对静态文件有效,tcp_nodelay依赖keepalive影响所有写入;静态路径须开sendfile和tcp_nopush、关tcp_nodelay;动态/API路径则关sendfile和tcp_nopush、开tcp_nodelay。

关键不是“开哪个”,而是让两个指令在各自适合的路径上各司其职:tcp_nopush 负责把大块静态内容攒成整包发,tcp_nodelay 确保小响应和连接尾部不卡住。
先明确各自生效前提
tcp_nopush 只在启用 sendfile 时起作用,且只对 Nginx 直接读取文件的场景有效(如 root + location 匹配本地路径)。它不参与 proxy_pass、FastCGI 或 gzip 压缩流程——这些路径走用户态缓冲,内核无法“攒包”。
tcp_nodelay 则依赖 keepalive 连接,在 HTTP/1.1 持久连接或 HTTP/2 下默认活跃,只要 socket 建立就参与调度,影响所有写入操作,包括响应头、小 JSON、心跳帧等。
静态资源路径必须配对启用
对 /static/、/assets/、.js/.css/.png 等纯文件服务:
• 必须开启 sendfile on;
• 必须开启 tcp_nopush on;
• 推荐关闭 tcp_nodelay off;(避免干扰合并逻辑)
• 同时增大缓冲:output_buffers 2 128k; 防止因缓冲不足提前冲刷
动态接口与长连接路径要单独控制
对 /api/、/ws、/events 等低延迟敏感路径:
• 关闭 sendfile(proxy_pass 场景下自动禁用)
• 关闭 tcp_nopush(无效且可能干扰)
• 显式开启 tcp_nodelay on;
• 确保 upstream 启用 keepalive 连接池
例如:
location /api/ {
proxy_pass http://backend;
tcp_nodelay on;
tcp_nopush off;
}
反向代理转发需额外满足条件
当 Nginx 作为代理拉取后端静态资源(如对象存储)时,tcp_nopush 要生效,后端响应必须:
• 返回明确的 Content-Length(不能是 chunked 编码)
• 允许 Nginx 完整缓存响应(proxy_buffering on,且 buffer 大小足够)
• 不做流式生成(如边读边传)
否则 Nginx 无法预知长度,tcp_nopush 自动退化为无效状态,行为退回到 tcp_nodelay 控制的小包发送。


















