From ccb6cd880aeedbf9f8bc0e63638c56a296f1f346 Mon Sep 17 00:00:00 2001 From: Alexsander Hamir Date: Wed, 10 Dec 2025 12:31:58 -0800 Subject: [PATCH] [Perf] - Cut memory leak in half (#17784) Stop passing references to large objects to fire-and-forget tasks. --- litellm/proxy/db/db_spend_update_writer.py | 15 ++++++++------- litellm/proxy/utils.py | 6 ------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/litellm/proxy/db/db_spend_update_writer.py b/litellm/proxy/db/db_spend_update_writer.py index 715a6ebd25d..97f5cb83439 100644 --- a/litellm/proxy/db/db_spend_update_writer.py +++ b/litellm/proxy/db/db_spend_update_writer.py @@ -6,6 +6,7 @@ Module responsible for """ import asyncio +import copy import json import os import random @@ -162,14 +163,14 @@ class DBSpendUpdateWriter: asyncio.create_task( self._update_tag_db( response_cost=response_cost, - request_tags=payload.get("request_tags"), + request_tags=copy.deepcopy(payload.get("request_tags")), prisma_client=prisma_client, ) ) if disable_spend_logs is False: await self._insert_spend_log_to_db( - payload=payload, + payload=copy.deepcopy(payload), prisma_client=prisma_client, ) else: @@ -179,34 +180,34 @@ class DBSpendUpdateWriter: asyncio.create_task( self.add_spend_log_transaction_to_daily_user_transaction( - payload=payload, + payload=copy.deepcopy(payload), prisma_client=prisma_client, ) ) asyncio.create_task( self.add_spend_log_transaction_to_daily_end_user_transaction( - payload=payload, + payload=copy.deepcopy(payload), prisma_client=prisma_client, ) ) asyncio.create_task( self.add_spend_log_transaction_to_daily_team_transaction( - payload=payload, + payload=copy.deepcopy(payload), prisma_client=prisma_client, ) ) asyncio.create_task( self.add_spend_log_transaction_to_daily_org_transaction( - payload=payload, + payload=copy.deepcopy(payload), org_id=org_id, prisma_client=prisma_client, ) ) asyncio.create_task( self.add_spend_log_transaction_to_daily_tag_transaction( - payload=payload, + payload=copy.deepcopy(payload), prisma_client=prisma_client, ) ) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 7512ddc3688..e486bac310d 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -1,6 +1,5 @@ import asyncio import copy -import gc import hashlib import json import os @@ -3379,7 +3378,6 @@ class ProxyUpdateSpend: headers={"Content-Type": "application/json"}, ) del json_data - gc.collect() if response.status_code == 200: prisma_client.spend_log_transactions = ( prisma_client.spend_log_transactions[ @@ -3401,9 +3399,6 @@ class ProxyUpdateSpend: ) # Explicitly clear batch memory del batch, batch_with_dates - # Only run gc every 5 batches to reduce overhead - if j % (BATCH_SIZE * 5) == 0: - gc.collect() prisma_client.spend_log_transactions = ( prisma_client.spend_log_transactions[len(logs_to_process) :] @@ -3429,7 +3424,6 @@ class ProxyUpdateSpend: finally: # Clean up logs_to_process after all processing is complete del logs_to_process - gc.collect() @staticmethod def disable_spend_updates() -> bool: