Operations

Choosing an MCP Server Profile: Small, Medium, Large

How to size MCP server compute — start small, scale on evidence, separate protocol health from CPU metrics, and control cost without starving agents.

10 min read Published July 14, 2026 Updated July 14, 2026

MCPLambda and similar hosts pack compute into profiles (small / medium / large). Exact CPU/RAM is product-defined — see Server profiles. This guide is the decision process: when to stay small, when to scale, and what sizing cannot fix.

Mental model

Agent latency ≈ host LLM time
              + MCP transport RTT
              + tool handler time
              + upstream API time

Throwing a larger profile at upstream or LLM latency does nothing. Sizing only helps the tool handler + runtime slice.

What sizing helps vs ignores

Sizing helpsSizing does not fix
Memory for heavy language runtimes / depsWrong transport or auth config
Concurrent tools/call capacityInvalid tool schemas
GC pressure from large in-process payloadsMissing rate limits (tools MUST rate-limit)
CPU-bound serialization/cryptoSlow third-party APIs
Avoiding OOM restartsProgressive discovery problems in the host (client best practices)

Profile guidance (starting points)

ProfileTypical fitExamples
SmallLightweight wrappers, low concurrency, stagingThin REST→tool adapters
MediumBroader tools, more deps, team shared useMulti-tool internal servers
LargeHeavy memory, parallelism, fat runtimesBig SDKs, local models adjacent (rare)

Always confirm current entitlements on profiles docs.

Evidence-based scale-up signals

Raise profile only when you see at least one:

  1. OOM / restart loops in runtime logs
  2. CPU near saturation while tools/call latency climbs under load
  3. p95 tool latency misses your interactive SLO (e.g. >2–3s for simple tools) after code/payload optimization
  4. Queueing behind single-threaded work you cannot shard

Do not resize because “the agent feels slow” without checking auth, upstream, and payload size (debugging).

Protocol health before resize

Run this sequence on the current profile:

  1. Lifecycle initialize OK (lifecycle)
  2. tools/list complete and stable
  3. Separate protocol errors vs isError tool results (tools errors)
  4. Confirm client timeouts exist (clients SHOULD timeout tool calls — tools security)
  5. Confirm server rate limits are intentional, not accidental 429 storms

Optimization order (cheaper than a larger profile)

1. Shrink tool results (summaries, pagination)
2. Cache safe read tools
3. Fix N+1 upstream calls inside handlers
4. Split hot tools onto a dedicated server
5. Then increase profile
6. Then add horizontal copies if the platform supports it

Large tool definitions and intermediate results also burn LLM tokens on the host side (client best practices) — that is not fixed by MCP CPU.

Worked examples

Example A — thin GitHub wrapper, 10 eng users

  • Start small
  • Measure p95 of list_prs under 20 concurrent calls
  • If p95 is dominated by GitHub API, keep small and cache

Example B — Python server with heavy ML preprocessing

  • May need medium/large for memory
  • Watch RSS and restart counts, not only CPU %

Example C — “slow” support agent with 80 tools

  • Often a host context problem, not profile
  • Apply progressive discovery; split servers by domain

Process

Deploy small → realistic tools/call load → measure runtime + tool metrics
→ optimize code/payloads → if still constrained, bump profile
→ re-measure → lock budget alerts

Pair with rate limits & cost control.

Checklist

  • Baseline p50/p95 per critical tool on small
  • OOM/restart dashboard in place
  • Upstream latency distinguished from handler latency
  • Staging profile ≤ prod (or equal for realism)
  • Cost alert if profile upgraded without load justification
  • Document why medium/large was chosen

Worked scenario: The “slow agent” that was not CPU

Support leads complain the agent is slow after you add a search_kb tool that returns full article HTML. CPU on the small profile is 15%. p95 of search_kb is 4s—almost all upstream + payload size.

You shrink results to titles + snippets, add pagination, and keep small. Later, a Python server with a heavy PDF library OOMs on small under concurrent calls; then you move that server to medium and leave the thin API wrappers on small.

Resizing is the last step after measuring handler time vs upstream time vs host LLM time.

Checklist for this topic

  • Baseline p50/p95 per critical tool on current profile
  • Separate upstream latency from process CPU/memory
  • Optimize payloads before upgrading profile
  • Raise profile on OOM, CPU saturation, or proven handler bottleneck
  • Keep staging profile realistic
  • Document why medium/large was chosen

Topic-specific failure modes

FailureLikely causeFix
Slow agents, low CPUPayload/upstream/LLMOptimize results; progressive discovery
OOM restartsUndersized memoryIncrease profile or slim deps
All servers set to largeFear of slownessRight-size per server
Resize fixed nothingAuth/tool errorsDebug protocol first

Observability · Rate limits & cost · Debugging

Example SLO-linked sizing

For interactive internal tools, target p95 tool execution under 1.5s excluding known-slow upstreams. If handler CPU time is under 20% of p95, do not upgrade profile—fix the upstream or payload. If handler CPU is most of p95 and cores are saturated, then upgrade or split load.

Sources

Next steps

Observability · Rate limits & cost

FAQs

Frequently Asked Questions

  • What profile should I start with?

    Start with the smallest profile that runs your server cleanly for expected concurrency. Raise size only when you see OOM, CPU saturation, or tool latency SLOs failing under realistic tools/call load.

  • Is high CPU the same as a bad MCP server?

    No. Agents can fail while CPU is low (auth errors, tool logic bugs, upstream 403s). Always pair runtime metrics with tools/list success and tools/call error rates.

  • Will a larger profile fix slow agents?

    Only if the bottleneck is local CPU/memory. Slow agents are often large tool payloads, missing progressive discovery, upstream latency, or retries on isError — resize after you rule those out.