![[Bug]: Unstable offset pagination in get_daily_activity (order by date only) yields non-deterministic, inflated spend totals](https://www.chat-gpts.plus/wp-content/uploads/2026/06/30164-a13afb53.jpg)
[Bug]: Unstable offset pagination in get_daily_activity (order by date only) yields non-deterministic, inflated spend totals
快速结论:该报错通常发生在调用 /team/daily/activity 或 /user/daily/activity 获取分页消费数据时,返回的 spend 合计值随 page_size 变化,甚至相同请求两次结果不同。优先确认 litellm/proxy/management_endpoints/common_daily_activity.py 中 get_daily_activity 函数的排序字段是否包含 id 作为唯一性 tiebreaker。
问题场景
在 LiteLLM 中通过 REST API /user/daily/activity 或 /team/daily/activity 查询用户或团队的日常消费数据时,客户端需要分页遍历所有结果并汇总 metrics.spend。当某天的行数超过单页大小时(例如一个繁忙的租户每天有数千条请求记录),使用偏移分页(offset pagination)且仅按 date 排序会导致非确定性结果。
报错原文
/team/daily/activity returned non-deterministic results for the same date range:
page_size=1000 run 1: 15,231.91
page_size=1000 run 2: 13,977.13
Correct total (via aggregated endpoint or single large page): 13,977.13
Summed totals vary by page_size:
page_size 50: 13,990.72
page_size 100: 16,393.02
page_size 250: 13,955.38
page_size 500: 13,977.13
page_size 1000: 13,977.13 (but non-deterministic on re-run)
page_size 5000: 13,977.13
原因分析
问题根源在 litellm/proxy/management_endpoints/common_daily_activity.py 的 get_daily_activity 函数中,数据查询使用了偏移分页,但排序键仅包含 date 字段。由于 date 并非唯一键(同一天内有多行,每行对应不同的 api_key、model 等),偏移分页的排序结果是不确定性的。这会导致不同查询之间的行顺序不一致:一些行被跳过(导致汇总不足),另一些行在多个页面中被重复返回(导致汇总过度)。结果值依赖于 page_size 和查询时间。
环境排查
- LiteLLM 版本:已验证在 v1.88.1、v1.88.2、v1.89.2 以及 main 分支上均可复现。
- 数据量:当某天的行数超过单页大小时(例如每天数千行),问题易触发。
- 依赖:确保
litellm包和相关数据库(如 PostgreSQL)版本一致。
解决步骤
- 打开文件
litellm/proxy/management_endpoints/common_daily_activity.py,定位到get_daily_activity函数中的find_many调用。 - 找到
order参数,当前为[{"date": "desc"}]。 - 添加唯一性 tiebreaker 字段:将
order修改为[{"date": "desc"}, {"id": "asc"}],其中id是LiteLLM_DailyUserSpend和LiteLLM_DailyTeamSpend表中的主键(类型为String @id @default(uuid()))。 - 保存文件并重启 LiteLLM 服务。
注意:尽管 PR #30167 中已包含此修复,但实际发布版本中该变更未被合并。如果上述修改不存在,请手动执行。另外,/team/daily/activity/aggregated 端点目前返回 404(缺少汇总端点),该问题作为后续关注事项。
验证方法
对同一数据和相同日期范围执行以下测试:
- 使用不同的
page_size(如 50、100、500、1000)多次调用/team/daily/activity,汇总所有页面的metrics.spend,确认结果稳定且与/user/daily/activity/aggregated返回的值一致。 - 反复执行同一请求(例如
page_size=1000),确认结果不再变化。 - 检查日志或单元测试(如
test_get_daily_activity_order_has_id_tiebreaker)是否存在。



