The Smallest Client
A complete Claude Messages API client in one source file, in a different language each week, measured the same way every time. The leaderboard, the spec and the posts.
People think an LLM client is a big thing because the SDKs are big. The wire protocol is one HTTPS POST, one JSON body, and a stream of six Server-Sent Event types. Every client on this page is the whole of it in a single file, with no SDK, and every one is measured the same way by the same harness.
The numbers come from a mock that replays a recorded exchange with its original timing, so they are about the client and not the network, and you can reproduce them without an API key.
Leaderboard
Sorted by what you ship: the artefact plus the runtime it needs. Cold start is process spawn to the first request arriving at the mock. Overhead is spawn to exit, minus the time the mock spent replaying. Medians over the runs.
| # | Client | Artefact | Runtime | Ship | Cold start | Overhead | Peak RSS | Toolchain | Post |
|---|---|---|---|---|---|---|---|---|---|
| 1 | rust | 1.4 MB | 2.0 MB | 3.3 MB | 1.6 ms | 25.74 ms | 2 MB | rustc 1.99.1 (58cf8f9c3 2026-10-13) | queued |
| 2 | go | 5.8 MB | 0 | 5.8 MB | 1.86 ms | 26.42 ms | 6 MB | go version go1.27.2 linux/arm64 | queued |
| 3 | csharp | 5.4 MB | 2.4 MB | 7.8 MB | 3.0 ms | 26.72 ms | 7 MB | dotnet SDK 10.0.402 | queued |
| 4 | bash | 3.7 KB | 23.7 MB | 23.7 MB | 7.12 ms | 56.63 ms | 11 MB | GNU bash, version 5.2.37(1)-release (aarch64-unknown-linux-gnu) | queued |
Apple M4 Max under Docker, linux/arm64. Download the data (CSV). A row marked queued has a post written and dated.
The spec
Every client must do all of this, and the bench checks each point rather than trusting the code.
- Read the key from
ANTHROPIC_API_KEYand the base URL fromANTHROPIC_BASE_URL. Nothing else from the environment. - Read the prompt from stdin.
POST /v1/messageswithx-api-key,anthropic-version: 2023-06-01andcontent-type: application/json, and a body withmodel,max_tokens,stream: true,messagesandtools.- Print each
text_deltaas it arrives. Buffering the whole reply fails. - Declare one tool,
local_time. When the stream ends withstop_reason: "tool_use", assemble theinput_json_deltafragments, run the tool, send thetool_resultback with the assistant turn echoed, and stream that reply too. - On a non-2xx response, print the body's
error.messageto stderr and exit non-zero. - One source file. HTTP and TLS from the platform where it has them. Where it does not, one named library, which counts towards size.
The posts
The first post publishes on Thursday 12 November 2026. Until then the repo is the post.