[Bug]: `litellm_settings.max_budget` ignores `budget_duration`; global proxy budget is a hardcoded trailing-30-day cap

当你在 LiteLLM Proxy 的 litellm_settings 中配置了全局 max_budget 与 budget_duration (例如 1d ),却发现预算不会按配置周期重置、请求持续返回 429 时,通常遇到的是这个 Issue。优先排查:全局预算的 budget_duratio

快速结论:当你在 LiteLLM Proxy 的 litellm_settings 中配置了全局 max_budget 与 budget_duration(例如 1d),却发现预算不会按配置周期重置、请求持续返回 429 时,通常遇到的是这个 Issue。优先排查:全局预算的 budget_duration 是否被真正用于限额统计窗口(LiteLLM 目前对全局预算使用的是硬编码的滚动 30 天总花费)。

适用环境:Issue 讨论中出现的对象为 LiteLLM Proxy(涉及 litellm/proxy/proxy_server.py、litellm/proxy/auth/auth_checks.py、litellm/proxy/auth/user_api_key_auth.py、litellm/proxy/db/create_views.py),以及后台重置任务 ResetBudgetJob。Issue 中未明确给出具体的 Python、CUDA、PyTorch、显卡或依赖版本,这些项目无证据可确认。

最快修复方案:暂无确认的一步修复方案。该 Issue 在 2026-07-25 被关闭,评论中提出的“将全局花费基线查询按 budget_duration 窗口化(对 LiteLLM_SpendLogs 按 NOW() - budget_duration 求和)”属于计划性修复方案,尚未在 Issue 中确认已合并或已发布,因此只能作为“可优先尝试”的方向。

注意事项:Issue 正文指出,仅依赖 default_user_id(proxy-admin)行的 spend 并不能作为全局预算的替代来源,因为该计数器只统计管理员用户自身的花费,而非全代理总量。评论中提出的窗口化方案也明确表示会保留共享的 MonthlyGlobalSpend 视图(供管理界面使用)不动。若自行改动,需确认改动后全局预算仍能被 ResetBudgetJob 正确重置,并避免影响按用户、按团队、按密钥的预算行为。

问题场景

用户在 LiteLLM Proxy 的配置中设置全局预算,例如:

litellm_settings:
  max_budget: 100
  budget_duration: 1d

期望这是一个每日(1d)封顶的预算,但实际行为与预期不符:budget_duration 对全局预算被静默忽略,实际执行的是最近 30 天的滚动总花费。一旦滚动 30 天合计超过 max_budget,代理会对每个请求返回 429,并且不会按配置的周期重置,只有在花费逐步滚出 30 天窗口后才会恢复。

报错原文

[Bug]: `litellm_settings.max_budget` ignores `budget_duration`; global proxy budget is a hardcoded trailing-30-day cap

相关的内部报错信息(配置加载时):

budget_duration is required to use max_budget

以及 Issue 中引用的硬编码 30 天窗口 SQL:

WHERE "startTime" >= (CURRENT_DATE - INTERVAL '30 days')
sql_query = """SELECT SUM(spend) AS total_spend FROM "MonthlyGlobalSpend";"""

原因分析

最可能的原因是全局预算的“重置接线”与“执行检查”使用了两个不同的计数器,导致 budget_duration 被存储和重置,但在限额执行时从未被读取:

  • 配置加载时,_add_proxy_budget_to_db(litellm/proxy/proxy_server.py)会在 budget_duration 未设置时报错,然后写入 proxy-admin 用户行(default_user_id),带上 max_budget、budget_duration 和 budget_reset_at。
  • ResetBudgetJob 会在重置时间到达时把这个行的 spend 清零,说明重置逻辑是有意为之的(参考 PR #27488 中关于 budget_reset_at 回填的注释)。
  • 但执行检查走的是另一条路径:_global_proxy_budget_check(litellm/proxy/auth/auth_checks.py:370)把 litellm.max_budget 与一个缓存的全局花费累加器(default_user_id:spend)比较,其基线来自 litellm/proxy/auth/user_api_key_auth.py:447,随后在内存中按请求递增(litellm/proxy/proxy_server.py:2860)。
  • 该基线查询使用 MonthlyGlobalSpend 视图,而这个视图是硬编码的最近 30 天窗口(litellm/proxy/db/create_views.py:68),没有 duration 或 reset 的概念。

因此,1d、7d、30d 全都表现成最近 30 天封顶。按用户、按团队、按密钥的预算各自使用自己的可重置 spend 计数器,所以它们能正确遵循 budget_duration;全局预算是唯一无法做到这一点的。

环境排查

  • 确认 LiteLLM Proxy 的部署方式与版本(Issue 未给出具体版本号,请以你实际运行的版本为准)。
  • 确认配置文件中的 litellm_settings.max_budget 与 budget_duration 是否同时设置。
  • 确认全局花费是否来自 MonthlyGlobalSpend 视图(涉及数据库为带 INTERVAL 语法的 SQL,通常为 PostgreSQL)。
  • 检查 default_user_id 行的 spend、budget_reset_at 是否按预期被 ResetBudgetJob 重置,以确认重置逻辑本身是否生效。
  • Issue 未提供具体的 Python、CUDA、PyTorch、显卡或依赖版本,无需在这些项目上做无依据的推断。

解决步骤

  1. 先确认现象:设置一个较短的 budget_duration(如 1d),观察超过 max_budget 后代理是否持续返回 429,以及是否在配置周期到达后恢复。若表现为“只随 30 天窗口滚动恢复”,即命中该 Issue。
  2. 确认全局预算执行路径:检查 _global_proxy_budget_check 与 _load_global_spend 是否仍从 MonthlyGlobalSpend 视图取基线(对应硬编码 30 天窗口)。
  3. 可优先尝试的方向(来自 Issue 评论的修复计划,尚未确认已发布):将全局花费基线查询按配置的 budget_duration 窗口化,即对 LiteLLM_SpendLogs 按 NOW() - budget_duration 求和,使封顶跟随滚动周期,并在花费滚出窗口后恢复。此改动应保留 MonthlyGlobalSpend 视图供管理界面使用,并避开 default_user_id 行(因为它只统计管理员用户自身花费)。
  4. 若你的部署确实采用固定 30 天窗口策略,另一条路径是:不再要求全局预算必须设置 budget_duration,并在文档中明确 max_budget 是最近 30 天封顶,而不是要求一个会被静默忽略的周期。
  5. 无论采用哪条路径,都需要覆盖回归测试:断言 budget_duration 确实驱动限额统计窗口,而不是被固定 30 天视图覆盖。

验证方法

配置一个较短的 budget_duration(例如 1d)并触发超出 max_budget 的花费,确认在配置周期到达后预算能恢复、请求不再持续返回 429,且恢复时机与 budget_duration 一致,而不是固定等到 30 天窗口滚动。对于自行修改代码的情况,还需运行针对该行为的回归测试,确认时长驱动窗口统计。由于 Issue 中给出的修复方案尚未确认发布,若当前版本仍表现为 30 天封顶,请以实际版本行为为准,并关注上游修复进展。

参考来源

BerriAI/litellm #31292

BerriAI/litellm PR #27488(fix: reset proxy budget when initial reset duration is null then updated)

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 28587

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注