mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-04 07:27:51 +00:00
* fix(proxy): charge budget windows when the cached key or team expired before the request ended The post-call spend update reads a key's or team's budget_limits from user_api_key_cache and returned early on a miss, skipping both the window counter increment and the LiteLLM_BudgetWindowSpend row. The cached object expires after user_api_key_cache_ttl (60s by default), so any request that ran longer than that without another request refreshing the entry was counted in the key's lifetime spend but never in its budget windows. With budget reservation disabled nothing else charges the windows, so keys kept running past their window caps On a miss the update now reads budget_limits straight from the key or team row. It does not re-cache the object, since a write from the spend path could race a /key/delete and put a just-deleted key back into the auth cache * test(proxy): assert the budget window fallback never re-caches the key or team * fix(proxy): read a missing key or team row once per cache TTL in the budget window fallback The master key and UI session tokens are logged under names no key row carries, so every one of their requests missed the auth cache and read the database. A missing row is now remembered for the cache TTL in this process only. A failed read is not remembered, and a row that exists is read fresh on every miss so a key update is never served stale. * fix(proxy): skip the budget window row read for a key or team with no windows The fallback remembered only a missing row, so a key or team that exists but holds no budget_limits was read from the database on every request that outlived the key cache. It now remembers both cases under one cache key built in user_api_key_cache.py, for the same TTL as the auth cache * fix(proxy): keep no-window markers in their own cache and clear them when an update adds windows Markers for keys and teams with no budget windows lived in the shared 200-entry auth cache, so a burst of late costs could evict cached teams and users. They now live in a dedicated in-memory cache on UserApiKeyCache, reached by local and broadcast evictions. /key/update and /team/update now evict the marker on every worker, so a late cost after an update charges the windows the update added. * test(proxy): give the spend counter tests the proxy's real key cache and type the window spend helper * fix(proxy): keep a row read that an update outran from restoring the no-window marker * fix(proxy): clear finished no-window reads and evict a marker-shaped user id from both caches * fix(proxy): apply other spend counters before a window row read and let no-window notes follow the key cache settings --------- Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| html_forms | ||
| __init__.py | ||
| test_admin_ui_utils.py | ||
| test_auth_cache_invalidation_pubsub.py | ||
| test_cache_aware_routing.py | ||
| test_cache_codec.py | ||
| test_callback_config_validation.py | ||
| test_callback_utils.py | ||
| test_check_batch_cost.py | ||
| test_check_responses_cost.py | ||
| test_codex_model_catalog.py | ||
| test_config_sync_pubsub.py | ||
| test_credential_hydration.py | ||
| test_custom_openapi_spec.py | ||
| test_debug_utils.py | ||
| test_discoverable_model_filter.py | ||
| test_encrypt_decrypt_utils.py | ||
| test_error_body_call_id.py | ||
| test_expired_ui_session_key_cleanup_manager.py | ||
| test_get_routes.py | ||
| test_http_parsing_utils.py | ||
| test_json_merge_patch.py | ||
| test_key_rotation_e2e.py | ||
| test_key_rotation_integration.py | ||
| test_key_rotation_lock.py | ||
| test_key_rotation_manager.py | ||
| test_load_config_utils.py | ||
| test_model_deprecation.py | ||
| test_model_listing_utils.py | ||
| test_openai_endpoint_utils.py | ||
| test_openai_error_payload.py | ||
| test_openapi_route.py | ||
| test_openapi_schema_compat.py | ||
| test_periodic_reload_schedule.py | ||
| test_proxy_encrypt_decrypt.py | ||
| test_rbac_utils.py | ||
| test_realtime_cache.py | ||
| test_registry_read_through.py | ||
| test_request_tag_mappings.py | ||
| test_reset_budget_job.py | ||
| test_resource_ownership.py | ||
| test_scheduled_job_stagger.py | ||
| test_semantic_text_index.py | ||
| test_slow_gc_logger.py | ||
| test_sse_keepalive.py | ||
| test_static_asset_utils.py | ||
| test_swagger_utils.py | ||
| test_timezone_utils.py | ||
| test_token_count_log.py | ||
| test_token_count_settings.py | ||
| test_upsert_budget_membership.py | ||
| test_user_api_key_cache.py | ||
| test_validation_error_body.py | ||