litellm/tests/e2e/quota_management/budgets/BUDGET_CODE_MATRIX.md

7.1 KiB

Budget Code Matrix

What LiteLLM actually implements for budgets: every entity that can carry a dollar budget, how the limit is enforced, and where in the code it happens. This is the "what we support" reference; the companion BUDGET_TEST_COVERAGE_MATRIX.md maps each row to its tests and the e2e gaps.

Over-budget surfaces as a budget_exceeded error (the live suite tests/otel_tests/test_e2e_budgeting.py asserts type == "budget_exceeded", code == "429"); the underlying BudgetExceededError is defined in litellm/exceptions.py (status_code=400). Enforcement runs in common_checks() / auth_checks.py at auth time, plus pre-call reservation in budget_reservation.py.

Legend for "Enforced": block = request rejected; filter = router skips the deployment; alert = notify only, request proceeds.


1. Per-entity dollar budgets

Entity Budget stored Hard max_budget Soft budget Per-window Model budget Reset by budget_duration
API key LiteLLM_VerificationToken (direct cols + budget_id FK) block (_virtual_key_max_budget_check) alert (_virtual_key_soft_budget_check) + 80% alert block (_virtual_key_multi_budget_check) block (model_max_budget_limiter.is_key_within_model_budget) keys reset job
Internal user LiteLLM_UserTable (direct cols) block (common_checks, only when not on a team) - - via model_max_budget json users reset job
Team LiteLLM_TeamTable (direct cols) block (_team_max_budget_check) alert (_team_soft_budget_check) block (_team_multi_budget_check) via model_max_budget teams reset job
Team member LiteLLM_TeamMembership -> LiteLLM_BudgetTable block (_check_team_member_budget) - - - budget-table reset job
End-user / customer LiteLLM_EndUserTable -> LiteLLM_BudgetTable block (_check_end_user_budget) - - block (is_end_user_within_model_budget) budget-table reset job
Organization LiteLLM_OrganizationTable -> LiteLLM_BudgetTable block (_organization_max_budget_check) - - via budget-table budget-table reset job
Tag LiteLLM_TagTable -> LiteLLM_BudgetTable block (_tag_max_budget_check) - - via budget-table budget-table reset job
Project LiteLLM_ProjectTable -> LiteLLM_BudgetTable block (_project_max_budget_check) alert (_project_soft_budget_check) - - budget-table reset job
Provider (router) config provider_budget_config (in-memory) filter (router_strategy/budget_limiter) - yes (time window) - window TTL
Global proxy litellm.max_budget (config) block (_global_proxy_budget_check) - - - -

Notes / flags from the code:

  • User budget only enforced off-team: common_checks skips the personal-user budget when the key belongs to a team (team budget governs instead).
  • Comparison operators are inconsistent: key/user use >=, team/end-user main budget use >. Spend exactly at max_budget blocks a key but not a team.
  • Provider budgets are filter-only: an over-budget provider is removed from routing; if all are over budget the router raises no_deployments_with_provider_budget_routing (not a per-entity block).
  • Enforcement timing differs by entity: key / user / org / team-member / tag / model enforce off real-time reservation counters (block within ~2 calls); end-user enforcement reads EndUserTable.spend, which only updates on the proxy_batch_write_at flush, so it lags by that interval (verified live).

2. Budget mechanisms

Mechanism What it does Code
Pre-call reservation Estimates max request cost, atomically reserves against redis spend counters for key/team/user/end_user/tag/team_member/org before the call; blocks if a counter would exceed spend_tracking/budget_reservation.py
Post-call reconciliation Adjusts the reservation to the actual cost once known reconcile_budget_reservation
Read-time enforcement Auth-time check of current spend vs max_budget auth_checks.common_checks + per-entity _*_max_budget_check
Soft budget / alerts At soft_budget (or 80% of max) fire Slack/email alert, do not block _virtual_key_soft_budget_check, _team_soft_budget_check, budget_alerts
Multi-window budgets budget_limits list of {budget_duration, max_budget}; each window enforced + reset independently _virtual_key_multi_budget_check, reset_budget_windows
Model-level budgets model_max_budget dict (per model: budget_limit + time_period) on key/user/end_user hooks/model_max_budget_limiter.py
Reset by duration Job zeros spend, recomputes budget_reset_at = now + duration_in_seconds(budget_duration), invalidates redis counters common_utils/reset_budget_job.py, duration_parser.duration_in_seconds
Zero-cost bypass Models with no configured price bypass budget reservation budget_reservation zero-cost path

3. Budget management surface (endpoints)

Action Endpoint Handler
Create budget POST /budget/new new_budget
Update budget POST /budget/update update_budget
Budget info POST /budget/info ({"budgets": [id]}) info_budget
Budget settings GET /budget/settings budget_settings
List budgets GET /budget/list list_budget
Delete budget POST /budget/delete ({"id": id}) delete_budget
Set on key POST /key/generate, /key/update (max_budget, soft_budget, budget_duration, model_max_budget, budget_id) key mgmt
Set on user POST /user/new (max_budget, budget_duration) internal user
Set on team POST /team/new (max_budget, soft_budget, team_member_budget) team
Set on team member POST /team/member_add (max_budget_in_team) team
Set on org POST /organization/new (max_budget, soft_budget, model_max_budget) org
Set on customer POST /customer/new, /customer/update (max_budget, budget_id) customer
Set on tag POST /tag/new, /tag/update (max_budget) tag mgmt
Read budget+spend /key/info, /user/info, /team/info, /organization/info, /customer/info, /budget/info per-entity info

Endpoint method/shape gotchas verified live: /organization/delete is DELETE with {"organization_ids": [id]}; /budget/info takes {"budgets": [id]}; model_max_budget entries use {"budget_limit", "time_period"}.

4. Config knobs

Setting Effect
litellm.max_budget proxy-wide hard cap (global proxy budget)
max_internal_user_budget / default_max_internal_user_budget default max_budget for internal users
internal_user_budget_duration default reset duration for internal users
max_end_user_budget / max_end_user_budget_id default budget for end-users
default_team_params default max_budget / budget_duration / limits for teams
provider_budget_config (router) per-provider spend caps + windows