要实现“先全速加载、后阶梯限速”,核心是用好 limit_rate_after 和 limit_rate 的配合:前者指定响应体字节数阈值(如5m),后者设定超限后的恒定速率(如512k),二者必须成对出现在同一 location 中,且仅支持 k/m/g 单位;limit_rate_after 从响应体首字节开始计数,突破后立即按 limit_rate 匀速发送,每次请求独立计数,不支持原生多档自动切换。

要实现“先全速加载、后阶梯限速”,核心是用好 limit_rate_after 和 limit_rate 的配合。它不是分阶段动态调速,而是单次响应内“前 N 字节不限速、超阈值后固定限速”。所谓“阶梯”需靠多 location 或变量控制模拟,原生不支持自动多档切换。
基础逻辑:一个连接、一次计数、两段速率
limit_rate_after 不是时间阈值,而是已发送响应体字节数的硬性开关:
- 计数从响应头发出后、响应体开始传输起算(不含响应头)
- 只要已发字节数 ≤ limit_rate_after 值,Nginx 完全不干预发送节奏——实际速度由磁盘 I/O、网络带宽、upstream 吞吐决定
- 一旦突破该字节数,立刻按 limit_rate 设定的恒定速率(如 256k)匀速发送剩余内容
- 每次 HTTP 请求独立计数,断点续传、Range 请求、重连都会重置计数器
配置要点:必须成对、位置敏感、单位严谨
这两个指令不能单独存在,也不能乱放位置:
- 必须同时出现在同一 location 或 server 块中;仅写 limit_rate_after 而无 limit_rate,等于没限速
- 不支持写在 http 全局块——会报错或静默失效
- 单位只认 k(KB)、m(MB)、g(GB),大小写敏感:
10m✅,10M❌,10MB❌,10.5m❌ - limit_rate 值为 0 表示不限速;设为 1 就几乎卡死(约 1 字节/秒)
典型实用场景与写法
不同业务目标对应不同组合方式:
-
大文件下载首屏加速:前 5MB 全速加载预览页或视频关键帧,之后限速防带宽打满
limit_rate_after 5m; limit_rate 512k; -
区分文件类型差异化策略:小图不限速,大附件限速
location ~ \.(jpg|png|gif)$ { limit_rate 0; }<br>location ~ \.(zip|mp4|iso)$ { limit_rate_after 2m; limit_rate 1m; } -
按请求参数动态限速:允许高权限用户跳过限速
set $dl_rate "256k";<br>if ($arg_nolimit = "1") { set $dl_rate "0"; }<br>limit_rate_after 10m;<br>limit_rate $dl_rate;
常见失效原因与避坑指南
配置没错但没生效?大概率掉进这几个坑:
-
Nginx 版本太低:limit_rate_after 是 1.19.10 引入的,1.18.x 及更早版本直接报
unknown directive,必须升级 -
gzip 干扰计数:开启 gzip 后,响应体被压缩,limit_rate_after 按压缩后字节数判断,导致提前或延迟触发限速。建议限速 location 中加
gzip off; -
proxy_pass 场景误判:limit_rate_after 对 proxy_pass 返回的内容有效,但若后端本身做了 chunked 编码或流式响应,且未正确设置
Content-Length,可能导致计数不准 - 被其它模块拦截:如果请求先被 limit_conn 或 limit_req 拒绝,根本不会走到限速逻辑;确保限速配置在流量控制之后执行










