Summary
On the official self-hosted v1.5.37 image, a remote MCP client shows materially higher end-to-end latency through Executor than through a direct MCP server over the same transport.
Warm downstream work is fast (roughly 50–100 ms), and Executor's own HTTP spans are usually under 100 ms, but end-to-end calls are commonly measured around 4–5.5 seconds. A comparable direct MCP call over the same tunnel is around 1.1 seconds. This does not prove that the steady-state gap is entirely inside Executor, but the current logs do not provide enough timing detail to identify where it is introduced.
Separately, there is a concrete periodic stall: the first tools/list after remote catalogues become stale can block for 12–15 seconds while catalogues refresh.
Environment
- Executor self-host
v1.5.37, official container image
- Linux amd64
- Dozens of configured integrations/connections
- Several thousand persisted tools
- Streamable HTTP MCP behind a private tunnel
- Healthy host with no CPU, memory, restart, or OOM pressure
Observed behavior
Most tunnel-to-Executor POST /mcp requests complete in under 100 ms. However, one request took approximately 13 seconds, and the matching application log reported:
executor tool sync preserved catalog
reason: plugin returned an incomplete tool catalog
A separate API execution during the same refresh pattern took approximately 15 seconds.
The source appears to explain this behavior:
- Remote catalogues expire on a default 15-minute TTL.
syncStaleConnectionTools iterates stale connections sequentially.
- Each
produceConnectionTools call is awaited before toolsList returns.
- Cached catalogues are preserved on failure, but the foreground request still waits for the attempted refresh.
Relevant implementation:
https://github.com/UsefulSoftwareCo/executor/blob/main/packages/core/sdk/src/executor.ts
Expected behavior
- Return the persisted catalogue immediately when one is available.
- Refresh stale remote catalogues asynchronously, or concurrently with bounded timeouts.
- A slow or unavailable integration should not delay unrelated tool discovery.
- Self-host operators should have a supported way to configure or disable time-based catalogue refresh.
- Logs or spans should make it possible to separate MCP session setup, catalogue refresh, QuickJS execution, downstream tool time, serialization, and response delivery.
Reproduction outline
- Configure multiple remote MCP integrations.
- Allow their persisted catalogues to age beyond the default TTL.
- Start a fresh MCP session and request
tools/list.
- Observe that the request waits for stale remote catalogue refreshes.
- Repeat immediately and observe that the warm request is much faster.
Questions
- Is there currently a supported self-host setting for
toolsSyncTtlMs? The SDK accepts null, but the stock self-host configuration does not appear to expose it.
- Would serving cached tools first and refreshing in the background be acceptable?
- Is there an existing trace/debug mode for breaking down the steady end-to-end MCP latency described above?
Summary
On the official self-hosted
v1.5.37image, a remote MCP client shows materially higher end-to-end latency through Executor than through a direct MCP server over the same transport.Warm downstream work is fast (roughly 50–100 ms), and Executor's own HTTP spans are usually under 100 ms, but end-to-end calls are commonly measured around 4–5.5 seconds. A comparable direct MCP call over the same tunnel is around 1.1 seconds. This does not prove that the steady-state gap is entirely inside Executor, but the current logs do not provide enough timing detail to identify where it is introduced.
Separately, there is a concrete periodic stall: the first
tools/listafter remote catalogues become stale can block for 12–15 seconds while catalogues refresh.Environment
v1.5.37, official container imageObserved behavior
Most tunnel-to-Executor
POST /mcprequests complete in under 100 ms. However, one request took approximately 13 seconds, and the matching application log reported:A separate API execution during the same refresh pattern took approximately 15 seconds.
The source appears to explain this behavior:
syncStaleConnectionToolsiterates stale connections sequentially.produceConnectionToolscall is awaited beforetoolsListreturns.Relevant implementation:
https://github.com/UsefulSoftwareCo/executor/blob/main/packages/core/sdk/src/executor.ts
Expected behavior
Reproduction outline
tools/list.Questions
toolsSyncTtlMs? The SDK acceptsnull, but the stock self-host configuration does not appear to expose it.