zackproser.com · Blueprint Deep Dive011
Memory ledger · Scheduling trace · Complete working drawing

The Inference Engine

Every API endpoint hides a scheduler deciding whose request waits. This drawing works out what actually fills the memory, what makes the first word slow, and why more throughput can mean a worse experience.

PROJECT
DEEP DIVES
DRAWING Nº
TDD-011
SUBJECT
SERVING
SCALE
1 : 1
DRAWN BY
Z. PROSER
READ TIME
15 MIN
DISTRIBUTION · REVISIONS ISSUED BY EMAILGet the next complete drawing.

Behind a language model endpoint sits a resource allocator, and most of what people find surprising about inference latency traces back to it. Every request that gets accepted wants a share of four things: the model weights, scratch space for the arithmetic of a single pass, a KV cache — the running notes the model keeps on every token so far, so it never has to recompute them — and repeated access to the chip and its memory bandwidth. The inference engine decides when each request gets in, where its state lives, which other requests it shares an iteration with, and whether a brand-new prompt is allowed to delay tokens already streaming to somebody else.

This drawing follows one request through, then turns on contention. Serving splits into two phases with completely different shapes. Prefill is the model reading your prompt: it can work on every prompt position at once, so raw compute is the limit. Decode is the model writing its answer one token per pass, each pass re-reading the weights, so memory bandwidth is the limit. Those shapes differ enough that a schedule which raises total tokens per second can simultaneously make the first word slower, or widen the gaps between later ones. Memory splits the same way: weights are mostly fixed, activations spike during a pass, and KV state grows with every live token.

The citable object here is a worked memory-and-time ledger. Its 7B teaching case uses explicit binary units and keeps every category on its own line. The scheduler panel runs fixed synthetic arrivals with the assumptions printed next to them — it demonstrates an algorithm, it doesn't benchmark hardware. Product shootouts and vendor benchmark tables stay off the permanent sheets, because model revision, traffic shape, kernels, hardware, and latency targets each change the answer.

§ 01 · SHEET 1 OF 8

Serving begins where one forward pass ends

You can describe an offline model call as tensor operations and be done. A service has to admit requests, queue them, cancel them, stream them, meter them, isolate them, and recover from them. It takes text or token IDs, applies the chat template and tokenizer, checks the length, picks a replica, waits for capacity, allocates KV pages, runs prefill, samples the first token, and repeats decode until something tells it to stop. Only then can it hand the request's cache blocks back.

State lives at each of those boundaries. The router knows the tenant and the deadline. The scheduler knows arrivals, token budgets, and which sequences are resident. The model runner owns the device buffers and the kernels. The sampler owns the decoding parameters and the random state. The streamer owns backpressure and cancellation. A request can die before a single matrix multiplication happens, finish while its batch peers keep going, or lose its client entirely while device work sits queued on its behalf.

The service clock starts well before the GPU clock. Authentication, request parsing, tokenizer work, replica selection, and queue delay can add up to more than the model time on a short prompt. Streaming adds yet another clock at the network boundary, where a token can be computed and still unavailable to the caller because serialization or a slow connection is backed up. So take timestamps at acceptance, at scheduler admission, at prefill start and end, at each token-ready event, at each token-write event, and at release. Those points separate engine delay from transport delay without pretending the user can't feel both.

ADMIT+ ROUTETOKENIZE+ LIMITQUEUE+ ALLOCATEPREFILLPROMPTDECODE1 TOKENSTREAM+ FREEKV BLOCK TABLE · TOKEN BUDGET · CANCELLATION STATECONTROL PLANEMODEL RUNNER
FIG. 1 — ONE REQUEST CROSSES ADMISSION, TOKENIZATION, SCHEDULING, PREFILL, ITERATIVE DECODE, AND RELEASE. KV STATE IS ALLOCATED BEFORE COMPUTE AND FREED AFTER THE TERMINAL TOKEN OR CANCELLATION.
Cancellation must reach both scheduler and cache manager. Releasing the HTTP connection without removing queued/device work wastes capacity; freeing blocks before in-flight kernels stop risks corrupt reuse.

All of which makes serving its own discipline, separate from model architecture. The Transformer drawing's KV-cache section covers why earlier keys and values can be reused at all. The inference engine takes that reuse and turns it into an allocation and scheduling problem spanning many unrelated sequences. The site's interactive demos index has adjacent tokenization and retrieval experiments; the scheduler below stays on this page so its assumptions sit next to the ledger they belong to.

Q — Why can a model fit on a GPU and still fail to serve one request?

The weight file may fit while the complete runtime does not. Kernel workspaces, graph captures, allocator reserve, activations, and the request’s growing KV cache require additional bytes. “Weights fit” answers one ledger line, not the resident-memory total.

§ 02 · SHEET 2 OF 8

Prefill and decode ask the accelerator for different work

Prefill eats the whole prompt. Inside each layer, many prompt positions get projected and processed at once. Attention still respects the causal mask, but what reaches the device is large matrix operations with a lot of arithmetic per launch. Prompt length is what drives time-to-first-token, because decode can't emit anything until the prompt's final position has made it through the model.

Decode picks up where prefill stopped. Each active sequence contributes one current token to the iteration, reads back its previous KV entries, produces logits, samples a token, and appends one K vector and one V vector at every layer. The serial dependency is absolute — token t + 1 needs token t and there's no way around it. Batching adds more sequences to the iteration. No scheduler anywhere can parallelize the future positions of a single autoregressive sequence.

EQ. 2.1

TTFT [ms/request] = queue delay [ms/request] + prefill service [ms/request] + first-step overhead [ms/request]

EQ. 2.2

ITLi [ms/token] = available time(tokeni+1) [ms] − available time(tokeni) [ms]

PREFILLDECODEP1P2P3P4P5P6P7P8T1T2T3T4T5T6T7MANY PROMPT POSITIONS IN LARGE KERNELSONE NEW TOKEN PER SEQUENCE PER ITERATION
FIG. 2 — PREFILL EXPOSES PROMPT-POSITION PARALLELISM; DECODE EXPOSES SEQUENCE-LEVEL BATCHING BUT RETAINS A TOKEN-BY-TOKEN DEPENDENCY WITHIN EACH REQUEST.

That difference is what predicts interference. Admit one long prefill whole and it can hold the runner long enough to widen the decode gaps for every sequence already streaming. Chunked prefill cuts the prompt into bounded pieces of token work so decode iterations can slip in between the chunks. SARATHI[1] formalized that piggybacking; DistServe[2] went further and treated prefill and decode as separable phases you can provision against different latency objectives.

Token throughput needs two counters, because input and output tokens are shaped differently. A prefill-heavy service can post an impressive total-token rate while streaming very few tokens to anyone. A decode-heavy service can spend most of its life rereading weights and growing KV for tiny one-token batches. Report input tokens/s and output tokens/s separately, with the request lengths beside them. End-to-end latency scales with requested output too — roughly TTFT plus the sum of the later ITLs — so comparing requests with different completion lengths without bucketing them is mixing workload into what looks like system behavior.

Example timing vocabulary: a request accepted at 0 ms, admitted at 18 ms, and first streamed at 94 ms has 18 ms queue delay and 94 ms TTFT. Tokens arriving at 94, 121, and 151 ms yield ITLs of 27 and 30 ms/token.
§ 03 · SHEET 3 OF 8

Weights, activations, and KV state occupy different ledgers

Weight memory is mostly fixed once a replica has loaded. Call P the parameter count and bw the stored bytes per parameter. Quantized formats bring along scales, zero points, packing, and sometimes a higher-precision subset, so that metadata belongs on the same line instead of vanishing into a slogan about bit width.

EQ. 3.1

Mweights [bytes] = P [parameters] × bw [bytes/parameter] + Mmetadata [bytes]

Activation and runtime memory moves around with kernels, batch token count, graph captures, temporary outputs, communication buffers, and allocator policy. Measure it at the batch shape you actually intend to run and carry it as Mruntime,peak. Training-style "activations per token" estimates tend to mislead here, because inference kernels fuse operations and reuse storage in ways the training math doesn't anticipate.

KV state scales directly, and the arithmetic is unforgiving. With L layers, Hkv KV heads per layer, head dimension dh elements per head, S sequence tokens per request, and bkv bytes per cached element, every single token stores one key and one value at every layer.

EQ. 3.2

MKV,request [bytes/request] = 2 [K,V] × L [layers] × Hkv [heads/layer] × dh [elements/head] × S [tokens/request] × bkv [bytes/element]

The worked case assumes 7,000,000,000 parameters in BF16, no added weight metadata, 32 layers, 8 KV heads, head dimension 128, BF16 KV, 4,096 tokens per resident request, and 16 resident requests. Weights consume 14,000,000,000 bytes = 13.04 GiB. KV consumes 131,072 bytes/token = 128 KiB/token, then 536,870,912 bytes/request = 0.50 GiB/request, then 8.00 GiB for 16 requests. Add a separately budgeted 3.00 GiB runtime peak and a 4.00 GiB safety reserve on a 40 GiB device. The committed-plus-reserved total is 28.04 GiB.

Sequence length in that multiplication means each request's current prompt plus what it has generated so far — not the configured maximum, unless memory really is reserved out to that maximum. For a mixed batch, swap N × S for the sum of live sequence lengths, Σr Sr. Paging rounds each request up to a block boundary, so physical allocation works out to Σr ceil(Sr / B) × B tokens for block size B. Prefix sharing can push physical occupancy below the naïve sum when several requests point at the same immutable blocks, and copy-on-write hands ownership back apart the moment a branch diverges.

The safety line is deliberate capacity, not unidentified waste. It absorbs measurement error, allocator behavior, and transient shapes you didn't plan for. Pick it from observed peaks and from how much failure you can tolerate, then write it into the workbook by name. When a runtime reserves memory without committing it, record allocator-reserved and tensor-allocated bytes as two numbers. Device telemetry on its own can't tell you which bytes are reclaimable or which request owns them.

Worked units: 1 KiB = 2^10 bytes and 1 GiB = 2^30 bytes. Decimal “GB” would produce different displayed values. The parameter count is exactly 7.0 billion for arithmetic, not a claim about a named checkpoint.
INTERACTIVE — KV CACHE LEDGER · BINARY UNITS
KV/TOKEN = 2 × 32 LAYERS × 8 KV HEADS × 128 ELEMENTS/HEAD × 2 BYTES/ELEMENT
= 131,072 BYTES/TOKEN = 128.0 KIB/TOKEN
KV/REQUEST = 131,072 BYTES/TOKEN × 4,096 TOKENS = 0.500 GIB
TOTAL KV = 0.500 GIB/REQUEST × 16 REQUESTS = 8.00 GIB
FIG. 3 — CACHE CAPACITY FROM MODEL SHAPE AND LIVE TOKENS. EXCLUDES WEIGHTS, ACTIVATIONS, ALLOCATOR RESERVE, AND BLOCK ROUNDING.

Grouped-query attention drops Hkv below the query-head count, which is exactly why the cache formula asks for KV heads rather than total attention heads. The GQA paper[3] covers converting multi-head checkpoints down to fewer KV heads. Read the ledger inputs off the model configuration, not off the size in its name.

Q — How many concurrent 4,096-token requests fit in the worked 40 GiB device?

The memory-only ceiling is floor((40 − 13.04 − 3.00 − 4.00) GiB ÷ 0.50 GiB/request) = 39 requests. That does not promise acceptable latency or 39 simultaneous compute slots. It says the declared memory categories leave room for 39 equal-size KV allocations under these assumptions.

§ 04 · SHEET 4 OF 8

Paging turns variable sequences into block tables

A naïve allocator hands each request one contiguous region sized to its maximum sequence. When the output finishes early, the unused tail is stranded. Allocate and free enough differently sized regions and you end up with plenty of total free memory and no single hole big enough for the next request. Copying a cache to grow it adds memory traffic at exactly the moment the engine is busiest.

PagedAttention[4] borrows an operating-system idea for KV storage. A request's logical cache gets divided into fixed-size token blocks, and its block table maps logical block numbers onto non-contiguous physical ones. The next token either fills the current block or triggers another allocation; when the request completes, its blocks go back to a shared pool. Only the last block carries ordinary rounding waste. The vLLM paper also works through copy-on-write sharing for common prompt state and for parallel sampling.

CONTIGUOUS RESERVATIONPAGED KV POOLREQUEST BLOCK TABLETAILFREE HOLESL0 → P9L1 → P2L2 → P14L3 → PARTIAL
FIG. 4 — CONTIGUOUS RESERVATION STRANDS UNUSED TAILS AND HOLES. PAGING MAPS EACH LOGICAL SEQUENCE TO FIXED PHYSICAL KV BLOCKS; ONLY ITS LAST BLOCK NEEDS PARTIAL OCCUPANCY.

Block size is a genuine trade rather than a tuning knob with a right answer. Smaller blocks cut last-block waste and make small growth increments cheaper, at the price of more block-table entries and more allocation operations. Larger blocks keep the metadata simple and can suit the kernels better, while amplifying rounding loss across a population of short sequences. Prefix caching layers a second policy question on top: reusable blocks only save prefill work if the hit rate and the reuse lifetime repay the bytes and the lookup.

Work an example. Three requests with live lengths of 17, 33, and 65 tokens, under 16-token blocks. Logical occupancy is 115 tokens. Physical occupancy is 2 + 3 + 5 = 10 blocks, or 160 token slots, which leaves 45 slots idle across their last blocks. Drop to four-token blocks and physical occupancy falls to 124 slots while block-table entries climb from 10 to 31. That arithmetic covers rounding and nothing else — kernel layout, allocator metadata, and shared prefixes each add their own term.

Paging improves allocation efficiency. It doesn't reduce the logical KV bytes the formula demands. When pressure arrives anyway, an engine can refuse admission, preempt a sequence, swap its state out, or free it and recompute the prefix later. Every one of those has a latency cost attached. Which is how "no OOM" ends up coexisting perfectly comfortably with cache thrash and terrible tail latency.

§ 05 · SHEET 5 OF 8

Iteration-level scheduling connects utilization to latency

Static batching locks a group of requests together for a larger span of work. Padding makes the short prompts pay for the longest prompt's shape, and a short generation leaves its slot idle until the longer peers catch up. New arrivals wait for the batch boundary. It's simple, and it's fine for homogeneous offline jobs. Interactive traffic almost never arrives or finishes in lockstep.

Continuous batching revisits membership at every iteration boundary. Finished sequences leave, and admitted ones join whenever the token and memory budgets allow. Orca[5] named the underlying move iteration-level scheduling and paired it with selective batching. Paged KV allocation is what makes changing membership practical, since each request carries a block table instead of a fixed rectangular slab of cache.

The scheduler still has to decide whose latency to spend. First-come, first-served is beautifully predictable right up until a long prompt blocks the line. Prioritize prefills and new-request TTFT improves while ITL stretches for everything already decoding. Prioritize decodes and the streaming cadence holds while the queue ages behind it. Chunking prefills caps the interference. Tenant weights, deadlines, maximum batched tokens, preemption cost, and replica routing all bend the trace further.

INTERACTIVE — REQUEST SCHEDULER · T+000 TICKS
QUEUE
PREFILL
R1 · 256/512
DECODE
KV PAGES
32 / 256 BLOCKS
32.0 / 256 MIB
0 EVICTIONS
0 / 8 DONE
P50 TTFT
300 MS
P95 TTFT
960 MS
OUTPUT RATE
118.9 TOK/S
FIG. 5 — ILLUSTRATIVE DETERMINISTIC SCHEDULER, NOT A GPU BENCHMARK. FIXED ARRIVALS; 20 MS TICKS; 64 KIB OF KV PER TOKEN; PREFILL PROCESSES 256 TOKENS/TICK.

The panel's metrics treat request acceptance as time zero. Push the prompt length up to add prefill work, drop the KV budget to force admission pressure, or hold arrivals fixed and compare policies against each other. Its synthetic tick costs are deliberately visible rather than hidden. A production comparison needs real prompt and output distributions, a declared SLO, warm-up, model and tokenizer revisions, kernel versions, accelerator topology, and input/output token accounting kept apart.

Tail example: seven 512-token prompts and one 1,792-token prompt enter the fixed trace. A static group waits on the long member. Continuous admission can release finished slots earlier, while prefill priority can still create a large decode gap.
Q — Why can p95 look healthy while p99 collapses?

A small class of long prompts, burst arrivals, allocator retries, preempted sequences, or replica imbalance can occupy less than five percent of samples yet dominate the slowest one percent. Record the joint prompt/output distribution and correlate tail requests with queue age, prefill chunks, evictions, and replica assignment.

DETACHABLE PLATE · TDD-011-PLATEA2 poster + editable workbook · PDF
Inference Capacity Workbook
  • Weight, runtime, and KV formulas with the worked 7B ledger
  • Concurrency envelope and quantization decision tables
  • TTFT, ITL, percentile, and benchmark-input record
  • One-page OOM, queue-growth, and cache-fragmentation checklist
§ 06 · SHEET 6 OF 8

IO-aware attention and quantization attack different costs

Standard attention materializes intermediates, or shuttles them repeatedly between high-bandwidth memory and the faster memory on chip. FlashAttention[6] tiles the queries, keys, and values, computes attention blocks on chip, and keeps the softmax statistics it needs to combine those tiles exactly. Memory traffic and temporary storage change; dense attention is not approximated. IO-awareness is the whole point — fewer floating-point operations buy you nothing in wall-clock time when data movement is what's actually limiting you.

HBM · LARGE / HIGH LATENCYQ, K, V BLOCKS · OUTPUT BLOCKSSRAM · SMALL / FASTTILED SCORES · ONLINE SOFTMAX · VALUE ACCUMULATIONFEWER HBM READS / WRITES
FIG. 6 — FLASHATTENTION TILES ATTENTION SO Q, K, AND V BLOCKS ARE REUSED IN FAST ON-CHIP MEMORY WHILE SOFTMAX STATISTICS ARE ACCUMULATED; THE FULL SCORE MATRIX NEED NOT BE WRITTEN TO HBM.

Quantization changes the representation instead. Lower-bit weights shrink stored bytes and memory traffic. Lower-bit activations can open up different matrix kernels. Lower-bit KV shrinks the per-token cache line. Those are three separate decisions with three sets of calibration, kernel, and quality consequences, and collapsing them into one "we quantized it" hides which one broke. A nominally four-bit weight file can still dequantize back up to higher precision for operations that lack support, carry scales and outliers alongside, or run kernels that underperform at small batch sizes.

SmoothQuant[7] goes after the activation outliers that make W8A8 post-training quantization hard. For a channel-wise scale s, the transformation divides activation channel X by s and multiplies the matching weight channel by s. Before quantization their product is mathematically identical; what's moved is the difficulty, from activations toward weights, which calibrate more easily under the method's assumptions. The quantized computation can still introduce error of its own.

EQ. 6.1

(X diag(s)−1)(diag(s) W) = XW   [same real-valued product before rounding]

Quantization stops being free at several different boundaries: when the quality loss crosses whatever the task can tolerate, when conversion or calibration turns operationally fragile, when the target hardware turns out not to have the kernels you assumed, when metadata eats the memory savings you were counting on, or when latency moves the wrong way at your deployed batch shape. Use perplexity only if perplexity predicts your application. Otherwise measure the task evaluation, the prompt languages, structured-output validity, and the tail cases the endpoint has to keep getting right.

Keep the memory claims tied to whichever target you picked. Weight-only quantization cuts the fixed replica line and leaves BF16 KV exactly where it was, so long-context concurrency barely moves once weights have stopped dominating. KV quantization changes bytes/token directly and brings its own accuracy and kernel questions. Activation quantization is mostly aimed at compatible matrix execution and transient storage. You can combine all three in one deployment — just keep three rows in the capacity workbook, so a regression can be traced back to the representation that changed.

§ 07 · SHEET 7 OF 8

Capacity is an envelope bounded by memory, compute, and latency

A concurrency number without a workload attached is half a sentence. Memory capacity depends on resident tokens. Compute capacity depends on input and output token rates, batch shapes, kernels, and parallelism. Service capacity adds the latency objectives on top, because a request only counts as useful if it met its TTFT, ITL, or end-to-end deadline. What you usually want is goodput — completed work that landed inside the stated SLO.

EQ. 7.1

Nmemory [requests] = floor((Mdevice − Mweights − Mruntime,peak − Msafety) [bytes] / MKV,request [bytes/request])

USEFUL OUTPUT TOKENS / SCONCURRENT REQUESTS →LATENCY CEILINGMEMORY CEILINGRAW THROUGHPUTSAFE MEASURED REGION
FIG. 7 — THE SAFE OPERATING REGION LIES BELOW THREE CEILINGS. MORE CONCURRENCY MAY FIT IN MEMORY YET MISS TTFT OR ITL; MORE RAW TOKENS PER SECOND MAY ARRIVE AFTER THEIR DEADLINES.

Build the envelope by sweeping offered load and length buckets rather than quoting a single saturation point. Hold the model and system revision fixed while you do it. Record p50, p95, and p99 for queue delay, TTFT, ITL, and end-to-end latency, plus input tokens per second, output tokens per second, cache occupancy, and preemptions. Then repeat the whole thing for burst shapes that look like your production traffic. Stop turning up the load when the declared SLO breaks, even though aggregate throughput will happily keep climbing past that point.

Use an open-loop load generator when the question is how the system behaves in overload. A closed-loop client that waits for one response before sending the next quietly reduces its own arrival rate as latency rises, which conceals exactly the queue growth you were trying to see. Record offered rate and achieved completion rate as separate numbers. Warm-up should cover model load, graph compilation or capture, allocator stabilization, and cache state — and the measured window should still include the cold behavior real users hit, whenever scale-to-zero or replica churn is part of production.

Replicas add another queueing layer on top of all of it. More replicas cut queue delay and isolate failures, and each one duplicates the weights unless the topology shards the model. Tensor or pipeline parallelism trades that for communication cost and different per-device memory. A router that balances by request count will cheerfully pile long prompts onto one replica while another handles short completions. Token-aware routing and per-replica telemetry are what make that imbalance visible before a customer finds it.

§ 08 · SHEET 8 OF 8

Failure lines reveal which serving layer you need

OOM is either a ledger violation or an allocation spike, and the two need different fixes. Break the number apart: load-time weights, runtime peak, logical KV, physical KV blocks, allocator reserve, communication buffers. Record which phase died — model load, prefill admission, decode growth, or graph capture. Lowering maximum concurrency can paper over a per-request cache you underestimated; lowering maximum sequence length can paper over an admission policy with no bound on it.

Queue collapse starts the moment sustained admitted work outruns completion capacity. Queue age rises, TTFT stretches, clients retry, and the retries push offered load higher still. Admission control, bounded queues, load shedding, and retry budgets are what stop a slow service from turning into a positive-feedback loop. Scaling out after saturation only helps if the new replicas come up before the queue and the retry storm have eaten the deadline.

Cache thrash shows up as frequent preemption, eviction, swapping, or prefix recomputation. The engine can sit comfortably below any OOM threshold while useful work falls, because it keeps reprocessing the same prompt tokens over and over. Compare logical live KV bytes against reserved block bytes, allocation failures, prefix-cache hit rate, and recomputed tokens. And test a block-size change against the real sequence distribution — picking it from the average length is how you end up optimizing for a sequence nobody sends.

OOMQUEUE COLLAPSECACHE THRASHWEIGHTS+ RUNTIME PEAK+ PHYSICAL KV+ RESERVEPHASE OF FAILURE?ARRIVALS > COMPLETIONSQUEUE AGE ↑TTFT ↑RETRIES ↑ADMISSION BOUND?PREEMPTIONSEVICTIONSRECOMPUTED TOKENSCACHE HIT RATE ↓USEFUL WORK?
FIG. 8 — THREE FAILURE LINES MAP TO DIFFERENT EVIDENCE: OOM TO THE MEMORY LEDGER, QUEUE COLLAPSE TO ARRIVAL VERSUS COMPLETION RATES, AND CACHE THRASH TO LOGICAL STATE VERSUS ALLOCATION AND RECOMPUTATION EVENTS.

Where you sit on the stack follows from what you need to own. An engine makes sense when you control the model processes and need direct access to scheduling, kernels, cache policy, and hardware tuning. An endpoint platform makes sense when you want a deployable model service with autoscaling, routing, observability, and operational APIs, while keeping real runtime choices in your hands. Managed inference makes sense when the provider can own the accelerators, the upgrades, the availability, and most of the capacity planning under a contract you're able to test.

Required control, required evidence, and staff time set that boundary. Custom kernels and cache policies mean owning the engine. Data residency, pinned revisions, or strict tail SLOs may mean a dedicated endpoint. Variable traffic and a small operations team point toward managed capacity. Whichever way it goes, keep the same benchmark input record and the same latency vocabulary. Abstraction can move the operations off your plate; it can't make the workload assumptions disappear.

Portability has limits worth naming before you commit. An engine configuration couples model architecture, quantized format, kernel availability, device generation, parallelism, and traffic into one thing. An endpoint contract couples scale behavior, quota, routing, observability, and revision policy. A managed API might expose nothing below request-level metrics. So work out the lowest layer at which your team will have to diagnose a missed SLO. If the cache, scheduler, or kernel evidence you'd need lives below the product boundary, either write that evidence into the contract or own the layer it comes from.

Q — What should be compared before choosing an engine, endpoint, or managed API?

Compare the exact model and revision, supported precision, maximum input/output tokens, isolation, cold-start behavior, streaming semantics, cancellation, observability, measured TTFT/ITL under your traffic, failure policy, data handling, and total operating ownership. A vendor throughput row without those fields cannot support the decision.

APPENDIX A — RFI DESK · REQUEST FOR INFORMATIONTDD-011-A

Anything on this sheet still unclear — or anything you were too polite to ask out loud? File an RFI. Answers come from the drawing itself and cite their sheet numbers, and every question is recorded in the drawing log so the next revision can answer it in print.

IN PRODUCTION · TDD-012 · THE GUARDTDD-011-D
GET THE NEXT DRAWING

One complete technical schematic, issued by email when it is ready. Free; one-click unsubscribe.

END OF DRAWING · TDD-011 · REV A · JUL 2026
✓ CHECKED — YOU ARE NOW AN EXPERT