Skip to content
← Free FDE training guides

Free learning / 40-minute streaming lab

Streaming 101: when is a response actually finished?

See how bytes become events and a partial draft becomes a reviewable result. Compare six local HTTP responses, including interrupted streams and incomplete messages.

No account needed. Use your own copy for writing and keep the original as a reference.

Engineering lab library / Run locally

See what arrived—and what actually completed.

Predict six responses, then change byte grouping and completion requirements separately. Keep partial output distinct from a finished result.

Real HTTP on a temporary loopback port with scripted text. No model, credentials, external service or files. Byte slices and events are observed; model tokens and latency are not measured.

  1. Start here / Node.js 24 · Offline exercise

    Streaming 101 · real local HTTP

    Reconstruct events across byte boundaries, withhold interrupted output and expose a premature-completion defect.

    Node.js 24 · Standard library · Loopback only · No model

You ask an assistant for a draft. Words begin appearing, then the answer stops halfway through a sentence. Did it finish? Did the connection fail? Can you use what appeared? Those are separate questions, and a forward-deployed engineer needs an interface that tells the difference.

This original 40-minute lesson starts with the mechanism, then follows six actual local HTTP responses. It uses fictional text and no model, credentials, packages or cloud account. You need Node.js 24 and permission to listen on a temporary loopback port on your own computer. Nothing is exposed to your network.

1. Name the pieces before following the stream

Streaming is a way to deliver a response incrementally while work proceeds, instead of waiting to deliver the whole body at once. It is a delivery behavior, not a language, model or agent framework. It can make progress visible sooner; it does not by itself make generation faster or the answer correct.

Think of a download progress display. Seeing bytes arrive is different from having a complete, usable file. The analogy has a limit: a generated response usually does not have a known final size, and its content still needs review.

PiecePlain meaningWhat it does not establish
Byte chunkA portion of the response body delivered to the readerOne complete event, character or model token
UTF-8 decoderCode that reconstructs text from bytes, keeping unfinished characters between readsA complete application message
Server-sent events (SSE)A text format for sending events from a server over HTTPThe event names or success rules of a particular model API
DeltaAn addition or change to the result being assembledA complete answer or executable tool arguments
Completion eventAn application-defined signal that a message has endedA factual answer, approved action or acceptable stop reason

In the supplied lab, an event has an event: line, a data: line containing JSON and a blank line that ends the event. The reader must wait for that boundary before parsing the JSON. The service invents start, text_delta and done for this teaching exercise. They are not a provider's API contract.

2. Follow a draft from bytes to a reviewable result

Our fictional service writes three additions: Café , pump: and check seal. The client accumulates them into Café pump: check seal. while marking the preview as partial. The accented character is intentional: one character can occupy more than one byte. The same decoder keeps its state across reads.

Follow four decisions in order:

  1. Confirm the HTTP status and content type before interpreting the body.
  2. Decode bytes, retain unfinished text, then parse complete event records.
  3. Update the preview as deltas arrive while keeping it visibly provisional.
  4. Require the documented completion and acceptable stop reason, then validate the assembled result before the application's next action.

HTTP 200 only describes the response status. The body can subsequently break, end early or contain invalid events. Our lab waits for normal transport end, valid records and done with reason normal before marking a result ready-for-content-review. That deliberately narrow result is not permission to execute a tool or publish the text.

UNDERSTAND THE SYSTEM

The text arrived. Did the response finish?

Follow a fictional maintenance draft through an HTTP stream. The visible preview, event record and completion decision change independently. These are explained examples of the accompanying local lab, not a live model call.

FOLLOW ONE EXAMPLE

See what moves and why.

Authored illustration
01 / EXPLORE THE PARTSTap a part to explain it
Direction of information or workReturn / feedback

WHAT THIS PART DOES

Response service

The local server sends scripted event records over one HTTP response. No model runs and no token usage is measured.

CONNECTED TO
  • Receive bytes: Byte reader
Read the connections in plain English
  1. 01
    Response service → Byte reader

    One read can contain partial or multiple records. It is not a token boundary.

  2. 02
    Byte reader → Complete event

    Decode and retain partial text before parsing a complete event.

  3. 03
    Complete event → Draft preview

    Only text additions change the draft. Progress remains provisional.

  4. 04
    Complete event → Acceptance check

    Inspect the completed message and its stop reason before continuing.

  5. 05
    Draft preview → Acceptance check

    A nonempty draft is insufficient without valid completion evidence.

Check your understanding: The connection ended normally and some text appeared. Can the app mark the draft complete?

Only if the service's documented completion evidence and your acceptance checks are satisfied. In the lab, the missing-done case has both a normal HTTP end and partial text, yet must remain incomplete.

3. Predict and run six local responses

Download fde-streaming-lab.mjs into a new folder. Use the same Node.js 24 command throughout:

Code example
node --version
node fde-streaming-lab.mjs

The file starts a server bound to 127.0.0.1 on an available port, makes six requests and closes the listener. It writes no files and reads no credentials. The server's short pauses make intermediate states observable; they are not measurements of inference performance. It does not retry failed requests.

Before running it, predict the completion decision for each case:

CaseWhat the server or reader changesExpected observation
completeThree deltas followed by normal completionFull text, completion observed, ready for content review
fragmentedSame response; client feeds its decoder one byte at a timeSame text and events despite many more parser slices
missing-doneHTTP body ends normally after two deltas, without completionPartial text, transport ended, completion absent; withheld
connection-lostConnection is destroyed after two deltasPartial text, body-read-interrupted; withheld
limitedFull-looking text followed by a length-limit reasonCompletion observed, but withheld by this app's contract
malformedFinal event contains invalid JSONInvalid record; withheld

Compare httpStatus, transportEnded, events, completionObserved, reason and decision. All six begin with 200. In previews, find text that appeared before any completion event. Do not infer a token count from text length, event count or receivedChunkBytes: the lab runs no model or tokenizer.

receivedChunkBytes records actual body reads; their grouping can vary by runtime and transport. parserSlices counts the pieces passed into our decoder. The fragmented case deliberately re-slices received bytes on the client. It does not claim that the network delivered one-byte packets. The controlled experiment isolates the parser's ability to preserve boundaries.

4. Change one assumption and explain the consequence

Keep the original file. In a first copy, change SLICE_BYTES = 1 to SLICE_BYTES = 7 and rerun. The fragmented case should have fewer parser calls but the same five events and complete text. A reader that relies on each read being a complete JSON object cannot meet that property.

Starting from the original, make a second copy and change REQUIRE_DONE = true to REQUIRE_DONE = false. This deliberately weakens the example's acceptance rule. The missing-done case now promotes Café pump: even though no completion arrived. The lost connection, invalid record and explicit length limit should still be withheld. Explain why a check that only asserts a nonempty response would miss this defect. Do not carry this broken rule into an application.

This is a small protocol lesson, not a general-purpose SSE implementation. The reader supports only the two-field, LF-delimited records emitted by this server. A complete SSE parser also handles other line endings, comments, multiple data lines and additional fields. Use the maintained SDK or parser appropriate to your production service, then test its behavior at your application's boundary.

5. Connect this to Claude and an agent workflow

Claude's documented stream has message and content-block events, text or tool input deltas, a stop reason and final message_stop. These names differ from our teaching protocol. Follow the provider's current SDK and event contract. Tool input can arrive as JSON fragments: a fragment is not yet validated tool arguments. Assemble the intended input, validate its schema and authorize the operation in trusted application code before executing it.

If the stream fails, retain an explicitly incomplete preview and the request's safe diagnostic metadata. A missing final event does not tell you whether a remote operation continued, how much it cost or whether an external effect occurred. Reconnection and safe retry are separate designs. This lab performs one attempt per case and has no continuation, replay or effect reconciliation.

In the UI, separate “receiving,” “ready for review,” “stopped” and “interrupted.” Do not let partial markup run as HTML or partial tool input trigger an action. When a user cancels, stop consuming and request supported cancellation; verify what the provider actually promises about remote work and billing. The local connection-lost case does not test provider cancellation.

For a real deployment, inspect buffering at the application, proxy and gateway. Measure first useful output and completed useful output separately. A responsive animation cannot establish either result. Do not add timing claims based on this fixture's deliberate pauses.

6. Hand over a response contract

Produce a small integration card with:

  • The actual endpoint, content type, event schema and supported client version.
  • Which preview states are visible and what qualifies as completed input.
  • The acceptable stop reasons and content checks before downstream work.
  • What happens after malformed data, a disconnect, timeout or user cancellation.
  • How request identity, retry policy and unknown usage are recorded safely.

Keep your six predictions, observed report and two independent changes. Ask a receiver why both a clean HTTP end and a visible sentence can still be insufficient. Then give them a tool-input fragment and ask what must happen before an agent may use it. A good explanation names assembly, validation, authorization and the unresolved remote outcome without inventing certainty.

Continue in the guided streaming lesson with existing training access, then build the first bounded LangChain agent.

Primary references checked 22 October 2026:

Before you move on

Keep the evidence of your work.

  • Six predictions and observed HTTP reports separating progress from completion.
  • Two controlled changes to byte grouping and completion requirements.
  • A response contract with explicit incomplete states and downstream checks.

Keep these in your own working copy. Reading this page does not save work or record completion.

Suggested next free session

Understand a model response before acting

Compare the response contracts used by Google Cloud, AWS and Azure. This is a suggested sequence; choose the practice that addresses your current gap.

Open the next free guide
Have Academy access?

Continue with worked explanations, practice and review in the related lesson.

Open the related Academy lesson →
Back to top ↑