core: leak when using object member in a `RunnableSequence`
#30,667 opened on 2025年4月4日
説明
Checked other resources
- I added a very descriptive title to this issue.
- I searched the LangChain documentation with the integrated search.
- I used the GitHub search to find a similar question and didn't find it.
- I am sure that this is a bug in LangChain rather than my code.
- The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
Example Code
import gc
from langchain_core.runnables import (
RunnableLambda,
RunnablePassthrough,
)
def log_memory_usage():
gc.collect()
objs = gc.get_objects()
print(f"Total objects: {len(objs)}")
class ThingWithRunnable:
def __init__(self, func):
self.func = func
self.runnable_lambda = RunnableLambda(func)
self.expensive = {i: [i] for i in range(1000000)}
def call(self, inputs):
return self.runnable_lambda.invoke(inputs)
def __del__(self):
print(">>>> Cleaning up")
def func(inp):
return {"result": "ok"}
def works():
thing = ThingWithRunnable(func)
thing.call({})
def works2():
thing = ThingWithRunnable(func)
(RunnableLambda(thing.func) | RunnablePassthrough()).invoke({})
def broken():
thing = ThingWithRunnable(func)
(thing.call | RunnablePassthrough()).invoke({})
def broken2():
thing = ThingWithRunnable(func)
(RunnableLambda(thing.call) | RunnablePassthrough()).invoke({})
if __name__ == "__main__":
gc.freeze()
print("Works:")
for _ in range(2):
works()
log_memory_usage()
print("Works 2:")
for _ in range(2):
works2()
log_memory_usage()
print("Broken:")
for _ in range(2):
broken()
log_memory_usage()
print("Broken 2:")
for _ in range(2):
broken2()
log_memory_usage()
Error Message and Stack Trace (if applicable)
No response
Description
(I created this first as a discussion but after giving it some more thought, I'm pretty sure it's a bug in langchain-core so I'm opening this issue)
Hi, we encountered a memory leak in our app and simplified it down to this. When creating a new RunnableSequence where a member of an object (thing.call) that invokes a Runnable is followed by something else like a RunnablePassthrough, the memory is not cleaned up.
There seems to be a reference to thing still held somewhere which is why the GC doesn't remove the object from memory.
Output:
Works:
>>>> Cleaning up
Total objects: 24670
>>>> Cleaning up
Total objects: 24658
Works 2:
>>>> Cleaning up
Total objects: 24936
>>>> Cleaning up
Total objects: 24936
Broken:
Total objects: 1024999
Total objects: 2025005
Broken 2:
Total objects: 3025011
Total objects: 4025017
What I would expect: "Cleaning up" logged also in the "broken" versions, object counts don't increase by a lot
In our real app, we were able to work around it by creating two Runnables, the first with the object member and the second with further steps, and invoking them one after the other.
System Info
uv run python -m langchain_core.sys_info
System Information
------------------
> OS: Darwin
> OS Version: Darwin Kernel Version 24.3.0: Thu Jan 2 20:24:24 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6030
> Python Version: 3.13.1 (main, Jan 5 2025, 06:22:40) [Clang 19.1.6 ]
Package Information
-------------------
> langchain_core: 0.3.50
> langsmith: 0.3.24
Optional packages not installed
-------------------------------
> langserve
Other Dependencies
------------------
> httpx: 0.28.1
> jsonpatch<2.0,>=1.33: Installed. No version info available.
> langsmith-pyo3: Installed. No version info available.
> langsmith<0.4,>=0.1.125: Installed. No version info available.
> openai-agents: Installed. No version info available.
> opentelemetry-api: Installed. No version info available.
> opentelemetry-exporter-otlp-proto-http: Installed. No version info available.
> opentelemetry-sdk: Installed. No version info available.
> orjson: 3.10.16
> packaging: 24.2
> packaging<25,>=23.2: Installed. No version info available.
> pydantic: 2.11.2
> pydantic<3.0.0,>=2.5.2;: Installed. No version info available.
> pydantic<3.0.0,>=2.7.4;: Installed. No version info available.
> pytest: Installed. No version info available.
> PyYAML>=5.3: Installed. No version info available.
> requests: 2.32.3
> requests-toolbelt: 1.0.0
> rich: Installed. No version info available.
> tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available.
> typing-extensions>=4.7: Installed. No version info available.
> zstandard: 0.23.0