mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
* fix(proxy): cache tag-name registry so unregistered request tags skip Postgres
Request tags are free-form attribution labels, so most have no LiteLLM_TagTable
row. get_tag_objects_batch never cached that absence: every tagged request ran
a find_many that came back empty, and under Prisma pool contention those
per-request queries queued for minutes inside user_api_key_auth.
Cache the bounded set of registered tag names under one aggregate key with the
management-object TTL. Uncached request tags are filtered against it before any
per-tag DB fetch, so unregistered tags cost zero DB reads on a warm path. An
empty registry is cached as a valid answer; DB errors are not cached and fall
back to the per-tag lookup; tables past TAG_REGISTRY_MAX_SIZE cache an overflow
sentinel that disables filtering. Tag create/update/delete endpoints now evict
the registry and per-tag keys and publish cross-worker invalidation (they
previously evicted nothing). The per-tag write-back also gains the management
TTL it was missing, and the hand-built tag:{name} key strings are replaced with
a shared builder.
* fix(proxy): skip per-request end-user DB reads via restricted-id registry
Every request carrying a user id ran get_end_user_object, and with high-cardinality
auto-created end-user rows (hundreds of thousands of ids, all restriction fields
NULL) the per-pod cache missed on nearly every request, so each one paid a Postgres
find_unique that queued behind the Prisma pool during background-job bursts. True
misses were never cached, and unknown ids paid the read twice per request.
Cache the bounded set of end-user ids that carry any restriction (blocked, budget,
region, default model, or object permission) under one aggregate key with the
management-object TTL. When an id misses the per-id cache and is absent from a
usable registry, get_end_user_object returns None with zero DB reads; restricted
ids keep today's fetch-and-cache path. The skip is bypassed whenever
litellm.max_end_user_budget_id is set (default budgets make unrestricted rows
behaviorally distinct from missing rows), validate_end_user_id_in_db is on
(existence checks need the row), or the token carries end_user_max_budget from
custom auth (the row's recorded spend seeds the budget counter). Empty registries
cache as a valid answer, DB errors are never cached, and oversized tables cache an
overflow sentinel that disables filtering. Customer create/update/block/delete now
evict the registry and per-id keys and publish cross-worker invalidation (they
previously evicted nothing), and the per-id write-back gains the management TTL it
was missing so Redis entries no longer live forever.
* refactor(proxy): single generic registry loader with error sentinel and single-flight
Code review follow-ups on the two registry caches. Registry DB errors now cache
the overflow sentinel for a short REGISTRY_ERROR_NEGATIVE_CACHE_TTL window and
log at warning, so a degraded Postgres stops paying the failing registry scan on
every request on top of the per-id fallback. Cold registry loads are single-flight
per worker behind per-registry locks with a recheck after acquire, so a TTL expiry
no longer fans out one full-table scan per in-flight request. The tag and end-user
loaders collapse into one _load_bounded_registry with per-entity fetch closures,
and the triplicated evict-then-broadcast protocol becomes one evict_and_broadcast
helper beside publish_auth_cache_invalidation, shared by the tag, customer, and
project eviction paths.
* chore(lint): suppress fail-safe registry excepts and ratchet BLE001 budget
* docs(proxy): trim registry cache commentary to single-line why docstrings
* fix(lint): move tag fetch return to else block to satisfy TRY300 budget
|
||
|---|---|---|
| .. | ||
| management_v1 | ||
| policy_endpoints | ||
| scim | ||
| search_endpoints | ||
| usage_endpoints | ||
| test_access_group_endpoints.py | ||
| test_access_group_management.py | ||
| test_activity_tenant_scoping.py | ||
| test_auto_router_endpoints.py | ||
| test_budget_endpoints.py | ||
| test_cache_settings_endpoints.py | ||
| test_callback_management_endpoints.py | ||
| test_common_daily_activity.py | ||
| test_common_utils.py | ||
| test_compliance_endpoints.py | ||
| test_config_override_endpoints.py | ||
| test_coordination_redis_endpoints.py | ||
| test_cost_tracking_settings.py | ||
| test_credential_migration.py | ||
| test_customer_budget.py | ||
| test_customer_endpoints.py | ||
| test_delete_callbacks_endpoint.py | ||
| test_delete_verification_tokens_failed.py | ||
| test_encryption_endpoints.py | ||
| test_entraid_app_roles.py | ||
| test_gateway_request_endpoints.py | ||
| test_internal_user_endpoints.py | ||
| test_key_management_endpoints.py | ||
| test_mcp_management_endpoints.py | ||
| test_model_management_endpoints.py | ||
| test_org_admin_team_access.py | ||
| test_organization_endpoints.py | ||
| test_policy_endpoints.py | ||
| test_project_org_authz.py | ||
| test_ptu_model_settings.py | ||
| test_router_settings_endpoints.py | ||
| test_saml_sso.py | ||
| test_tag_management_endpoints.py | ||
| test_team_callback_endpoints.py | ||
| test_team_default_params.py | ||
| test_team_endpoints.py | ||
| test_team_model_alias_merge.py | ||
| test_tool_management_endpoints.py | ||
| test_ui_sso.py | ||
| test_workflow_management_endpoints.py | ||