# MCP servers over stdio: startup time, call latency and what broke when we ran 15 of them

Canonical: https://theagenticweekly.com/research/mcp-servers-latency-and-failures · Last verified: 2026-10-25 · Published: 2026-10-25 · Author: Agentic Weekly (operated independently from Texas, US) · Evidence: Measured by us on 2026-10-25. Local open-weight models on a CPU-only box; nothing is vendor-reported. Smoke tests, not benchmarks.

> Over stdio on one 8-core box, local MCP servers started in about 150 to 540 ms and answered a simple tool call in 0.4 to 3.2 ms at the median; browser-driven servers took tens to hundreds of milliseconds per call and the Context7 lookup took about 1.2 s because it calls a hosted API. Two failures were instructive: the Fetch server refuses localhost by default, and the 2.x reference servers need Node 24 and are silently replaced by 1.x on Node 20.

## How we measured

A small client written with the official MCP Python SDK (2.3.0) spawns each server as a child process over stdio. It times the initialize handshake (cold start: from spawning the process to receiving the initialize result), one tools/list request, and then 30 sequential tools/call requests (3 for the hosted lookup and 10 for the browser servers), reporting the median and 95th percentile. No language model was involved. Inputs were tiny, so these numbers are protocol and process overhead, not throughput.

All numbers come from one Linux virtual machine (Debian 13, 8 vCPU Intel Xeon, 15 GiB RAM, no GPU) that also ran other people's jobs, so timings are indicative and the 1-minute load average is recorded next to each run in the underlying test logs.

## Results

Table: Cold start, tool listing and call latency per server (milliseconds)

| Server | Reported name and version | Cold start | tools/list | Tools | Timed call | Median | p95 | Call result |
|---|---|---|---|---|---|---|---|---|
| [Filesystem, Node 20](https://theagenticweekly.com/tests/mcp-server-filesystem) | secure-filesystem-server 1.0.0 | 279 | 10.3 | 14 | read_text_file | 0.8 | 2.1 | ok |
| [Filesystem, Node 24](https://theagenticweekly.com/tests/mcp-server-filesystem) | secure-filesystem-server 2.0.1 | 187 | 8.0 | 14 | read_text_file | 1.0 | 2.4 | ok |
| [Memory, Node 20](https://theagenticweekly.com/tests/mcp-server-memory) | memory-server 1.0.0 | 284 | 8.5 | 9 | search_nodes | 0.9 | 1.9 | ok |
| [Memory, Node 24](https://theagenticweekly.com/tests/mcp-server-memory) | memory-server 2.0.0 | 147 | 8.1 | 9 | search_nodes | 0.6 | 1.7 | ok |
| [Sequential Thinking, Node 20](https://theagenticweekly.com/tests/mcp-server-sequential-thinking) | sequential-thinking-server 1.0.0 | 271 | 6.6 | 1 | sequentialthinking | 0.8 | 1.5 | ok |
| [Sequential Thinking, Node 24](https://theagenticweekly.com/tests/mcp-server-sequential-thinking) | sequential-thinking-server 2.0.0 | 159 | 5.9 | 1 | sequentialthinking | 0.4 | 1.4 | ok |
| [Everything, Node 20](https://theagenticweekly.com/tests/mcp-server-everything) | mcp-servers/everything 1.0.0 | 356 | 8.6 | 13 | echo | 0.5 | 1.4 | ok |
| [Everything, Node 24](https://theagenticweekly.com/tests/mcp-server-everything) | mcp-servers/everything 2.0.1 | 252 | 6.4 | 16 | echo | 0.4 | 1.2 | ok |
| [Fetch (default)](https://theagenticweekly.com/tests/mcp-server-fetch) | mcp-fetch 2026.10.24 | 533 | 1.9 | 1 | fetch | 6.2 | 6.8 | error (see text) |
| [Fetch (--allow-private-ips)](https://theagenticweekly.com/tests/mcp-server-fetch) | mcp-fetch 2026.10.24 | 538 | 2.5 | 1 | fetch | 698.3 | 796.3 | ok |
| [Git](https://theagenticweekly.com/tests/mcp-server-git) | mcp-git 2026.10.19 | 512 | 3.6 | 12 | git_status | 3.2 | 3.7 | ok |
| [Time](https://theagenticweekly.com/tests/mcp-server-time) | mcp-time 2026.10.19 | 483 | 2.3 | 2 | get_current_time | 0.8 | 2.2 | ok |
| [Playwright MCP](https://theagenticweekly.com/tests/playwright-mcp) | Playwright 1.64.0-alpha-1790635538000 | 383 | 10.1 | 25 | browser_navigate | 40.5 | 51.8 | ok |
| [Chrome DevTools MCP](https://theagenticweekly.com/tests/chrome-devtools-mcp) | chrome_devtools 1.12.0 | 565 | 14.1 | 32 | new_page | 136.6 | 256.6 | ok |
| [Context7 MCP (hosted lookup)](https://theagenticweekly.com/tests/context7-mcp) | Context7 4.4.4 | 462 | 5.9 | 2 | resolve-library-id | 1201.3 | 1201.3 | ok |

Notes on rows: the Fetch default row timed a call that the server refused (the median is the time to refuse); the Chrome DevTools row timed new_page after an earlier navigate_page attempt failed validation for a missing pageId (kept in the test log); the Context7 median is a network round trip to a hosted service over 3 calls.

## Two Python server implementations side by side

Table: The same three-tool server in FastMCP 4.1.3 and the official MCP Python SDK 2.3.0, three repeats each (ms)

| Implementation | Cold start per repeat | tools/list per repeat | Median call per repeat |
|---|---|---|---|
| FastMCP 4.1.3 | 643, 735, 645 | 120.8, 139.3, 127.3 | 1.2, 1.3, 1.3 |
| Official SDK MCPServer 2.3.0 | 461, 516, 463 | 1.8, 2.6, 2.4 | 0.7, 0.8, 0.9 |

An earlier first run of each (not in the table) took 1589 ms for FastMCP and 472 ms for the SDK server; the FastMCP number includes first-import work. A server written against the 1.x import path of the SDK (from mcp.server.fastmcp import FastMCP) failed under SDK 2.3.0 with an ExceptionGroup error; the 2.x class is mcp.server.mcpserver.MCPServer, which the table's SDK rows use.

## Node 20 against Node 24: different servers

Table: Reference servers on Node 20 and Node 24: the version npm resolved and the cold start (ms)

| Server | Node 20 version | Node 20 cold start | Node 24 version | Node 24 cold start |
|---|---|---|---|---|
| Filesystem | 1.0.0 | 279 | 2.0.1 | 187 |
| Memory | 1.0.0 | 284 | 2.0.0 | 147 |
| Sequential Thinking | 1.0.0 | 271 | 2.0.0 | 159 |
| Everything | 1.0.0 | 356 | 2.0.1 | 252 |

The 2.x reference servers require Node 24 or newer. On Node 20, npm installed the 1.0.0 line without any error, so the same install command gave us different servers on the two Node versions. Check the version string a server reports before comparing numbers or following a tutorial.

## What broke, and what held

- The Fetch server refused http://127.0.0.1 with an explanatory error (Refused to fetch ... 127.0.0.1 resolves to 127.0.0.1, which is not a public address). That is a safety default; --allow-private-ips lets it through, and then it took about 698 ms per call.
- Chrome DevTools MCP rejected navigate_page without a pageId ('expected number, received undefined'), which is what a model that skips new_page would hit.
- Context7's tools are a thin client for a hosted service: about 1.2 s per lookup and the data leaves your machine.
- Filesystem server sandbox check (v2.0.1, one allowed directory): the output below shows that two attempts to read outside it were refused while in-root listing and writing worked. This is four requests, not a security audit; symlinks were not tried.

Filesystem server v2.0.1: four requests

```
read_text_file {'path': '/etc/hostname'} -> ERROR Access denied - path outside allowed directories: /etc/hostname not in /workspace/tests2/work/fsroot
read_text_file {'path': '/workspace/tests2/work/fsroot/../gitrepo/f'} -> ERROR Access denied - path outside allowed directories: /workspace/tests2/work/gitrepo/f not in /workspace/tests2/work/fsroot
list_directory {'path': '/workspace/tests2/work/fsroot'} -> ok [FILE] notes.txt
write_file {'path': '/workspace/tests2/work/fsroot/new.txt', 'content': 'x'} -> ok Successfully wrote to /workspace/tests2/work/fsroot/new.txt
```

## Caveats

- Local stdio only, one client, tiny payloads; remote transports, authentication and concurrency were not measured.
- Cold start includes the Node or Python runtime start, so it says as much about the runtime as about the server.
- Single runs per row except where repeats are shown, on a shared machine; read differences below a few milliseconds, or between servers of different languages, as noise.
- MCP Inspector (0.15.0 and 2.12.0) was also run in CLI mode to list the filesystem server's 14 tools; see its test log.

## FAQ

### How fast is an MCP server over stdio?

In our runs a local server answered a trivial tool call in about 0.4 to 3.2 ms at the median and took about 150 to 540 ms to start and complete the initialize handshake. Browser servers took longer per call and hosted lookups took about a second.

### Why did the MCP Fetch server refuse localhost?

By default it blocks loopback, private and link-local addresses as a guard against server-side request forgery; --allow-private-ips turns that off for local testing.

### Why do the Node 20 and Node 24 rows show different versions?

The 2.x reference servers need Node 24, and on Node 20 npm quietly installs the 1.0.0 line instead.

## Related

- [All research](https://theagenticweekly.com/research)
- [All test logs](https://theagenticweekly.com/tests)
- [Methodology and testing rig](https://theagenticweekly.com/methodology#testing-rig)
- [MCP Inspector test log](https://theagenticweekly.com/tests/mcp-inspector)
- [Study: install traps on older Node](https://theagenticweekly.com/research/older-node-silent-downgrades)

## Changelog

- 2026-10-25: First published.

## How to cite

Agentic Weekly, "MCP servers over stdio: startup time, call latency and what broke when we ran 15 of them", last updated 2026-10-25, https://theagenticweekly.com/research/mcp-servers-latency-and-failures
