[Fix] /key/aliases: Add pagination and search to prevent OOMs - #22137
Conversation
The /key/aliases endpoint previously fetched all key aliases from the database without limit, causing OOM crashes with large key sets. Added page, size, and search query parameters with database-level filtering to enable paginated and searchable key alias retrieval. Updated the response to include pagination metadata (total_count, current_page, total_pages, size) matching the /v2/model/info pattern. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes an OOM risk in the
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| litellm/proxy/management_endpoints/key_management_endpoints.py | Replaces unbounded ORM query with paginated raw SQL using parameterized queries. Correctly computes parameter indices for LIMIT/OFFSET. Minor issue: ILIKE wildcard chars in search input are not escaped. |
| tests/proxy_unit_tests/test_key_generate_prisma.py | Updated existing integration tests to match new paginated response shape and added search parameter test cases. |
| tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py | Added 4 mock-based unit tests covering response shape, pagination math, ILIKE search filtering, and no-search case. All tests use AsyncMock (no real network calls). |
Sequence Diagram
sequenceDiagram
participant Client
participant KeyAliasesEndpoint as /key/aliases
participant PostgreSQL as PostgreSQL DB
Client->>KeyAliasesEndpoint: GET /key/aliases?page=1&size=50&search=my-key
KeyAliasesEndpoint->>PostgreSQL: SELECT COUNT(*) ... WHERE key_alias ILIKE $2
PostgreSQL-->>KeyAliasesEndpoint: total_count
KeyAliasesEndpoint->>PostgreSQL: SELECT key_alias ... WHERE key_alias ILIKE $2 LIMIT $3 OFFSET $4
PostgreSQL-->>KeyAliasesEndpoint: alias rows (key_alias only)
KeyAliasesEndpoint-->>Client: { aliases, total_count, current_page, total_pages, size }
Last reviewed commit: 386c148
| rows = await prisma_client.db.litellm_verificationtoken.find_many( | ||
| where=where, | ||
| order=[{"key_alias": "asc"}], | ||
| skip=(page - 1) * size, | ||
| take=size, | ||
| ) |
There was a problem hiding this comment.
Fetching full rows when only key_alias is needed
This query fetches all columns of LiteLLM_VerificationToken (which includes large fields like metadata, permissions, etc.) when only key_alias is needed. Since this endpoint is specifically designed to prevent OOM issues, consider using Prisma's include or restructuring to only retrieve the key_alias column. With large key sets, retrieving full rows at page size 100 may still use significantly more memory than necessary.
Add select={"key_alias": True} to the find_many call so only the alias
column is fetched from the database instead of full token rows. Add
five unit tests in test_key_management_endpoints.py covering response
shape, pagination skip/take computation, search filter injection,
absence of contains filter when no search term is given, and the
select-only-alias optimization.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
LiteLLM_VerificationTokenActions.find_many() does not support the select keyword argument. Remove it and drop the corresponding test. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Replace Prisma ORM count/find_many calls with two query_raw calls that only project the key_alias column. The Prisma client wrapper does not support SELECT projection via find_many, so raw SQL is used to keep memory usage proportional to the page size rather than total key count. Update tests to mock query_raw instead of count/find_many. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Additional Comments (1)
If a user passes a Consider escaping these characters before wrapping with |
Replace the non-paginated Key Alias filter with a new PaginatedKeyAliasSelect component that mirrors the existing PaginatedModelSelect pattern. This aligns the UI with the paginated /key/aliases endpoint from PR #22137. Changes: - Added useInfiniteKeyAliases hook for paginated key alias fetching - Created PaginatedKeyAliasSelect component with infinite scroll (80% threshold) - Updated keyAliasesCall in networking to accept page/size/search params - Replaced Key Alias filter in Request Logs and Virtual Keys tables to use customComponent - Removed fetchAllKeyAliases helper and related upfront fetching logic - Added 22 tests for new component and hook; all existing tests pass (54 tests) Fixes the issue where the UI was fetching all key aliases at once, causing performance issues with large key sets. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Replace the non-paginated Key Alias filter with a new PaginatedKeyAliasSelect component that mirrors the existing PaginatedModelSelect pattern. This aligns the UI with the paginated /key/aliases endpoint from PR #22137. Changes: - Added useInfiniteKeyAliases hook for paginated key alias fetching - Created PaginatedKeyAliasSelect component with infinite scroll (80% threshold) - Updated keyAliasesCall in networking to accept page/size/search params - Replaced Key Alias filter in Request Logs and Virtual Keys tables to use customComponent - Removed fetchAllKeyAliases helper and related upfront fetching logic - Added 22 tests for new component and hook; all existing tests pass (54 tests) Fixes the issue where the UI was fetching all key aliases at once, causing performance issues with large key sets. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Replace the non-paginated Key Alias filter with a new PaginatedKeyAliasSelect component that mirrors the existing PaginatedModelSelect pattern. This aligns the UI with the paginated /key/aliases endpoint from PR BerriAI#22137. Changes: - Added useInfiniteKeyAliases hook for paginated key alias fetching - Created PaginatedKeyAliasSelect component with infinite scroll (80% threshold) - Updated keyAliasesCall in networking to accept page/size/search params - Replaced Key Alias filter in Request Logs and Virtual Keys tables to use customComponent - Removed fetchAllKeyAliases helper and related upfront fetching logic - Added 22 tests for new component and hook; all existing tests pass (54 tests) Fixes the issue where the UI was fetching all key aliases at once, causing performance issues with large key sets.
[Fix] /key/aliases: Add pagination and search to prevent OOMs
Summary
The `/key/aliases` endpoint previously fetched all key aliases from the database without limit, causing out-of-memory crashes with large key sets. This fix adds pagination and search parameters to the endpoint, moving filtering and pagination to the database level.
Changes
Added `page`, `size`, and `search` query parameters to `/key/aliases`. Replaced the unbounded database query with `count` + `find_many` using `skip`/`take` and case-insensitive `contains` filtering via Prisma. Added `select={"key_alias": True}` so only the alias column is fetched instead of full token rows. Response now includes pagination metadata (`total_count`, `current_page`, `total_pages`, `size`) matching the `/v2/model/info` pattern. Added five unit tests in `tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py` covering response shape, pagination, search filter injection, and the select-only-alias optimization.
Type
🐛 Bug Fix
✅ Test