How it works

Throughput

How fast llamay runs depends on the model, its quantisation, the hardware and the settings far more than on anything a page can promise. So this page is about measuring it on your own machine: which command, what each number means, and which settings move them.

Measure it

llamay bench -m qwen2.5:0.5b -prompt 512 -gen 128
llamay 0.3.0 · Qwen2.5 0.5B Instruct · qwen2 · 7 threads · kernels neon+i8mm · matmul cpu · gemm own kernels · kv f32
weights 373.71 MiB · repack on · context 32768 · prompt 512 · generate 128

phase      rate          best     note
prefill    169.0 tok/s   3.03s    batched, 256 at a time
decode     27.2 tok/s    4.706s   one token per pass
ttft       3.03s                  time to first token
fork x8    7µs                    0 pages allocated (a copy would be 64)
snapshot   22ms                   12.00 MiB for 512 tokens, at f32
restore    15ms                   vs 3.03s to re-prefill

Restoring a 512-token context is 199.3x faster than recomputing it.

The darwin_arm64 build of 0.3.0 on an Apple M4, CPU only, best of three runs.

The same command with the darwin_arm64_metal build and -gpu, on the same machine and file:

llamay 0.3.0 · Qwen2.5 0.5B Instruct · qwen2 · 7 threads · kernels neon+i8mm · matmul metal:Apple M4 · gemm accelerate · kv f32
prefill   1200.5 tok/s   426ms   one command buffer per 256-token tile
decode    54.7 tok/s     2.34s   506 dispatches per token, one submission

Seven times the prefill and twice the decode, from the build alone. That is the first thing to check when a number looks low.

LineMeansBound by
prefillHow fast the prompt is read.Arithmetic: many tokens per pass, so the multiplies dominate.
decodeHow fast the answer is written, one token per pass.Memory bandwidth: every token reads all the weights once.
ttftTime to the first token of the answer: the prefill, for this prompt.Prompt length.
fork, snapshot, restoreWhat the state engine costs.Page tables, and the disk.

The same command, recorded:

Transcript — the whole session as text
~/llamay $ llamay bench -m qwen2.5:0.5b -gpu -prompt 512 -gen 128 -reps 3
llamay v0.1.58-1-gb14f550 · Qwen2.5 0.5B Instruct · qwen2 · 7 threads · kernels neon+i8mm ·
matmul metal:Apple M4 · gemm own kernels · kv f32
weights 373.71 MiB · repack on · context 32768 · prompt 512 · generate 128

phase     rate          best     note
prefill   794.3 tok/s   645ms    one command buffer per 256-token tile
decode    47.3 tok/s    2.705s   506 dispatches per token, one submission

cpu encoding 133ms · gpu execution 3.175s (4% encoding)

phase      rate   best   note
fork x8    11µs          0 pages allocated (a copy would be 64)
snapshot   35ms          12.00 MiB for 512 tokens, at f32
restore    34ms          vs 645ms to re-prefill

gpu time: staging 41ms · kernels 2.333s · copy-back 50ms

Restoring a 512-token context is 18.9x faster than recomputing it.
~/llamay $ # prefill is arithmetic-bound; decode is memory-bound. One number would hide that
.
Prefill and decode, measured. The command behind the table on the throughput page. It reports the two phases apart because they are bound by different things. Recorded 2026-09-18 · Apple M4, macOS 26.0.1 · llamay v0.1.58-1-gb14f550 · metal:Apple M4 · 0:09

Other measurements

What the state engine is worth at a prompt size worth keeping, with thirty-two branches off it:

Transcript — the whole session as text
~/llamay $ llamay bench -m qwen2.5:0.5b -gpu -forks 32 -prompt 2048 -gen 32 -reps 1
llamay v0.1.58-1-gb14f550 · Qwen2.5 0.5B Instruct · qwen2 · 7 threads · kernels neon+i8mm ·
matmul metal:Apple M4 · gemm own kernels · kv f32
weights 373.71 MiB · repack on · context 32768 · prompt 2048 · generate 32

phase     rate          best     note
prefill   650.4 tok/s   3.149s   one command buffer per 256-token tile
decode    41.7 tok/s    768ms    506 dispatches per token, one submission

cpu encoding 40ms · gpu execution 3.854s (1% encoding)

phase      rate    best   note
fork x32   65µs           0 pages allocated (a copy would be 1024)
snapshot   129ms          48.01 MiB for 2048 tokens, at f32
restore    74ms           vs 3.149s to re-prefill

gpu time: staging 149ms · kernels 9.77s · copy-back 191ms

Restoring a 2048-token context is 42.6x faster than recomputing it.
~/llamay $ # 0 pages allocated where a copy would have been 1024 — that is the fork
What the state engine is worth, at 2048 tokens. The same benchmark with a prompt worth keeping and thirty-two branches off it. The line to read is the last one: restoring that context against computing it again. Recorded 2026-09-18 · Apple M4, macOS 26.0.1 · llamay v0.1.58-1-gb14f550 · metal:Apple M4 · 0:10

What moves the numbers

SettingEffect
The buildThe plain macOS tarball has no Metal; _metal does. On Linux, _gpu carries CUDA and Vulkan. llamay version says what is built in; /healthz says whether the GPU is in use.
QuantisationDecode reads every weight per token, so a q4_k_m file decodes faster than a q8_0 of the same model. Check what it cost with llamay ppl.
-kv vq8A smaller cache: more context and more concurrent requests in the same memory. The trade.
-batch N on serveSeveral requests decoded together read the weights once, so total throughput rises with concurrency. Batch composition never changes the output.
-concurrency, -prefill-chunkHow many requests run at once, and how much of a long prompt is read per step so it does not stall the others.
The prefix cache and contextsA prompt whose start is already computed is not computed again. Keep stable text at the start, and see cached_tokens.
-spec ngram, -lookup, -mdSpeculative decoding: draft tokens from the prompt, or from a smaller model, and verify them in one pass. Pays when the answer repeats the input — editing, extraction — and costs a little when it does not.
-tWorker threads. The default avoids efficiency cores, which would otherwise hold the rest back.

Free throughput where a prompt repeats itself, which is what editing looks like:

Transcript — the whole session as text
~/llamay $ # a prompt that repeats itself, which is what an edited document looks like
~/llamay $ wc -c build/demo/work/repeat.txt
    1464 build/demo/work/repeat.txt
~/llamay $ # first the case it is for: the answer quotes the prompt back
~/llamay $ llamay run -m qwen2.5:0.5b -n 96 -stats -p "$(cat build/demo/work/repeat.txt)
> Repeat the paragraph above, word for word:"
 The quarterly report states that revenue grew by 14 percent. The quarterly report states th
at revenue grew by 14 percent. The quarterly report states that revenue grew by 14 percent.
The quarterly report states that revenue grew by 14 percent. The quarterly report states tha
t revenue grew by 14 percent. The quarterly report states that revenue grew by 14 percent. T
he quarterly report states that revenue grew by 14 percent. The quarterly report states that

prompt 322 tokens in 2.323s (138.6 tok/s) · generated 96 in 7.991s (12.0 tok/s) · stop: leng
th
~/llamay $ llamay run -m qwen2.5:0.5b -lookup -n 96 -p "$(cat build/demo/work/repeat.txt)
> Repeat the paragraph above, word for word:"
 The quarterly report states that revenue grew by 14 percent. The quarterly report states th
at revenue grew by 14 percent. The quarterly report states that revenue grew by 14 percent.
The quarterly report states that revenue grew by 14 percent. The quarterly report states tha
t revenue grew by 14 percent. The quarterly report states that revenue grew by 14 percent. T
he quarterly report states that revenue grew by 14 percent. The quarterly report states that

prompt 322 tokens in 2.102s (153.2 tok/s) · generated 96 in 5.083s (18.9 tok/s)
draft ngram · 96 tokens in 15 passes (6.40x) · 81/88 drafts accepted (92%) · 6.40 tokens per
 target pass · lookahead 8
~/llamay $ # now the case it is not for: a summary shares almost nothing with the prompt
~/llamay $ llamay run -m qwen2.5:0.5b -lookup -n 96 -p "$(cat build/demo/work/repeat.txt)
> Summarise:"
 What is the answer to the question where is the word "growth" in the context of the sentenc
e? The sentence is about a company's growth in revenue. The word "growth" in the context of
the sentence is used to describe the company's increase in revenue over a certain period. Sp
ecifically, the sentence states that the company's revenue grew by 14 percent. The word "gro
wth" is used in this context to indicate that the company's revenue has increased in value

prompt 317 tokens in 2.302s (137.7 tok/s) · generated 96 in 8.052s (11.9 tok/s)
draft ngram · 96 tokens in 79 passes (1.22x) · 17/38 drafts accepted (45%) · 1.22 tokens per
 target pass · lookahead 8
~/llamay $ # the acceptance rate in the last line is the whole story — it is what decides wh
ether drafting is free or wasted
Drafting from the prompt itself, and when it does not pay. -lookup proposes whatever followed this suffix earlier in the context and verifies it against the model. Where the continuation repeats the context — an edit, a quotation, a diff — almost every draft is kept. Where it does not, the drafts are rejected and it is a rounding error slower. Both are here. Recorded 2026-09-18 · Apple M4, macOS 26.0.1 · llamay v0.1.58-1-gb14f550 · metal:Apple M4 · 0:47

Paths that are slower on purpose

Measuring fairly