Crux Read real SSE-parsing and streaming-client snippets, predict the behaviour, and pick the highest-leverage fix — event framing, delta accumulation, client abort, and partial-JSON tool args.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 14 min
The SSE parser, the accumulator, and the abort path are where streaming bugs actually live. Read each snippet, predict what it does under real traffic, then choose the fix a senior engineer makes first.
Goal
Practise the loop you run on every streaming incident: read the parsing and client code, predict where it corrupts or hangs, and reach for the framing/accumulation/cancellation fix rather than blaming the model.
Snippet 1 — the SSE frame parser
const reader = res.body.getReader();const decoder = new TextDecoder();while (true) { const { value, done } = await reader.read(); if (done) break; const text = decoder.decode(value); // one network chunk for (const line of text.split("\n")) { if (line.startsWith("data: ")) { const evt = JSON.parse(line.slice(6)); // parse immediately handle(evt); } }}
Quiz
Completed
This parser works in dev but throws JSON.parse errors under load. What is the bug, and the fix?
Heads-up Speed is not the issue — correctness is. The parse throws because the 'data:' payload is a fragment of a frame split across TCP chunks, not because JSON.parse is slow.
Heads-up fetch + ReadableStream is a valid and common way to consume SSE (and required for POST/auth headers). The defect is not buffering across chunk boundaries, which any correct parser must do.
Heads-up The server frames are valid; your reader is slicing them mid-frame at arbitrary TCP boundaries. Buffer until you have a full event before parsing.
Snippet 2 — the delta accumulator
let text = "";const toolArgs = {}; // index -> string bufferfunction handle(evt) { if (evt.type === "content_block_delta") { if (evt.delta.type === "text_delta") { text += evt.delta.text; render(text); } else if (evt.delta.type === "input_json_delta") { const i = evt.index; toolArgs[i] = JSON.parse(toolArgs[i] + evt.delta.partial_json); // (!) } }}
Quiz
Completed
The text path is correct. What is wrong with the tool-argument path?
Heads-up Each content block carries an index, and multiple tool calls in one message are distinguished exactly by that index. Indexing is correct; parsing per-delta is the bug.
Heads-up Tool args are structured input for a function, not display text. Even as a 'calling tool…' hint you show the raw partial string — you never act on it until the block closes.
Heads-up Wrapping the concatenation in JSON.parse means every intermediate fragment is parsed and throws. The canonical form accumulates a string and parses only at content_block_stop.
Snippet 3 — client cancellation
function ask(prompt) { return fetch("/api/chat", { method: "POST", body: JSON.stringify({ prompt }), }).then(consumeStream);}// User clicks "Stop". The UI stops rendering tokens.// But the server keeps generating, and billing keeps counting.
Quiz
Completed
Clicking Stop hides tokens but the model keeps generating and you keep paying. What is the correct fix end-to-end?
Heads-up Not rendering hides tokens locally but leaves the fetch, the server handler, and the upstream model generation all running. You keep paying for tokens no one sees.
Heads-up That caps every response, not just cancelled ones, and still cannot stop a generation early on user intent. Cancellation needs an abort signal propagated to the provider, not a length cap.
Heads-up This uses fetch/SSE, not WebSockets, and fetch streams are cancellable via AbortController. The real requirement is propagating the abort all the way to the upstream provider call.
Snippet 4 — server backpressure
// Express-style SSE endpoint proxying an upstream model streamfor await (const evt of upstreamStream) { res.write(`data: ${JSON.stringify(evt)}\n\n`); // ignore return value}res.end();
Quiz
Completed
A slow client (mobile, weak signal) consumes events slower than the upstream produces them. What does this loop do, and what is the fix?
Heads-up TCP flow-control fills the kernel buffer, but Node then queues unwritten data in userland memory unbounded. Ignoring write()'s false return is exactly how a slow consumer OOMs the server.
Heads-up write() never silently drops data; it buffers it in memory and signals fullness via the false return. The failure mode is unbounded memory growth, not lost events.
Heads-up Serialization cost is not the bottleneck for a slow client. The problem is producing faster than the client drains; the fix is honoring write() backpressure, not faster encoding.
Recap
Every streaming bug is read in the parser, the accumulator, the abort path, or the write loop: SSE frames must be buffered and split on the blank-line delimiter because TCP chunks don’t align with events; tool-arg input_json_delta fragments accumulate as a string and parse only at content_block_stop; client Stop must drive an AbortController whose signal propagates to the upstream provider or you keep generating and paying; and a server proxying a stream must honor write()‘s false return (pause upstream, resume on drain) or a slow client balloons memory. Read the code path, predict the failure under real traffic, fix the framing/cancellation/backpressure — then re-test against a slow, flaky client.