n4nAI

Comparing SSE streaming across OpenAI, Anthropic, and n4n

Head-to-head sse streaming openai anthropic n4n comparison: SSE shapes, cost, latency, ergonomics, limits, and a verdict for engineers.

n4n Team4 min read885 words

Audio narration

Coming soon — every post will get a voice note here.

Streaming tokens over HTTP settled on Server-Sent Events because it rides on plain HTTP/1.1 and plays nice with proxies. This sse streaming openai anthropic n4n comparison looks at how the three APIs frame events, report usage, and fail—because those details determine how much glue code you write. If you’re routing between models, the wire format is the difference between a ten-line client and a forked SDK.

Protocol fundamentals

OpenAI native SSE

OpenAI ships a minimal SSE dialect: every event is data: {json}\n\n, and the stream ends with data: [DONE]\n\n. No event: field is used. The JSON chunks carry choices[].delta with incremental text. The content type is text/event-stream; charset=utf-8, and the server sends Cache-Control: no-cache.

curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","stream":true,"messages":[{"role":"user","content":"hi"}]}'
import json
# raw iteration over a requests response
for line in response.iter_lines():
    if not line:
        continue
    if line.startswith(b"data: "):
        payload = line[6:].strip()
        if payload == b"[DONE]":
            break
        delta = json.loads(payload)["choices"][0]["delta"]
        if "content" in delta:
            print(delta["content"], end="")

Anthropic native SSE

Anthropic uses named events: event: content_block_delta\ndata: {...}. This carries more semantic structure—separate events for message_start, content_block_start, content_block_delta, content_block_stop, ping, and message_stop. You must parse both event: and data: lines and maintain a small state machine.

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-3-5-sonnet-20241022","stream":true,"messages":[{"role":"user","content":"hi"}]}'
event = None
for line in response.iter_lines():
    if not line:
        continue
    if line.startswith(b"event: "):
        event = line[7:].decode()
    elif line.startswith(b"data: "):
        data = json.loads(line[6:])
        if event == "content_block_delta":
            print(data["delta"]["text"], end="")
        elif event == "message_stop":
            break

n4n.ai gateway SSE

The n4n.ai gateway exposes a single OpenAI-compatible endpoint that fronts 240+ models. It emits the OpenAI data: frame shape exactly, so existing OpenAI clients work unmodified. Behind the curtain it honors client routing directives (e.g., x-routing: prefer=anthropic) and forwards provider cache-control hints, while automatic fallback switches providers when one is rate-limited or degraded—without changing the SSE contract.

curl https://api.n4n.ai/v1/chat/completions \
  -H "Authorization: Bearer $N4N_KEY" \
  -H "x-routing: prefer=anthropic" \
  -d '{"model":"claude-3-5-sonnet","stream":true,"messages":[{"role":"user","content":"hi"}]}'

The bytes on the wire match the OpenAI example above.

Capabilities

OpenAI’s stream includes partial tool-call arguments as JSON delta fragments and a final usage object if you send stream_options: {include_usage: true}. Anthropic streams structured blocks: you get input_json deltas for tool use, plus message_start carrying initial metadata like model and usage estimates. n4n.ai normalizes usage into the OpenAI usage shape via per-token metering, regardless of underlying provider, and passes through provider-specific delta fields under a provider key when needed.

All three support cancelling mid-stream via connection close. None support server-initiated resumption; you replay from your own checkpoint. OpenAI and n4n.ai allow include_usage to flush a final accounting chunk; Anthropic embeds usage in message_stop.

Cost and metering

OpenAI and Anthropic bill per output token and meter separately per request; you read usage after the stream closes (Anthropic inside message_stop). n4n.ai applies per-token usage metering uniformly across providers, so a mixed route of OpenAI and Anthropic models shows consistent fields in one response object. Pricing itself is provider-set; the gateway does not invent discounts. You still pay the underlying token price, but you avoid writing dual billing code.

For cost-sensitive logging, the normalized usage.prompt_tokens and usage.completion_tokens from n4n.ai can be written to one ledger. With native APIs you maintain two parsers.

Latency and throughput

Measured TTFB depends on model load, not protocol. SSE adds negligible framing overhead versus raw TCP. Anthropic’s named-event format is slightly heavier to parse because of the event: line, but that is microseconds in Python. OpenAI’s flat data: stream is the leanest. n4n.ai’s fallback can add one retry hop on provider degradation, but the client sees no protocol change—just possibly a longer first byte if the primary is down.

Inter-token latency is bounded by the model’s decode speed. No SSE layer introduces meaningful batching delay if you flush per token. Anthropic’s ping events every ~20s keep idle connections open but do not affect token cadence.

Ergonomics

OpenAI’s format is supported by every LLM SDK (langchain, openai, litellm). Anthropic’s format requires its official SDK or a small state machine. Because n4n.ai speaks OpenAI wire format, you reuse the OpenAI client and get 240+ models for free.

from openai import OpenAI
client = OpenAI(base_url="https://api.n4n.ai/v1", api_key=N4N_KEY)
stream = client.chat.completions.create(
    model="gpt-4o",
    stream=True,
    messages=[{"role": "user", "content": "Explain SSE"}]
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

In TypeScript the same OpenAI class works:

import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.n4n.ai/v1", apiKey: N4N_KEY });
const stream = await client.chat.completions.create({ model: "claude-3-5-sonnet", stream: true, messages: [...] });
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Ecosystem and tooling

OpenAI: massive. Anthropic: first-party SDKs for Python/TS, plus community adapters. n4n.ai: leverages OpenAI ecosystem; any tool that accepts a base_url works, including proxy layers like LiteLLM. If you already standardized on the OpenAI client, the gateway requires zero code changes beyond the URL and key.

Limits and failure modes

OpenAI caps stream duration implicitly by request timeout; disconnect yields a 499. Anthropic sends ping events every ~20s to keep proxies alive—handle them or ignore. n4n.ai inherits provider limits but masks transient 429s via fallback; persistent limits surface as standard SSE error data: with error object.

All three recommend client-side timeout and exponential backoff. None guarantee ordering across reconnects. Anthropic’s structured events make partial-state recovery easier; OpenAI’s flat deltas require you to concatenate everything you saw. n4n.ai surfaces the original provider error under error.provider while keeping the OpenAI envelope.

Comparison table

Dimension OpenAI Anthropic n4n.ai
Wire format data: only, [DONE] named event: + data: OpenAI-compatible data:
Usage reporting usage opt-in message_stop data unified usage per token
Model coverage OpenAI only Anthropic only 240+ models, multi-provider
Fallback none none automatic on degrade/429
Client SDK openai, many anthropic, few any OpenAI-compatible
Keepalive none ping events provider-dependent
Routing control n/a n/a header directives honored

Which to choose

Single-vendor prototype: Use the native SDK. If you’re all-in on OpenAI, their SSE is the path of least resistance. Same for Anthropic shops—their event types map cleanly to their message model.

Multi-model production: The sse streaming openai anthropic n4n comparison shows the gateway wins when you must swap models without client changes. Point your OpenAI client at n4n.ai, set routing headers, and get fallback.

Cost-auditing pipelines: If you need uniform token accounting across providers, the normalized usage object saves a translation layer.

Latency-critical, single path: Stay native; skip the extra proxy hop. The protocol difference is trivial, but every network segment counts.

Edge function streaming: OpenAI’s flat format is easiest to parse in constrained runtimes; Anthropic’s events need a buffer. n4n.ai gives you both behind one shape.

Pick the wire format that matches your client code, not the logo on the dashboard.

Tagssseopenai-apianthropic-apicomparison

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All server-sent events (sse) streaming deep dive posts →