Context EngineeringLesson 41 of 87

Contents

Context Engineering

Lesson 41 of 87. Sign in to keep your place.

Module 5 · Cost, caching and latency

Where the milliseconds go

9 min read

Input sets the wait, output sets the rest0250050004120thousands of input tokensmilliseconds—— Time to first token– – Decode of four hundred output tokensOne model, four hundred output tokens, ten runs a point, medians. Prefill is compute-bound and growswith input; decode is bandwidth-bound and barely notices how long the input was. Streaming hides thelower line and does nothing for the upper one, which is why a five-second silence is fixed by cachingthe prefix or cutting the input, never by streaming.
One model, four hundred output tokens, ten runs a point, medians. Prefill is compute-bound and grows with input; decode is bandwidth-bound and barely notices how long the input was. Streaming hides the lower line and does nothing for the upper one, which is why a five-second silence is fixed by caching the prefix or cutting the input, never by streaming.

Figure

Two phases with different physics

A model call has two stages and they are bottlenecked by different hardware.

Prefill processes your entire input. Every token is handled in parallel, so this stage is compute-bound: it saturates the arithmetic units of the accelerator. Its duration scales with how many input tokens there are. Prefill is what you are waiting for during time-to-first-token.

Decode produces the output one token at a time. Each token requires reading the whole model’s weights from memory, so this stage is memory-bandwidth-bound and largely indifferent to how long your input was. Its duration scales with how many output tokens you asked for.

That split explains most latency behaviour people find confusing.

Text
time_to_first_token  ≈ queue + prefill(input_tokens)
total_time           ≈ time_to_first_token + output_tokens × time_per_token

What it implies

A long context is slow to start and then normal. Going from 4,000 to 60,000 input tokens can add hundreds of milliseconds to several seconds before anything appears, and then the text streams at the same rate as always. Users describe this as “it hangs and then works”, which is exactly right.

Streaming hides decode, not prefill. Streaming is the standard latency fix and it only helps after the first token. If your problem is a five-second silence, streaming does not touch it. What touches it is a shorter input, a cache hit, or a smaller model.

Output length is the strongest lever on total time. Each output token costs a full pass over the weights. Halving a verbose answer halves most of the wall-clock. “Answer in at most three sentences” is a latency optimisation as much as a style choice.

A cache hit removes prefill for the cached part. This is why caching improves perceived speed as much as it improves cost, and often more noticeably.

The quadratic that mostly is not

Attention is quadratic in sequence length in the arithmetic. In practice, serving stacks have spent years making that not dominate: flash-attention kernels avoid materialising the full matrix, chunked prefill breaks a long input into pieces, and paged caches keep memory usable.

The result is that measured prefill time is closer to linear in input length across the range most applications use, with the quadratic term becoming visible at very long contexts. So do not model prefill as quadratic and do not assume it is free: measure it at the lengths you actually send.

Measure it yourself

Everything here is observable with a stopwatch and a streaming client.

Python
t0 = time.perf_counter()
first = None
for i, chunk in enumerate(stream_call(messages)):
    if first is None:
        first = time.perf_counter() - t0        # TTFT
total = time.perf_counter() - t0
print(f"ttft={first:.2f}s total={total:.2f}s tps={n_out/(total-first):.1f}")

Run it at three input lengths and two output lengths, ten times each, and record medians and 95th percentiles. Half an hour of work replaces every argument your team is going to have about latency.

The 95th percentile is the number that matters. Provider latency is noticeably variable (queueing, capacity, other tenants) and a median that looks fine can hide a tail where one request in twenty takes four times as long.

The rest of the latency budget

The model is often not the largest term. A realistic breakdown for a retrieval-augmented answer:

  • Query rewriting call: 200 to 500 ms, if you do it.
  • Embedding the query: 10 to 50 ms locally, 50 to 200 ms hosted.
  • Vector search: 10 to 100 ms.
  • Reranking 50 candidates: 50 to 400 ms depending on hardware.
  • Prefill on 8,000 tokens: 200 ms to 1 s.
  • Decode of 400 tokens: 2 to 8 s.

Two lessons. The pre-model stages add up to something comparable to prefill, and they are serial by default: run the ones that do not depend on each other in parallel. And decode dominates everything, which puts the answer’s length at the centre of any latency work.

What to do when it is still too slow

In rough order of return:

  1. Shorten the output. Largest effect, no infrastructure change.
  2. Cache the prefix. Removes most of prefill on repeat traffic.
  3. Stream, and show something immediately (the retrieved sources, a skeleton) so the wait is occupied.
  4. Parallelise the pre-model stages.
  5. Cut input length, which the selection module was already arguing for.
  6. Use a smaller model for the easy majority, which the routing lesson covers.

Notice that only the last two change what the model sees. Most latency work is not a context problem, but the two that are, are the ones you now know how to measure.

Every lesson here is open. Your progress is recorded once you pass the Data, SQL and Getting to the Answer exam.

Check your understanding

Users complain about a five-second pause before any text appears. The team enables streaming and the complaint persists. Why?

Pick the one you would defend. Your answer stays private.

Next lesson · 8 minCaching a stable prefix

Stuck on something?Ask Sayali, your AI tutor

How to cite: Addaly (2026) ‘Where the milliseconds go’, in Context Engineering. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/context-engineering/prefill-decode-and-where-the-time-goes (Accessed: 13 October 2026).