Skip to content

Performance Overhead of Mounted Multi-Server Proxy #3466

@zirota

Description

@zirota

Description

Hello, I am not sure if this is a bug or intended.

I am on the latest FastMCP version: 3.1.0

My current setup is to mount a multi-server proxy on an existing FastAPI instance.
The proxy is created similar to this example: https://gofastmcp.com/servers/providers/proxy#multi-server-proxies

Then the proxy is mounted as a stateless-http http app.

 proxy.http_app(transport="streamable-http", stateless_http=True)

What I observe during my performance tests is that, there seems to be a huge performance overhead when making direct tool calls against the proxy.

100 Requests.
Proxy: Average of 15s
Direct to MCP: Average of 80ms

On analysis, it seems that:

When creating a proxy with create_proxy(), the default _create_client_factory() is used.

Since client_factory is invoked on every mcp method call on the proxy server, there is a new ProxyClient being created withbase_client.new().
https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/providers/proxy.py#L671-L678

This causes connect_session to be called multiple times, once on list_tools and another on the actual tool call. Resulting in multiple mcp initialization handshakes.

I do think this might be intended to prevent context mixing.

However, since I am intending to go with a stateless-http proxy server.
Would overriding the client_factory here to return the same client make sense?

def _create_client_factory() -> ClientFactoryT:
        base_client = ProxyClient(cast(Any, config))
        client = base_client.new()

        def proxy_client_factory() -> Client:
            return client

client_factory = self._create_client_factory()
proxy = FastMCPProxy(client_factory=client_factory, name="proxy")

This approach dramatically improves the performance from 15s to 5s.

Or is there a better approach I can do to avoid the overhead caused by mcp session initialization when running the proxy in stateless mode?

Version Information

FastMCP version:                                                                         3.1.0
MCP version:                                                                               1.26.0
Python version:                                                                            3.12.1
Platform:                                                            macOS-15.7.3-arm64-arm-64bit

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working. Reports of errors, unexpected behavior, or broken functionality.httpRelated to HTTP transport, networking, or web server functionality.potential-duplicateBot-suggested duplicate awaiting human review. Auto-closes after 3 days if unchallenged.serverRelated to FastMCP server implementation or server-side functionality.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions