启用 deferred 参数后,Nginx 延迟 accept 调用至首个数据包到达,避免空连接占用资源、降低 epoll 系统调用频次,提升高并发效率;其底层依赖 Linux 的 TCP_DEFER_ACCEPT 选项,仅对 TCP 监听套接字生效,需配合 bind 使用,推荐写法为 listen 80 deferred;。

启用 deferred 参数后,Nginx 不会在 TCP 三次握手完成时立即调用 accept(),而是等到客户端真正发送第一个数据包(如 HTTP 请求头)时,才把连接交由 worker 进程处理。这减少了空连接占用资源、降低 epoll 等系统调用频率,提升高并发下的响应效率。
deferred 的作用机制
Linux 内核通过 TCP_DEFER_ACCEPT socket 选项实现该行为:当服务端收到 SYN 后回复 SYN-ACK;若客户端仅发 ACK(无数据),内核暂不将连接移入全连接队列,也不触发 accept;只有当后续数据包到达,内核才将其加入队列并通知 Nginx。这样避免了大量“建连即断”或“建连后长期 idle”的连接占用 worker 资源。
如何正确配置 deferred
- 仅适用于监听 IPv4/IPv6 的 TCP 端口,不支持 UNIX 域套接字或 SSL 直接监听(但可与 ssl 共存)
- 必须配合 bind 使用才生效(多数情况下 Nginx 默认已隐式 bind,但显式写更稳妥)
-
推荐搭配 backlog 参数,例如
backlog=4096,防止半连接队列溢出 - 写法示例:
listen 80 deferred;或listen 127.0.0.1:8080 deferred bind;
实际配置注意事项
在 server 块中直接添加即可,无需额外模块或编译选项:
server {
listen 80 deferred;
listen 443 ssl deferred;
server_name example.com;
# …
}- 多个 listen 指令可分别设置,互不影响
- 若同时监听 IPv4 和 IPv6,建议为两者都加
deferred,或使用ipv6only=off统一处理 - 注意:某些旧内核(ss -lnt 查看监听项是否含
defer标识确认生效
与其他性能参数的协同
deferred 常与以下参数组合使用以发挥最大效果:
-
backlog=4096:增大全连接队列,容纳更多延迟 accept 的连接 -
reuseport:每个 worker 独立监听同一端口,配合 deferred 可进一步分摊连接建立压力 -
so_keepalive=on:对已建立连接启用 TCP keepalive,避免因 deferred 导致 idle 连接被误判为异常 - 避免与
accept_filter(仅 FreeBSD)混用,二者语义重叠且不可共存


















