从 11 月 4 日起,Cloudflare D1 的单次查询如果返回结果超过 50MB 会直接失败,报错是“D1 query result exceeded the maximum response size limit of 50 MB”,靠 SELECT 星号拉全表的写法要改了。

从 11 月 4 日起,Cloudflare D1 的单次查询如果返回结果超过 50MB 会直接失败,报错是“D1 query result exceeded the maximum response size limit of 50 MB”,靠 SELECT 星号拉全表的写法要改了。
这次改的是什么
Cloudflare 在 10 月 30 日的更新日志里写明:11 月 4 日起对 D1 的查询结果强制执行 50MB 上限,超过就报错。官方同时给了一个让人安心的数字——50MB 覆盖了 D1 全部请求的 99.999 分位,也就是绝大多数站点根本碰不到。通过 REST API 做的导入导出不受这条限制,照旧工作。
换句话说,这不是一次性能优化,而是一条硬边界:原来能跑通的“全量拉取”,从今天开始会在某个数据量点上突然断掉,而且断得很干脆,不返回部分结果。
哪些查询会撞线
三类最常见:一是 SELECT 星号的全表拉取,尤其是带 TEXT、JSON 字段的表;二是导出报表、备份、批量同步这类“一次拿完”的任务;三是搜索或列表接口没有分页,数据涨上来之后慢慢就超了。按 UTF-8 字节算,单条记录平均 1KB,五万条左右就到顶;如果一条文章正文 10KB,五千条就够呛。
怎么改
第一,只取需要的列,别用星号,正文和 JSON 字段按需单独查。第二,用 LIMIT 加上游标分页:WHERE id > ? ORDER BY id LIMIT 500,这比 OFFSET 稳,翻到后面也不会越来越慢。第三,聚合放数据库做,别把行拉回来在 Worker 里算。第四,真要整表导出,走 REST 的导出接口,那条路不受这条限制。第五,给前端加个兜底提示,别让用户只看到白屏。
容易忽略的细节
COUNT 的结果也算在响应体里,但它本身很小,一般不是问题;真正占体积的是重复的长文本。另外 OFFSET 分页在 D1 上不是免费的,偏移越大扫描越多,十万条以后会明显变慢,所以游标分页不是“更优雅”,而是更省。还有一个坑:批量写入返回的 RETURNING 结果同样计入 50MB,一次插太多行会撞线。
对站长的实际影响
还有一件事值得做:给查询加一层长度保护。先估算结果规模再决定分页大小,比如先取 limit 1 探一下,或者干脆固定每页 200 条。遇到超限时记一条带查询语句的日志,别等到用户报障才知道。Cloudflare 的错误信息里会明确写 exceeded,抓这个关键字做告警最省事。
用 Pages Functions 或 Workers 搭轻站的,评论列表、文章归档、站内搜索这三处最容易踩。今天之后如果突然出现“列表加载失败”,先别怀疑网络,去看查询是不是没分页。对纯静态站没有影响,但如果你把 D1 当“免费 MySQL”用,这次该认真看一眼查询语句了。
本文根据公开报道整理,主要参考:Cloudflare 开发者文档更新日志(2026-10-30)。