The Free Encyclopedia

Measuring Local LLM Performance

Revision as of Oct 27, 2026 12:19 by theLAB.

Local LLM performance includes responsiveness, throughput, memory use, and behavior under concurrent load. A single tokens-per-second number cannot describe all of them.

This article measures serving performance. Evaluating LLMs with Local Benchmarks covers answer quality; a fast configuration that fails the task is not an improvement.

Measure the stages separately

Metric Meaning
Time to first token (TTFT) Client-observed delay until the first generated token
Prompt processing rate Input tokens processed per second
Generation rate Output tokens generated per second
End-to-end latency Time from request start to completed response
Aggregate throughput Work completed across simultaneous requests
Queue time Time waiting before processing begins

Client TTFT can include network transit, queuing, model loading, and prompt processing. A runtime's internal timing fields usually do not include every one of those stages. Record both when diagnosing the user experience.

Make a reproducible workload

Record the model identifier and digest, quantization, runtime version, hardware, context setting, sampling parameters, prompt, and expected output length. Keep these constant when comparing one tuning change.

Use a short interactive prompt, a long-context prompt, and a representative task with tools or structured output. Token counts differ between tokenizers, so comparisons across models need care.

Run cold-start tests separately from warm tests. Warming a model before measuring every request hides startup latency that users may actually encounter. Likewise, prefix caching can change repeated-prompt results; note whether it is present.

Inspect runtime timings

Ollama's non-streaming generation response includes counters and timing fields that can help separate prompt evaluation from generation:

curl --fail-with-body http://localhost:11434/api/generate \
  -H 'Content-Type: application/json' \
  -d '{"model":"YOUR_INSTALLED_MODEL","prompt":"Explain a database index in one paragraph.","stream":false,"options":{"num_predict":128,"temperature":0}}'

For timing fields documented in nanoseconds:

generation tokens/s = eval_count / (eval_duration / 1,000,000,000)

That calculation is not client-observed TTFT. Measure streaming arrival times with a monotonic clock when first-token latency matters. Handle missing fields and zero durations rather than fabricating a rate.

Test realistic concurrency

Start with one request, then increase concurrency gradually. Record per-request latency, completion rate, errors, memory, and total throughput. Stop if the machine becomes unstable or the queue grows without bound.

A higher aggregate throughput can come with worse individual latency. Report medians and tail latency such as p95, together with the sample count. A p95 calculated from only a handful of requests is not a reliable service target.

Read memory and utilization correctly

Observe CPU, system RAM, swap, GPU memory, GPU utilization, and temperatures. More context and simultaneous sequences increase KV-cache requirements. Quantizing model weights does not make those costs disappear.

An out-of-memory failure, CPU offload, thermal throttling, or model eviction can explain large timing changes. Collect the evidence before increasing concurrency or context limits.