Skip to content

litellm-community: the SpendLogs pruner is not running — retention window grows monotonically #44

Description

@sre-helmcode

What

litellm-community is configured to keep 2 days of LiteLLM_SpendLogs and prune daily. It is not pruning. The oldest row has not moved in over 24 hours of observation and the table's span keeps growing.

Config, confirmed live inside the pod (/etc/litellm/, not just in git):

maximum_spend_logs_retention_period: 2d
maximum_spend_logs_retention_interval: 1d

Observed:

when min(startTime) span rows
2026-09-08 ~22:00Z 2026-09-05 19:33:22.833 3d 02:45 1,404,423
2026-09-09 07:46Z 2026-09-05 19:33:22.833 3d 12:13 1,581,290
2026-09-09 08:47Z 2026-09-05 19:33:22.833 3d 13:14 1,600,008

Same oldest row throughout. With a 2-day period and a 1-day interval it should have been purged on 2026-09-07. No cleanup activity in the proxy logs.

Enterprise, for contrast, is pruning: 7d configured, span measured at exactly 7d (2026-09-02 → 2026-09-09), and its row count fell from 82,021 to 59,483 during a few hours of observation. So the mechanism works somewhere; community specifically is not doing it.

Why it matters

  1. It extends a credential exposure window. Per LiteLLM community: member API keys are stored in cleartext in SpendLogs (secret_fields.raw_headers) #43, community stores members' Authorization: Bearer sk-... in cleartext in proxy_server_request in 99.87% of rows. The 2-day retention was the one thing bounding how many live keys sit in the table. It is not bounding anything.
  2. Unbounded growth. The table is at 1.6M rows and ~1,500 rows/minute of ingest with store_prompts_in_spend_logs: true, so rows are large. There is prior art on this exact database filling up (project_litellm_dailytagspend_bloat: DBs reached 179/97 GB).
  3. Every measurement taken against this table inherits a wrong window. nan-devops#289 had to correct "1 row in 30 days" to "the retained window"; the retained window is itself not what the config says. Anything derived from "we keep 2 days" is wrong.

Where to look

  • Whether the pruner task actually starts: it is a background job in the proxy, and community runs 10 replicas — check whether it is leader-elected, and whether whichever replica owns it is the one that keeps getting restarted.
  • Whether it errors silently. The DailyTagSpend bloat incident showed jobs on this database timing out without surfacing.
  • Whether the delete is too large to complete inside its window: 1.6M rows of full request bodies is a lot to remove in one pass, and per feedback_purga_masiva_postgres_cnpg the real ceiling here is WAL archiving to R2 and autovacuum, not the DELETE.

Do not fix by

Turning off store_prompts_in_spend_logs to shrink the rows. That is a separate decision (see #43 option 2) and it would mask this bug rather than fix it — the pruner would still not be running.

Evidence trail

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions