为什么请求不多也会被限流?为什么 A 账户触发错误,B 账户也停了?理解这些问题,要把开发者应用、广告账户、业务用例和具体操作分开。
A 被限流,为什么 B 也停了
做 Meta 广告管理或数据同步时,最常见的处理方式是:请求失败,识别为限流,等待一段时间后重试。这个流程很容易写出来,但如果没有弄清楚限制的是谁,等待策略就可能变成新的瓶颈。
假设一个系统用同一个开发者应用,管理广告账户 A 和 B。A 在读取素材时返回 80004。系统随即把所有读取暂停一小时,B 的报表也不再更新。
这时,人们很容易得出结论:"A 用完了额度,所以 Meta 把 B 也限制了。"但实际至少有两种不同的情况。
第一种,触发的是开发者应用层面的限制,通过这个应用访问不同账户的某类请求确实可能一起受影响。第二种,Meta 只拒绝了某个账户相关业务,系统却为了保守处理,主动把整个凭据范围的任务暂停了。后一种情况下,B 的暂停来自项目策略。
排查限流,要同时回答两个问题:Meta 触发了什么规则,项目又把这次错误传播到了多大范围。
同样重要的是,"请求太多"并不总是指请求次数。Meta 还会观察后端计算时间、总处理时间、瞬时写入速度,以及单次查询的数据规模。请求数量不高,也可能碰到另一项保护。
本文主要讨论广告管理与 Insights 读取涉及的 Marketing API 规则。通用 Graph API、Page、Instagram 等产品的规则会在必要处说明边界,避免把不同产品的公式混在一起。
应用、账户、BUC 和 Ad Set,不是一棵树
理解 Meta 限流时,一个容易走偏的分类方法是:第一层分为开发者应用和广告账户,广告账户下面再分为业务用例和 Ad Set。这个结构把不同维度放在了同一层。
更好的办法,是把一次请求拆成"谁发起""做什么""操作谁"三个问题。
- 身份与影响范围:开发者 App M · 账户 A。规则可以约束应用、账户,或二者组合。
- 业务操作类别:ads_management / ads_insights。BUC 说明这次调用属于哪一类业务。
- 目标对象与动作:Ad Set X · 读配置或改预算。对象、字段和操作还可能有专门规则。
一次调用可以同时受到多个适用规则约束。这些维度交叉,不是唯一的父子关系。
这里的 App,是开发者应用
这里的 App 指在 Meta for Developers 中注册的开发者应用,以及对应的 App ID。它与广告正在推广的 Android 或 iOS 产品不是同一个概念。
例如,你推广三款游戏,却通过同一个开发者 App 发起 API 请求。对于按该开发者 App 约束的规则,这些适用请求仍可能汇聚到一起。换一台服务器、增加 Worker 或使用多个 Token,也不能仅凭这些变化就认定拿到了独立的应用额度。
BUC,是 Meta 定义的业务操作类别
BUC 的全称是 Business Use Case。它不是"某款短剧""某个部门"或"某个定时任务",而是 API 的业务类别,通常由端点及官方规则决定。
ads_management:广告对象管理及相关读取。ads_insights:广告投放效果报表。custom_audience:自定义受众相关操作。
因此,management 并不意味着只有写入。读取 Campaign、Ad Set、Ad 或 Creative 的配置,也可能属于管理业务。
Ad Set,是对象
同一个广告组 X,读取名称、状态和预算配置时,可以属于 ads_management;读取展示、消耗等效果数据时,属于 ads_insights;修改日预算时,又回到管理业务,并增加预算修改次数的约束。
Ad Set 的预算修改限制不是一种独立 BUC,而是某个对象、某些字段和某类写入动作的专门规则。
依据:Marketing API 限流说明、Insights 最佳实践。
读取一次广告组效果,可能经过哪些限制
继续假设:开发者应用 M 服务账户 A 和 B,广告组 X 属于 A。现在查询 X 过去 30 天的展示、消耗和触达,并按天、年龄和性别拆分。
text
GET /v[实际API版本]/[ADSET_X_ID]/insights
fields=impressions,spend,reach
date_preset=last_30d
time_increment=1
breakdowns=age,gender
请求为教学示例,版本和 ID 是占位符,不含凭据,也不执行真实调用。
第一步,识别业务类别。端点是 /insights,所以应按效果报表业务判断。不能因为目标对象是 Ad Set,就把它归成管理读取。
第二步,检查账户 API 积分。这仍是一次访问账户 A 的 Marketing 调用,普通读取通常按 1 分计算。积分限制与后面提到的小时 BUC 配额是两套不同约束。
第三步,观察账户的 ads_insights BUC。该类业务有自己的小时公式,也会涉及调用量、CPU 与总处理时间等使用维度。
第四步,检查 Insights 应用负载。Meta 对同步和异步 Insights 请求合并观察,并提供应用和账户的容量占比。如果 M 的 Insights 应用容量已满,通过 M 读取 B 的报表也可能受影响。
第五步,判断单次查询是否过重。长时间范围、更多对象、高基数维度和复杂指标都会影响查询规模。即使近期用量较低,一个过大的查询也可能被单次数据量规则拒绝。
此外,Insights 平台整体高负载或账户异常流量防护,也可能影响请求。但它们需要相应错误及上下文支持,不能在没有证据时统一归因。
准确判断,也包括排除
这次调用没有改预算、没有改账户花费上限,也没有创建广告。因此,预算修改次数、账户花费上限修改次数、广告创建限制,以及指定对象创建/编辑 QPS,不能因为"访问了 Ad Set"就自动套用。
如果换一个端点,分类就可能变化
读取同一个对象的配置:
text
GET /v[实际API版本]/[ADSET_X_ID]
fields=id,name,status,daily_budget
这属于管理读取,应关注账户积分与 ads_management 等适用规则。虽然读取了 daily_budget,但读取不等于修改,不会因此消耗"预算每小时修改 4 次"的次数。
如果改为 POST 更新 daily_budget,则要同时考虑管理 BUC、通常更高的写入积分、指定对象编辑 QPS,以及 X 自身的预算修改频率。
所以,一次读取可以帮助理解多个限流层面,却不可能真正覆盖所有写入专用限制。读请求和写请求需要放在同一组例子里对照。
依据:Marketing 限流、Insights 负载与查询限制。
账户积分、小时配额和访问档位
账户积分,约束短期累积调用
Marketing API 为调用分配分值。官方说明中,普通读取通常为 1 分,写入通常为 3 分。账户积分达到上限后,会返回相应限流错误。
| 档位 | 最大积分 | 衰减参数 | 达到上限后的阻塞时长 |
|---|---|---|---|
| Development / Limited | 60 | 300 秒 | 300 秒 |
| Full | 9,000 | 300 秒 | 60 秒 |
这里的 300 秒衰减,不能简单实现为"每到整点五分钟全部清零"。官方概览没有公开足以完整重建其内部积分算法的细节。
当前 Marketing 文档把 17 / 2446079 和 613 / 1487742 列为账户 API 积分类限流。即使消息里出现 User,也不能只看这个单词就判定为个人号或 Token 全局额度。
BUC 配额,观察某类业务的滚动小时用量
在同一广告账户上,属于同一 BUC 的相关端点共享对应业务额度。以活跃广告数 A、公式中的用户错误数 E 为变量,官方概览给出的管理与 Insights 小时公式如下。
| 业务 | Limited / Development | Full / Standard 配额 |
|---|---|---|
| 广告管理 | 300 + 40 × A |
100000 + 40 × A |
| Insights | 600 + 400 × A − 0.001 × E |
190000 + 400 × A − 0.001 × E |
假设 A 为 100,E 为 0:Limited 档的管理公式值是 4,300,Insights 是 40,600;Full 档则分别是 104,000 和 230,000。它们是公式代入值,不是当前剩余额度,也不保证系统可以持续达到这个吞吐量。
A 指活跃广告数,不能替换成历史 Creative 数、Campaign 数、安装量或累计素材数量。E 也不能把网络超时、本地异常、冷却跳过都自行算进去。
自定义受众使用活跃自定义受众数作为变量:Limited 基数 5,000,Full 基数 190,000,再加其数量的 40 倍,上限 700,000。这与活跃广告数是不同变量。
即使调用量公式仍有空间,CPU 或总处理时间维度仍可能先触发。一小时额度很高,也不意味着允许把所有调用集中到某一秒发完。
先确认 Tier,再讨论配额
官方已把相关 Feature 名称更新为 Marketing API Access Tier,界面名称和响应头名称之间存在一个容易误读的对应关系。
| 当前界面 | 配额/响应头值 | 旧界面名称 |
|---|---|---|
| Limited Access | development_access |
Standard Access |
| Full Access | standard_access |
Advanced Access |
也就是说,旧界面的 Standard Access 与响应头里的 standard_access,对应的不是同一档。核实配额时,应看当前 App Dashboard 的 Feature 状态和真实响应头,不能只看一个 Standard 单词。
用户 Token、系统用户 Token、业务权限授权与配额档位,分别回答不同问题。Token 类型不能单独证明已经拿到 Full。
不要套错 API 产品的公式
通用 Graph Platform 文档有"滚动一小时 200 × 用户数"的应用公式,也描述用户级跨应用累计。但 Marketing API 使用自己的限流体系。不能把这套通用公式当成广告管理或 Insights 的额度,也不能把它机械叠加到每个 Marketing 请求上。
依据:Marketing 积分、配额与 Tier、Graph 产品边界。
响应头比一句"请求太多"提供更多信息
错误码帮助识别规则类别,响应头帮助判断用量状态。最常见的误解,是把 call_count 当作原始次数,把 total_cputime 当作本地服务器 CPU 使用率。
下面是一组教学读数:
text
X-Business-Use-Case-Usage:
{
"[官方返回的对象键]": [{
"type": "ads_insights",
"call_count": 35,
"total_cputime": 100,
"total_time": 48,
"estimated_time_to_regain_access": 19
}]
}
它表示调用额度占比约 35%,Meta 后端 CPU 额度占比 100%,总处理时间占比 48%。因此,即使调用量不高,也可能因 CPU 资源维度受限。
estimated_time_to_regain_access 的单位是分钟,示例中的 19 表示预计 19 分钟,不是 19 秒,也不是恢复保证。外层对象键的含义还应结合官方定义和请求上下文识别,不能把所有键都直接当成广告账户 ID。
应用满、账户低,说明了什么
text
X-FB-Ads-Insights-Throttle:
{
"app_id_util_pct": 100,
"acc_id_util_pct": 20,
"ads_api_access_tier": "standard_access"
}
这组模拟读数里,账户容量只用了 20%,但应用 Insights 容量已到 100%。如果仍通过同一 App 查询账户 B 的报表,换账户可能无法解决问题。
这并不意味着所有对象管理端点也必然失败。该头描述的是 Insights 负载,要与实际错误和请求端点一起理解。
| 响应头 | 重点观察 |
|---|---|
X-Ad-Account-Usage |
账户占比、reset_time_duration(秒)、Tier。 |
X-Business-Use-Case-Usage |
BUC 类型;调用、CPU、时间的额度占比;恢复估计(分钟)。 |
X-FB-Ads-Insights-Throttle |
Insights 应用与账户容量占比、Tier。 |
X-FB-Ads-Insights-Reach-Throttle |
特定历史 reach 拆分查询的专门额度。 |
X-App-Usage |
通用 Graph 应用使用情况;先确认产品适用性。 |
没有取得响应头,就应记录为未知。它可能未返回,也可能被 SDK 或日志层丢掉;"没看到"不能解释成"用量为 0"。HTTP 状态同样不能独立分类:限流可能以 400 返回,429 也不能告诉你是哪一个范围用满。
写入频率和单次查询规模,要单独处理
账户积分和 BUC 很重要,但不覆盖所有限制。有些规则约束特定写入,有些规则约束一次查询的大小。
指定对象创建和编辑的 100 QPS
官方针对 Campaign、Ad Set、Ad 的指定创建和编辑端点,按 App 与广告账户组合限制为 100 请求/秒,目的是防止瞬时写入峰值。
它不是普通 GET 的统一 QPS,也不是"低于 100 QPS 就不会限流"。更低的请求速度仍可能碰到账户积分、BUC 或字段修改次数。异步 Insights 提交虽然使用 POST,也不能仅凭 HTTP 方法就套入这组对象创建/编辑规则。
账户花费上限与广告组预算
账户 spending limit 相关字段,例如 spend_cap,每天最多修改 10 次。广告组的 daily_budget 和 lifetime_budget 每小时最多修改 4 次;超限后,该广告组预算修改会被阻塞一小时。
前者约束账户,后者约束具体 Ad Set 的预算变更。读预算字段不会被算作改预算;不断微调预算则可能在管理配额尚未耗尽时,先触发对象规则。
广告创建与异常流量防护
广告创建还有与账户日花费上限相关的限制,常见标识是 613 / 1487225。官方概览没有给出适用于所有账户的统一创建次数,不能凭空写一个固定值。
异常流量防护则可能临时降低异常账户的额度。Marketing 文档将无子码的 613 列于这一类。遇到它应排查异常调度、重复重试和请求放大,并结合端点与详情联系支持,而不是假设某个固定等待时间必然恢复。
查询太大,不一定是频率超限
Insights 的 100 / 1487534 指向单次返回行数或计算数据点的限制。它对同步、异步都适用。今天的第一个请求,也可能因为查询过大而失败。
这种情况下,要缩小日期、对象集合、维度或指标,不能让原查询保持不变,只不断延长重试等待。
异步适合较大报表,但不会获得无限额度。同步异步 Insights 负载合并计入;提交、轮询和结果分页都应纳入请求规划。Batch 可以减少通信往返,却不能被当作"多个子请求保证只消耗一个配额"。
Insights 平台高负载和历史 reach 特例
Insights 后端整体高负载时,也可能返回 4 / 1504022。它与应用报表负载使用的错误存在重叠,因此单凭这个子码,不能唯一判断是应用用满还是平台容量保护。
还有一个容易遗漏的规则:标准查询带 breakdowns、开始日期超过 13 个月时,reach 及相关字段可能不返回。要读取这种历史拆分 reach,可以使用异步任务,每广告账户每天最多 10 次请求,并观察专门的 X-FB-Ads-Insights-Reach-Throttle。
这个 10 次/天只适用于所述历史 reach 场景,不是所有 Insights 的日额度。字段缺失也不能直接显示成零。
依据:Marketing 专用限制、Insights 查询和历史数据规则。
把主码、子码和端点放在一起看
主码适合快速分流,却往往不够精确。相同的主码可能对应完全不同的业务处理方式。
| 错误标识 | 优先判断类别 | 必须保留的边界 |
|---|---|---|
80004/2446079 |
管理 BUC | 不能单独确定调用、CPU、时间哪个维度用满。 |
80000/2446079 |
Insights BUC | 不同于 Insights 应用负载 code 4。 |
17/2446079;613/1487742 |
账户 API 积分 | 以当前 Marketing 文档及端点上下文判断。 |
4/1504022;4/1504039 |
Insights 应用负载;1504022 也可能平台高负载 | 子码重叠,需看用量、时序及平台信息。 |
4 子码未知 |
应用级判断入口 | 不能把所有 code 4 归成同一种配额。 |
613/5044001 |
指定写入 QPS | 不是所有 API 的统一 QPS。 |
17/1885172 |
账户花费上限修改 | 每天 10 次,区别于广告组预算。 |
613/1487632 |
广告组预算修改 | 每小时 4 次,超限阻塞一小时。 |
613/1487225 |
广告创建 | 与账户日花费上限相关,无统一次数。 |
613 无子码 |
Marketing 异常流量防护 | 仍需核对产品、端点和详情。 |
100/1487534 |
单次报表数据/计算量 | 拆查询;不能只等时间。 |
其他产品或业务还可能出现自定义受众 80003、Catalog Batch 80014、Catalog Management 80009、Page 32 或 80001 等。它们提醒我们先识别产品边界,不能把所有错误装进"普通广告读取"这一类。
通用 Graph 错误表包含旧 Ads API 版本的说明。处理当前 Marketing 请求时,要优先核对当前 Marketing 端点规则、实际版本及响应头,不能把旧表的一句解释直接覆盖所有场景。
一次有价值的诊断记录,应保留时间、开发者 App、已知账户、HTTP 方法、端点模板、版本、主码、子码、用量头和 fbtrace_id。其中不能包含 Token、app secret、完整授权头或含凭据的分页 URL。
依据:Marketing 错误分类、Graph 错误表、Insights 错误。
管理读取是主要类别,根因仍要看维度
在一个广告同步项目的历史只读诊断中,2026-10-12 09:47 至 2026-10-13 09:47(UTC+8)的 24 小时窗口,登记了 18 条提供方限流事件:
- 10 条发生在 Creative 读取,错误为
80004 / 2446079。 - 6 条发生在账户发现阶段,同为
80004 / 2446079,但记录未锁定具体账户。 - 2 条发生在 Ad Set 读取,为
17 / 2446079。
能够得出的结论是:该样本主要记录到管理 BUC 类错误,也出现了账户积分限制。18 条是登记事件数,不是全部 HTTP 请求数,不能直接用来计算失败率。
还不能得出的结论是:所有 80004 都由请求次数耗尽造成。没有对应完整用量头,CPU 与总处理时间维度仍无法排除。
本地策略,会放大观察到的影响
项目对已知账户的部分管理错误采取账户冷却;对账户未知的发现错误、部分其他错误采取凭据范围冷却。它会影响更多账户的调度,但这个范围来自项目实现,不能倒过来当作 Meta 应用额度耗尽的证据。
样本还有 51 次冷却跳过。这些工作因本地保护而没有继续访问,不能再统计成 51 次新的 Meta 拒绝。
同样,项目对 80004 设置至少 3,600 秒等待,是本地保护下限,结合提供方提示处理。它不是 Meta 规定所有 80004 必须等待一小时。
素材多,为什么值得关注
两个账户分别有 3,446 和 2,229 条 Creative。若每页按 25 条完整读取,理论上至少需要 138 和 90 页,合计 228 页。实际请求数还会受端点分页、重试和其他读取影响。
这能说明全量素材同步可能是重要的请求来源,却不能把素材数代入活跃广告公式,也不能仅凭字段较宽就认定 CPU 是已确认根因。
更稳妥的改进,是把端点、账户、BUC、请求页数、用量维度和本地暂停范围关联起来。历史错误分类未显式列入某些主码时,还应补齐可观测性,避免把"未被专门统计"理解为"从未发生"。
本节为本项目先前诊断的匿名化历史案例,不是实时线上结论;来源为历史只读输出及对应证据报告。
先定位,再决定限速、拆查询还是改调度
"降低并发"有时有效,但它不能代替分类。不同规则需要不同的工程动作。
如果是账户积分或突发请求,重点是均匀调度、减少重复任务、控制同账户峰值,并给重试加入退避和随机抖动。只看小时总量,会遗漏短时间内的集中请求。
如果是 BUC 调用量,重点是减少不必要读取、复用已有快照、对实际变化做增量同步,并核实访问档位。换 Token 不能直接证明账户额度重置。
如果是 CPU 或总处理时间,重点应转向字段、指标、对象集合和日期范围。减少一个轻请求,未必比拆开一个重查询更有效;优化后应比较同类请求的资源用量。
如果是 Insights 应用负载,必须统筹同一 App 下的跨账户报表。只换广告账户、却保持同样的应用总负载,可能继续失败。
如果是单次数据量,先拆日期、对象、维度或指标;如果是预算修改次数,先合并策略决策,减少高频微调;如果是异常流量防护,先查失控调度与重试放大。
本地资源和 Meta 容量是两件事
升级到 4 核 8 GB、增加 Worker、迁移 Redis,可以影响本地调度、入库和传输性能,但不会直接增加 Meta 配额。若这些变化让请求发得更快,还要重新观察 Meta 侧负载。
把三种"时间"分别记录
官方规则的阻塞时长、响应头给出的恢复估计、项目设置的下一次重试时间,应分别展示。用一列"冷却到"装下全部信息,会让后续排查越来越困难。
例如,一个 BUC 头给出预计 19 分钟恢复,项目也许选择更保守的下次尝试时间。这可以是合理策略,但告警应该说明差别,而不是把项目等待写成官方时长。
一条中文告警,应当让人知道下一步查什么
text
任务:广告对象读取
请求:GET /act_[账户A]/adcreatives
错误:80004 / 2446079
分类:ads_management BUC
已知:管理业务被限流。
未知:未取得BUC用量头,不能区分次数、CPU和处理时间。
本地处理:[实际暂停范围与下次尝试时间]
官方恢复估计:[实际值及分钟单位,缺失则未知]
影响:相关对象快照可能滞后。
建议:核对Tier、完整分页次数、宽字段和重复同步。
追踪:保留脱敏fbtrace_id。
这类告警比只输出一个代码更有用,也能避免把策略和提供方事实混在一起。真实写入如果结果未知,还应先回读确认,不能因为一次失败就整批重复创建。
优化完成后,应看数据最终是否完整、新鲜度是否改善,以及同类规则的错误是否减少。一个请求成功、一个 Stream 暂时清空,都不能独立证明整轮采集达到目标。
依据:官方处理建议、查询最佳实践;具体调度方案应结合系统证据制定。
把"请求太多",拆成可以回答的问题
Meta 限流难理解,常常不是因为公式复杂,而是因为多个维度被混在了一起:应用和账户混在一起,BUC 和对象混在一起,官方规则和项目冷却混在一起,调用次数和计算资源又混在一起。
下一次遇到错误时,可以先问五个问题:
- 这是哪个 API 产品、哪个端点、哪个 BUC?
- 规则约束应用、账户、二者组合、具体对象,还是单次查询?
- 主码、子码和响应头已经确认了什么?
- 瓶颈是次数、CPU、时间、瞬时峰值,还是查询规模?
- 当前影响范围由 Meta 决定,还是项目主动扩大?
回答这些问题以后,才有依据决定:应该减少管理读取、简化报表、摊平并发、核实 Tier,还是调整本地恢复策略。
好的限流处理,不只是让系统等待后继续跑,而是让每一次等待都有清楚的原因、范围和恢复依据。
官方参考资料
1. Marketing API --- Rate Limiting
账户积分、BUC、应用限制、写入 QPS、预算/花费上限、异常流量及访问档位。
Platform 与 BUC 边界、响应头字段和单位、各产品错误分类;注意其中的旧 Ads 版本说明。
3. Ads Insights --- Limits and Best Practices
同步异步负载、应用/账户容量、单次数据量、平台高负载和历史 reach 特例。
规则依据为 2026-10-13 已取得的官方原文,文章整理于 2026-10-14;实施时需核对具体 API 版本、端点、当前控制台和响应头。请求与响应头示例均为教学模拟。本项目实际 Access Tier 与历史 BUC 触发维度未在本文认定。