sendfile 仅在 linux 内核(2.3.10+)本地文件系统(如 ext4、xfs)上稳定生效,不支持 macos/windows 及 nfsv3、cifs 等;需配合 tcp_nopush on,但弱网下易增 ttfb;gzip、sub_filter、proxy_pass、range 请求等均使其失效;大小文件应分层配置。

sendfile 不适合所有网络环境的静态服务,它有明确的适用边界和依赖条件。
只在 Linux 内核且本地文件系统上稳定生效
sendfile 是 Linux 内核 2.3.10+ 提供的系统调用,macOS 和 Windows 不支持该优化路径。即使 Nginx 配置了 sendfile on,在非 Linux 环境下也会静默退化为普通 read/write 流程。同时,它要求文件必须位于支持 sendfile 的本地文件系统(如 ext4、XFS),而 NFSv3、CIFS、FUSE、某些容器存储驱动(如 overlay2 在旧内核下)可能不完整支持,导致内核返回失败,Nginx 自动回退。
对网络链路质量敏感,小包/高延迟场景需权衡
sendfile 必须配合 tcp_nopush on 才能发挥批量发送优势,但它依赖 TCP 缓冲区填满才发包。在高丢包、高延迟或带宽极低的链路上,攒包可能引入额外等待,反而增加首字节延迟(TTFB)。此时若同时启用 tcp_nodelay on,又会与 tcp_nopush 冲突,破坏零拷贝的传输效率。因此,公网边缘节点或面向弱网终端(如移动 3G/4G)的服务,不宜盲目全局开启;更适合部署在 IDC 内网、CDN 边缘或局域网等低延迟、高带宽环境中。
不兼容需要用户态干预的常见功能
以下任一情况都会让 sendfile 自动失效,哪怕配置正确:
- 启用了 gzip on(运行时压缩必须进用户态)
- 使用 sub_filter、add_before_body 等内容改写指令
- 配置了 proxy_pass、fastcgi_pass 或 X-Accel-Redirect 返回非本地路径文件
- 响应头中动态生成 ETag、Expires 或含 Set-Cookie
- 客户端发起 Range 请求(如视频拖拽)
大文件与小文件表现不同,需分层配置
小文件(如 JS/CSS/图标)走 page cache + sendfile 效果最好;但超大文件(≥4MB 视频、安装包)若全靠 page cache,易挤占内存、影响其他请求。此时应结合 aio on 和 directio 4m,绕过 page cache 直读磁盘,避免缓存污染——这已不属于传统 sendfile 路径,而是异步零拷贝增强模式,需单独配置 location 块并确认内核支持。











