MP-301g · Module 1

Message Ordering & Concurrency

3 min read

JSON-RPC 2.0 does not guarantee in-order responses. A server may process requests concurrently and return responses in whatever order they complete. The id field is the only mechanism for matching responses to requests — the client must maintain a pending-request map keyed by id and resolve each response by lookup, not by position. If your client assumes the first response corresponds to the first request, concurrent tool invocations will silently return the wrong result to the wrong caller.

Request pipelining — sending multiple requests without waiting for responses — is safe as long as the requests are independent. If request B depends on the result of request A, you must serialize them. The protocol does not enforce this; it is an application-level concern. A common pattern is to pipeline tools/list and resources/list during initialization (they are independent), then serialize tool calls that depend on each other's output. Over-serialization wastes latency; under-serialization causes data races.

Do This

  • Correlate responses by id, never by arrival order
  • Pipeline independent requests to reduce round-trip latency
  • Use monotonic integer IDs for easy debugging and ordering
  • Set a timeout per pending request and clean up the map on expiry

Avoid This

  • Assume responses arrive in the same order as requests
  • Block on each request before sending the next — this serializes everything unnecessarily
  • Use random UUIDs for IDs in high-throughput scenarios — the wire overhead adds up
  • Leave orphaned entries in the pending-request map when the connection drops