From 54dd6d2cbf8668d5f218775803b4e7e26631e02e Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Wed, 28 Oct 2026 12:19:37 -0700 Subject: [PATCH] perf(spend-logs): index the error code with the time so the error code filter reads only matching rows --- db_scripts/partition_spend_logs.sql | 4 ++-- .../litellm_proxy_extras/request_log_indexes.py | 4 ++-- .../database/migrations/test_request_log_indexes.py | 10 +++++----- .../database/test_request_log_indexes_at_boot.py | 2 +- .../integration/spend/test_spend_log_error_filters.py | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/db_scripts/partition_spend_logs.sql b/db_scripts/partition_spend_logs.sql index 34dbcabedcf..28107f28043 100644 --- a/db_scripts/partition_spend_logs.sql +++ b/db_scripts/partition_spend_logs.sql @@ -57,8 +57,8 @@ ALTER INDEX IF EXISTS "LiteLLM_SpendLogs_api_key_startTime_idx" RENAME TO "LiteLLM_SpendLogs_legacy_api_key_startTime_idx"; ALTER INDEX IF EXISTS "LiteLLM_SpendLogs_litellm_call_id_idx" RENAME TO "LiteLLM_SpendLogs_legacy_litellm_call_id_idx"; -ALTER INDEX IF EXISTS "LiteLLM_SpendLogs_error_startTime_idx" - RENAME TO "LiteLLM_SpendLogs_legacy_error_startTime_idx"; +ALTER INDEX IF EXISTS "LiteLLM_SpendLogs_error_code_startTime_idx" + RENAME TO "LiteLLM_SpendLogs_legacy_error_code_startTime_idx"; CREATE TABLE "LiteLLM_SpendLogs" ( LIKE "LiteLLM_SpendLogs_legacy" INCLUDING DEFAULTS INCLUDING GENERATED diff --git a/litellm-proxy-extras/litellm_proxy_extras/request_log_indexes.py b/litellm-proxy-extras/litellm_proxy_extras/request_log_indexes.py index d34c4d18c95..6a261a22d8f 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/request_log_indexes.py +++ b/litellm-proxy-extras/litellm_proxy_extras/request_log_indexes.py @@ -70,8 +70,8 @@ REQUEST_LOG_INDEXES: Final = ( RequestLogIndex("LiteLLM_SpendLogs", "LiteLLM_SpendLogs_litellm_call_id_idx", '("litellm_call_id")'), RequestLogIndex( "LiteLLM_SpendLogs", - "LiteLLM_SpendLogs_error_startTime_idx", - '("startTime")', + "LiteLLM_SpendLogs_error_code_startTime_idx", + "((metadata->'error_information'->>'error_code'), \"startTime\")", "jsonb_typeof(metadata->'error_information') = 'object'", ), ) diff --git a/tests/integration/database/migrations/test_request_log_indexes.py b/tests/integration/database/migrations/test_request_log_indexes.py index 805663ff9fa..5ab0e954890 100644 --- a/tests/integration/database/migrations/test_request_log_indexes.py +++ b/tests/integration/database/migrations/test_request_log_indexes.py @@ -44,7 +44,7 @@ API_KEY_INDEX_MIGRATION: Final = "20260823000000_add_spend_logs_api_key_starttim CALL_ID_INDEX_MIGRATION: Final = "20260831120001_spend_logs_litellm_call_id_index" API_KEY_INDEX: Final = "LiteLLM_SpendLogs_api_key_startTime_idx" CALL_ID_INDEX: Final = "LiteLLM_SpendLogs_litellm_call_id_idx" -ERROR_INDEX: Final = "LiteLLM_SpendLogs_error_startTime_idx" +ERROR_INDEX: Final = "LiteLLM_SpendLogs_error_code_startTime_idx" START_TIME_INDEX: Final = "LiteLLM_SpendLogs_startTime_idx" PARTITIONED_PARENT_ERROR: Final = 'cannot create index on partitioned table "LiteLLM_SpendLogs" concurrently' ORIGINAL_MIGRATION_SQL: Final = MappingProxyType( @@ -311,7 +311,7 @@ def test_a_partitioned_spend_logs_upgrade_builds_every_index_per_partition_and_a _assert_index_covers_every_partition(partitioned_database, API_KEY_INDEX, "api_key_startTime_idx") _assert_index_covers_every_partition(partitioned_database, CALL_ID_INDEX, "litellm_call_id_idx") - _assert_index_covers_every_partition(partitioned_database, ERROR_INDEX, "error_startTime_idx") + _assert_index_covers_every_partition(partitioned_database, ERROR_INDEX, "error_code_startTime_idx") ledger: Final = _assert_every_ledger_row_is_finished(partitioned_database) _assert_no_pending_migrations(partitioned_database) oids: Final = _index_oids(partitioned_database) @@ -346,7 +346,7 @@ def test_a_plain_spend_logs_upgrade_builds_every_index_and_a_second_job_run_rebu assert _index_validity(scratch_database, "api_key_startTime_idx") == {API_KEY_INDEX: True} assert _index_validity(scratch_database, "litellm_call_id_idx") == {CALL_ID_INDEX: True} - assert _index_validity(scratch_database, "error_startTime_idx") == {ERROR_INDEX: True} + assert _index_validity(scratch_database, "error_code_startTime_idx") == {ERROR_INDEX: True} _assert_every_ledger_row_is_finished(scratch_database) _assert_no_pending_migrations(scratch_database) oids: Final = _index_oids(scratch_database) @@ -573,11 +573,11 @@ def test_partitioning_a_table_the_index_job_already_covered_moves_its_indexes_as _indexed_table(scratch_database, "LiteLLM_SpendLogs_legacy_litellm_call_id_idx") == "LiteLLM_SpendLogs_legacy" ) assert ( - _indexed_table(scratch_database, "LiteLLM_SpendLogs_legacy_error_startTime_idx") == "LiteLLM_SpendLogs_legacy" + _indexed_table(scratch_database, "LiteLLM_SpendLogs_legacy_error_code_startTime_idx") == "LiteLLM_SpendLogs_legacy" ) assert ensure_request_log_indexes(scratch_database, "public") is True _assert_index_covers_every_partition(scratch_database, CALL_ID_INDEX, "litellm_call_id_idx") - _assert_index_covers_every_partition(scratch_database, ERROR_INDEX, "error_startTime_idx") + _assert_index_covers_every_partition(scratch_database, ERROR_INDEX, "error_code_startTime_idx") @requires_db diff --git a/tests/integration/database/test_request_log_indexes_at_boot.py b/tests/integration/database/test_request_log_indexes_at_boot.py index eec9819770c..92c3b3f62ef 100644 --- a/tests/integration/database/test_request_log_indexes_at_boot.py +++ b/tests/integration/database/test_request_log_indexes_at_boot.py @@ -44,7 +44,7 @@ INDEXES_IN_PLACE: Final = "Request-log indexes are all in place" INDEX_BUILD_LINES: Final = ("Building index", "Attached index") BUILD_SECONDS: Final = 60 ORIGINAL_SPEND_LOGS_INDEXES: Final = ("LiteLLM_SpendLogs_api_key_startTime_idx", "LiteLLM_SpendLogs_litellm_call_id_idx") -SPEND_LOGS_INDEXES: Final = (*ORIGINAL_SPEND_LOGS_INDEXES, "LiteLLM_SpendLogs_error_startTime_idx") +SPEND_LOGS_INDEXES: Final = (*ORIGINAL_SPEND_LOGS_INDEXES, "LiteLLM_SpendLogs_error_code_startTime_idx") POPULATED_PARTITIONS: Final = MappingProxyType( { "LiteLLM_SpendLogs_p2026_08": ("2026-08-01", "2026-09-01"), diff --git a/tests/integration/spend/test_spend_log_error_filters.py b/tests/integration/spend/test_spend_log_error_filters.py index 85ed605c393..04f20bb115f 100644 --- a/tests/integration/spend/test_spend_log_error_filters.py +++ b/tests/integration/spend/test_spend_log_error_filters.py @@ -15,7 +15,7 @@ from psycopg.types.json import Jsonb pytestmark: Final = pytest.mark.timeout(240) -ERROR_INDEX: Final = "LiteLLM_SpendLogs_error_startTime_idx" +ERROR_INDEX: Final = "LiteLLM_SpendLogs_error_code_startTime_idx" INDEXES_IN_PLACE: Final = "Request-log indexes are all in place" SUCCESS_ROWS: Final = 5000