Skip to content

Revert "[Fix] Team Usage Spend Truncated Due to Pagination"#23028

Merged
yuneng-jiang merged 1 commit intomainfrom
revert-22938-litellm_fix_team_usage_spend
Mar 7, 2026
Merged

Revert "[Fix] Team Usage Spend Truncated Due to Pagination"#23028
yuneng-jiang merged 1 commit intomainfrom
revert-22938-litellm_fix_team_usage_spend

Conversation

@yuneng-jiang
Copy link
Collaborator

Reverts #22938

@vercel
Copy link

vercel bot commented Mar 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Building Building Preview, Comment Mar 7, 2026 7:23am

Request Review

@yuneng-jiang yuneng-jiang merged commit cb0d01f into main Mar 7, 2026
12 of 40 checks passed
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 7, 2026

Greptile Summary

This PR reverts #22938 ("Fix Team Usage Spend Truncated Due to Pagination"), re-introducing the original bug where /team/daily/activity returns inaccurate spend totals for teams with large datasets. Three significant regressions are introduced:

  • Spend truncation bug returns: get_team_daily_activity is switched back from get_daily_activity_aggregated (full SQL GROUP BY) to the paginated get_daily_activity (default 10 rows/page). The metadata.total_spend and all aggregate metrics are now computed only from the current page's rows — systematically understating real totals for busy teams.
  • timezone parameter silently dropped: The timezone query parameter is removed from the endpoint signature with no deprecation path. Existing callers that relied on timezone-adjusted date filtering will silently receive UTC-based results.
  • get_daily_activity_aggregated loses entity breakdown: The function now unconditionally passes entity_id_field=None, meaning it can no longer produce per-team/per-entity breakdowns even if needed by future callers.

The test that validated the aggregated-with-entity-breakdown behavior (test_get_team_daily_activity_uses_aggregated_with_entity_breakdown) is also removed, reducing test coverage for this critical path.

Confidence Score: 1/5

  • This PR reintroduces a known data-correctness bug and silently removes a previously-supported API parameter; it should not be merged without a clear justification and a plan to re-fix the original issue.
  • The revert re-introduces the pagination truncation bug where team spend totals are computed only from the current page (default 10 rows), making all aggregate metrics in the response inaccurate for teams with large datasets. It also silently removes the timezone parameter that was part of the API, breaking timezone-aware callers with no deprecation notice. Both are functional regressions with direct user-visible impact.
  • litellm/proxy/management_endpoints/team_endpoints.py requires the most attention — the switch back to paginated get_daily_activity is the root cause of the spend truncation regression.

Important Files Changed

Filename Overview
litellm/proxy/management_endpoints/team_endpoints.py Reverts to paginated get_daily_activity, reintroducing the spend truncation bug and silently dropping timezone parameter support.
litellm/proxy/management_endpoints/common_daily_activity.py Reverts _build_aggregated_sql_query and get_daily_activity_aggregated to always skip entity breakdown; list-based api_key filtering in the SQL builder also removed.
tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py Updates mocks to match reverted function names; removes the test that validated aggregated-with-entity-breakdown behavior, reducing coverage.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Endpoint as GET /team/daily/activity
    participant DB as litellm_dailyteamspend

    Note over Endpoint,DB: BEFORE revert (PR #22938 — correct)
    Client->>Endpoint: GET /team/daily/activity?team_ids=X&timezone=480
    Endpoint->>DB: SQL GROUP BY (all rows, no pagination)
    DB-->>Endpoint: ~2-3k aggregated rows
    Endpoint-->>Client: SpendAnalyticsPaginatedResponse (accurate totals, per-team breakdown)

    Note over Endpoint,DB: AFTER revert (this PR — buggy)
    Client->>Endpoint: GET /team/daily/activity?team_ids=X
    Endpoint->>DB: find_many(skip=0, take=10)
    DB-->>Endpoint: 10 rows (page 1 only)
    Endpoint-->>Client: SpendAnalyticsPaginatedResponse (truncated totals — rest of data ignored)
Loading

Comments Outside Diff (1)

  1. litellm/proxy/management_endpoints/team_endpoints.py, line 3884-3893 (link)

    Backward-incompatible removal of timezone parameter

    The timezone query parameter was removed from the endpoint signature. Any callers (UI or API consumers) that were already passing ?timezone=480 (or any offset) to /team/daily/activity will silently get UTC-based results instead of timezone-adjusted ones, with no error or warning. This is a silent data correctness regression — the date boundaries used for filtering will be wrong for users in non-UTC timezones.

    Per the repository's convention, removing a previously-supported parameter without a feature flag or deprecation period breaks existing behaviour for users relying on it.

Last reviewed commit: 034e83e

Comment on lines +4012 to 4025
return await get_daily_activity(
prisma_client=prisma_client,
table_name="litellm_dailyteamspend",
entity_id_field="team_id",
entity_id=team_ids_list,
entity_metadata_field=team_alias_metadata,
exclude_entity_ids=exclude_team_ids_list,
start_date=start_date,
end_date=end_date,
model=model,
api_key=final_api_key_filter,
exclude_entity_ids=exclude_team_ids_list,
timezone_offset_minutes=timezone,
include_entity_breakdown=True,
page=page,
page_size=page_size,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pagination truncation bug reintroduced

This revert switches get_team_daily_activity back to the paginated get_daily_activity, which only fetches page_size (default 10) rows from the database per request. The _aggregate_spend_records call inside get_daily_activity then computes totals (total spend, tokens, API requests, etc.) from only those paginated rows, not from the full dataset.

For teams with hundreds or thousands of rows in litellm_dailyteamspend (e.g. many models × many dates × many api keys), the metadata.total_spend and all other aggregate metrics in the response will be systematically understated — reflecting only the current page, not the true total. This is the exact bug PR #22938 was introduced to fix.

The correct approach is to use get_daily_activity_aggregated (which performs a SQL GROUP BY and returns all aggregated rows in one query), or to compute totals with a separate SUM() query over the full filtered result set before applying pagination.

# Before revert (correct):
return await get_daily_activity_aggregated(
    ...
    include_entity_breakdown=True,
)

# After revert (buggy — totals only reflect current page):
return await get_daily_activity(
    ...
    page=page,
    page_size=page_size,
)

Comment on lines 785 to 790
aggregated = await _aggregate_spend_records(
prisma_client=prisma_client,
records=records,
entity_id_field=entity_id_field if include_entity_breakdown else None,
entity_metadata_field=entity_metadata_field if include_entity_breakdown else None,
entity_id_field=None,
entity_metadata_field=None,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_daily_activity_aggregated loses all entity breakdown capability

After this revert, _aggregate_spend_records is always called with entity_id_field=None and entity_metadata_field=None, unconditionally. This means get_daily_activity_aggregated can never produce per-entity (per-team, per-user, per-org) spend breakdowns — even if a caller explicitly wants them.

The include_entity_breakdown parameter that controlled this was removed, and the function is now equivalent to the version before PR #22938 except that the SQL still correctly aggregates without the entity dimension in GROUP BY. Any future callers expecting entity-level breakdown from this function will silently get a flat aggregation instead.

If this revert is intentional as a short-term rollback, the entity breakdown capability should be restored before the next release.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant