Skip to content

API latency: /v0/servers reads consistently take 20–25s #1252

Closed

Description

@rhinocap

Summary

/v0/servers queries on registry.modelcontextprotocol.io return successful responses but with extreme latency (20–25s for trivial queries returning a few KB of JSON). Default-timeout HTTP clients (and most CLI tools) treat these as failures, making the API effectively unusable without explicit long timeouts.

Repro (just now from California, 2026-05-04 ~11:00 PDT)

$ curl -sL --max-time 30 -w "\nHTTP %{http_code} | %{time_total}s | %{size_download}b\n" \
  "https://registry.modelcontextprotocol.io/v0/servers?search=raven&limit=5"
... [valid JSON list of 5 servers] ...
HTTP 200 | 24.903s | 3947b

$ curl -sL --max-time 30 -w "\nHTTP %{http_code} | %{time_total}s\n" \
  "https://registry.modelcontextprotocol.io/v0/servers/com.knowledge-raven%2Fmcp/versions/1.0.0"
... [valid server metadata] ...
HTTP 200 | 20.921s | 716b

$ curl -sL --max-time 30 -w "\nHTTP %{http_code} | %{time_total}s\n" \
  "https://registry.modelcontextprotocol.io/v0/servers?limit=3"
... [valid 3-server response] ...
HTTP 200 | 25.818s

By contrast, the static frontend at / returns in 394ms — same hostname, presumably a different cluster:

$ curl -sI --max-time 8 -w "\nHTTP %{http_code} | %{time_total}s\n" \
  "https://registry.modelcontextprotocol.io/"
HTTP/2 200
HTTP 200 | 0.394s

So this is API-side, not network/DNS.

Why this matters in practice

Most HTTP libraries default to 5–15 second timeouts. With API responses landing at 20–25s, anything calling the API with defaults will see what looks like a hard failure:

  • WebFetch / similar tooling I tried earlier today returned empty bodies and gave up
  • My initial curl --max-time 12 runs all returned HTTP 000 — I assumed the endpoints were broken
  • A first-time integrator doing fetch(...) with default 10s would conclude the API is down

For context: I just published ai.ravenmcp/raven-mcp (registered 2026-05-04T17:26:51Z). Confirming the publish landed required ~10 minutes of guessing the right query shapes because every short-timeout probe returned HTTP 000. The publish succeeded (mcp-publisher exited 0) but verification was needlessly hard.

Hypothesis

The latency profile (~20–25s near-uniform across read endpoints) looks more like a cold-start / per-request resource provisioning issue than slow query execution. A 3-server list response shouldn't be doing 25s of database work. Could be Cloud Run-style cold starts, a per-request DB connection setup, or a synchronous external dependency (e.g. validating against a static schema URL on every request).

Asks

  1. Latency budget on /v0/servers/* — 20–25s for sub-4KB responses is a UX cliff. Sub-1s would be a reasonable target for cached lookups; sub-5s for searches.
  2. If a fix isn't quick — surface a recommended minimum timeout on the API reference docs so integrators don't conclude the API is broken when it's just slow. (Currently nothing in /docs warns about timeouts.)
  3. Health endpoint — a fast /v0/health or similar that confirms "API is responsive" cheaply would let clients distinguish "API hung" from "your timeout is too short."

Happy to share the mcp-publisher publish flow + verification timing data if useful for whoever picks this up.


(Filed by @rhinocap from ai.ravenmcp/raven-mcp publication context.)

Activity

  1. rdimitrov commented on May 5, 2026

    @rdimitrov
    Member

    Thanks @rhinocap for the detailed repro and for sticking with mcp-publisher. Totally agree this kind of timeout guessing isn’t a great experience.

    What’s happening

    • Your probes hit a daily slowdown window (~17:30–18:30 UTC). During that time, latency spikes (~45–50s p95) due to a scraper paging through the full catalog and saturating Postgres. Outside that window, the same endpoint is ~<100ms p95.

    What we’re doing

    • v1.7.8 is out with improved metrics (fixes cancelled requests showing as 500s)
    • Reaching out to the scraper to switch to incremental sync (?updated_since=), which should drastically reduce load
    • Considering rate limiting / autoscaling if needed

    On your asks

    • Latency: off-peak already fast; fixing the peak window is in progress
    • Docs: we’ll add a recommended timeout (for now, ~30s is safest)
    • Health endpoint: already available at /v0/health (~500ms), will make it more visible in docs

    If you retry outside that window, you should see much better performance — happy to compare results.

  2. rhinocap commented on May 5, 2026

    @rhinocap
    Author

    Thanks @rdimitrov — appreciate the breakdown and the fast turnaround on v1.7.8.

    A few observations from the client side:

    v1.7.8 metrics fix confirmed. /metrics now exposes status_code="499" separately from 5xx on mcp_registry_http_request_duration — clean signal for dashboards. No more false-alarm 500-rate spikes from cancelled clients.

    Off-peak latency. Just probed /v0/servers?limit=10: 340ms round-trip from the West Coast US, including TLS + DNS. Lines up with your <100ms p95 claim once you back out transit. Confirms the peak-window framing.

    Incremental sync (?updated_since=). Big +1. Once it ships, happy to rerun the probe pattern that surfaced the original spikes and report back on whether the 17:30–18:30 UTC window flattens out.

    One small ask if you go the rate-limit route: surface Retry-After headers on 429s so well-behaved clients can back off without looking like the load source. Would also help separate "scraper paging through" traffic from organic SDK usage in your metrics.

    Glad the repro was useful. Cc me on the ?updated_since= rollout and I'll close the loop with a follow-up data point.

    — Andrew

  3. MukundaKatta commented on May 11, 2026

    @MukundaKatta

    Just measured from California, 2026-05-11 ~02:00 PDT: three sequential
    /v0/servers reads averaged 0.32s (HTTP 200, 4KB response). Same shape of
    query as your repro. Either the original symptom was transient and is now
    resolved, or there's a CDN cache that's warming differently per region.
    Worth confirming whether it's still reproducible before treating as open.

  4. added 4 commits that reference this issue on Oct 25, 2026
    5b2a1a3
    4e2df3f
    cfc66cb
    e47b29e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions