Repository navigation
First Check
Commit to Help
Example Codeimport inspect
import fastapi
app = fastapi.FastAPI()
deps = {}
LIMIT = 100
def create_dependencies(index: int):
"""Factory to create a dependency that depends on the next one in the chain."""
# The base case: the last dependency (100) doesn't depend on anything
if index == LIMIT:
def dependency_100() -> str:
return "100"
return dependency_100
# Recursive-style case: depend on the index + 1
next_dep_func = deps.get(index + 1)
async def dependency_node(sub_dep: str = fastapi.Depends(next_dep_func)) -> str:
return f"{index} -> {sub_dep}"
# Rename the function for FastAPI's internal dependency resolution/debugging
dependency_node.__name__ = f"get_dep{index}"
return dependency_node
# Build the chain of dependencies from 100 down to 0
for i in range(LIMIT, -1, -1):
deps[i] = create_dependencies(i)
def create_dynamic_endpoint_function(param_count: int):
"""
Creates a function with 'param_count' arguments, each having a default value.
FastAPI will inspect __signature__ to resolve dependencies.
"""
parameters = []
for i in range(param_count):
# Logic to determine the default value (e.g., a specific dependency)
# Here we use the existing 'deps' dictionary built above
default_val = fastapi.Depends(deps.get(i, lambda: i))
param = inspect.Parameter(
name=f"arg_{i}",
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
default=default_val,
annotation=str
)
parameters.append(param)
# Define the actual runtime logic of the function
async def dynamic_wrapper(**kwargs):
return {
"message": "Called dynamic endpoint",
"param_count": len(kwargs),
# "values": kwargs # Uncomment to see the resolved values
}
# Override the signature so FastAPI sees 'arg_0', 'arg_1', etc.
dynamic_wrapper.__signature__ = inspect.Signature(parameters)
return dynamic_wrapper
# Register two routes with 50 parameters dynamically
app.add_api_route(
"/dynamic-health",
create_dynamic_endpoint_function(50),
methods=["GET"]
)
app.add_api_route(
"/dynamic-health",
create_dynamic_endpoint_function(50),
methods=["POST"]
)DescriptionWe're currently using FastAPI Using memray to profile the total memory usage, I got: However, when we tried to upgrade to I did a profile of the total memory usage with 0.121.3 and I got: When I dig deeper in the flamegraph, I found the following difference between the two versions. As you can see from the flamegraph, 0.121.3 shows more memory consumption from Also, running memray in live mode showed the following: As we can see there, So, I checked the PR With all this information, I did two tests.
As you can see in both examples, total memory consumption was reduced to something very similar as version Lastly, I also tried running FastAPI with all versions from 0.120 to the latest 0.128 in Docker and I got the following resources usage metrics: Also, this shows an increment of memory usage. I also noticed that in the latest versions more cached properties were introduced, so changing only From the information I was able to gather, I can't really say if this is a memory leak or just more memory consumption. I'd appreciate any help of feedback about this issue. Thanks Operating SystemLinux, macOS Operating System DetailsNo response FastAPI Version0.121.3 Pydantic Version2.12.5 Python Version3.12.9 Additional ContextNo response |
Replies: 4 comments 7 replies
This comment has been hidden.
This comment has been hidden.
|
What would be needed to move this discussion forwards or upgrade to an issue? @YuriiMotov tagging you because you're an active collaborator of this repository and replied to the comment above. |
|
Thanks for sharing all the graphs, I'll check it out. It looks a bit weird that it would consume so much memory as it's computed once and then cached. I imagine maybe if there's something creating new dependencies every time, maybe storing them somewhere, or something like that... I'm trying to figure out in which case could there be something that consumes and keeps consuming so much extra memory, I don't see an obvious answer in the code, nor the functools docs. 🤔 I'll keep checking a bit more to see if I can find anything, but if you or anyone else could create some way to replicate it, it would be very useful. |
|
I opened a PR that should help or close this issue: #15336 |










Thank you for all the investigation and report about this! And thanks for the intial work in a PR.
I used the reasearch you did (plus some other reported by others) to make this one #16049, I wanted to handle
Dependants properties in a different way.It is now released in FastAPI 0.140.0. ☕