快速结论:这个报错发生在 LiteLLM 进程优雅关闭时,内存队列中尚未写入数据库的 SpendLogs 行会被静默丢弃。优先排查 LiteLLM 版本,若在 v1.97.0 及更早版本,升级到 v1.98.0 或更高版本即可修复。
适用环境:LiteLLM v1.97.0(官方 ghcr.io/berriai/litellm 镜像,Azure Container Apps),NUM_WORKERS=2,MAX_REQUESTS_BEFORE_RESTART=10000,proxy_batch_write_at: 60。修复已在 v1.98.0 GA 及 v1.99.0-rc.1 中验证。
最快修复方案:将 LiteLLM 升级到 v1.98.0 或更高版本。该版本已合入修复(PR #34826),在 ASGI lifespan 关闭阶段调用 _flush_spend_logs_queue_on_shutdown() 排空内存队列。
注意事项:修复不覆盖内存中的聚合 spend 队列(db_update_spend_transaction_handler 路径),每日/密钥/团队/组织 spend 计数器在关闭时仍可能丢失一个 flush 窗口的数据;该问题在 redis-buffer 模式和直接模式下均存在。
问题场景
在 LiteLLM 代理服务中,当 Kubernetes/Container Apps 滚动更新、缩容,或 uvicorn 通过 –max_requests_before_restart 触发 worker 回收时,进程优雅关闭而 SpendLogs 数据尚未刷入数据库,导致这部分数据静默丢失。用户实测在 45,000 次请求中丢失了 317 行(0.7%),客户端全部返回 HTTP 200,无任何报错日志。
报错原文
[Bug]: proxy_shutdown_event never drains spend_log_transactions — graceful shutdown (worker recycle, deploy) silently loses queued SpendLogs rows
原因分析
LiteLLM 的 proxy_shutdown_event(位于 proxy_server.py 约 L830,v1.97.0)在关闭时只处理了 gateway-request 计数和 langfuse 队列,随后直接调用 prisma_client.disconnect()——并未排空内存中的 spend_log_transactions 队列。该队列由 DBSpendUpdateWriter._insert_spend_log_to_db 每请求追加,由 update_spend 按 proxy_batch_write_at(默认 10 秒)周期刷入 Postgres。shutdown 钩子没有触发这个 flush,导致队列中未落库的行被直接丢弃。tool_usage_transactions 和 autorouter_turn_transactions 队列存在同样的缺口。设置 use_redis_transaction_buffer: true 无法解决此问题,因为它只迁移了聚合 spend 队列到 Redis,SpendLogs 行仍保留在进程本地。
环境排查
- 确认 LiteLLM 版本:v1.97.0 及更早版本存在此问题;v1.98.0 GA 及以上版本已修复
- 检查 proxy_batch_write_at 配置:该值越大(如 60 秒),关闭时潜在丢失的数据窗口越大(60 秒 = 默认暴露量的 6 倍)
- 确认使用场景:Kubernetes/Container Apps 滚动更新、缩容、uvicorn worker 回收(–max_requests_before_restart)都会触发关闭路径
- 验证 NUM_WORKERS 和 MAX_REQUESTS_BEFORE_RESTART 设置是否导致频繁 worker 回收
解决步骤
- 升级 LiteLLM 到 v1.98.0 或更高版本(修复合入于 PR #34826,2026-08-13 合并)。lifespan 关闭现已在 prisma_client.disconnect() 之前调用 _flush_spend_logs_queue_on_shutdown() → drain_spend_logs_queue()。
- 验证修复行为:drain 会取消队列监控任务,循环调用 update_spend_logs_job(最多 MAX_SPEND_LOG_DRAIN_ITERATIONS = 20 次),直到 _total_queued_spend_transactions 报告为 0,如有剩余会记录错误日志。
- 确认 sibling 队列(tool_usage_transactions 和 autorouter_turn_transactions)同样被覆盖:update_spend_logs_job 在同一轮中排空这两个队列,_total_queued_spend_transactions 计数包含所有三个队列。
- 若无法升级,可考虑调小 proxy_batch_write_at 以缩小每个进程关闭时丢失的数据窗口(这是缓解方案,不是完整修复)。
验证方法
升级到 v1.98.0+ 后,在相同负载和配置下运行压测,对比 LiteLLM_SpendLogs 表实际行数与客户端请求数。或检查关闭日志中是否有 drain 过程的相关输出。由于修复并没有输出确认日志(仅在有剩余时才记录错误),最可靠的验证是确认版本号≥1.98.0,并确认升级后同样的场景不再丢失 SpendLogs 行。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


