Benchmark suite and community leaderboard for local LLM inference on Apple Silicon
Project description
mlx-Chronos ⏱️
Benchmark suite and community leaderboard for local LLM inference on Apple Silicon.
Run it. Share your results. Compare across hardware.
What is mlx-Chronos?
mlx-Chronos is a standardized benchmarking tool for local LLM inference engines on Apple Silicon. It automatically detects your hardware, runs a consistent set of tests across installed engines, and produces a structured JSON result you can contribute to the community leaderboard.
Supported engines:
- Ollama (MLX backend)
- oMLX
- Rapid-MLX
- mlx-lm (Apple MLX)
Metrics measured:
- TTFT — Time to First Token (cold and cached, with statistics)
- tok/s — Client-observed request throughput (mean, stddev, min, max across trials)
- Sustained tok/s — Optional long throughput profile for heat buildup and late-run degradation checks
- Output tokens — Completion token counts for throughput trials
- System RAM peak — Peak total Mac RAM in use during the benchmark, used as the public memory comparison metric
- Engine RSS — Diagnostic peak RSS of the engine server process when available
- Tool calling — Success rate (coming in v0.2)
How It Works
When you run mlx-Chronos, it executes a fixed benchmark protocol against the running engine:
Cold TTFT — sends a prompt to the model and measures the time from request to first non-empty streamed token, including whitespace-only text tokens. Each trial uses a unique prompt to avoid cache hits.
Cached TTFT — sends the same fixed prompt on every cached trial. A priming call loads it into cache first, then cached trials run consecutively. This measures cache performance without interleaving unrelated prompts between cached measurements.
Request throughput (tok/s) — measures completion tokens divided by the full
client-observed request time for a standard fixed prompt. This includes request
overhead, prefill, and decode, so it is an end-to-end throughput metric rather
than pure decode speed. New runs also record client-observed
decode_tokens_per_second from the streaming throughput trial when reliable
completion-token usage is available. If an engine cannot provide usage in the
streaming response, the run falls back to a local estimate and is marked as not
leaderboard-comparable. Throughput uses a fixed
requested max_tokens value by default, and optional output token bounds can be
requested with --max-tokens / --min-tokens.
System RAM peak — continuously samples total Mac RAM usage from before warmup through the recorded benchmark phases and reports the observed peak in GB and percent. This is the public leaderboard memory metric because it answers the practical question of how much memory pressure the run placed on the Mac.
Thermal monitor — records phase timings plus a lightweight thermal summary during the run when macOS thermal state is available through Foundation/PyObjC. New JSON results include start/end/worst thermal state, sample count, and phases where non-nominal thermal state was observed.
Sustained profile — --profile sustained runs a single long throughput
trial with max_tokens=1000 by default and records progress samples every 100
generated output units. These samples make late-run throughput drops easier to
spot. When a sustained run also observes a thermal-state change or non-nominal
thermal state, mlx-Chronos records a sustained throttling warning in result
metadata.
Cooldown tracking — before each run, mlx-Chronos checks the latest prior
JSON result in the same output directory. The elapsed time is saved as
meta.elapsed_since_last_benchmark_seconds; --cooldown-seconds can enforce a
pause before starting a new run.
Peak engine RSS — records the resident memory of the engine server process
after warmup, through the recorded benchmark phases, when the process can be
identified. This is diagnostic only: it is not total model memory or a public
efficiency ranking metric, because macOS/Metal unified-memory accounting can
vary across environments. The default RAM sampling interval is 50ms and can be
changed with --ram-sample-interval.
All metrics are run over multiple trials and reported with mean, stddev, min,
and max. p95 is added only when at least 20 trials are available. The default is
5 trials, with a maximum of 30 unique cold prompts.
Results are saved as structured JSON in results/local/ by default. Maintainers
publish reviewed JSON files into results/submitted/ after accepting them for
the community leaderboard.
New result JSON also records the benchmark protocol metadata, including exact
prompt text and requested token bounds, so runs can be reproduced without
digging through source code.
Current protocol v2 throughput uses streaming requests with usage metadata.
Older protocol v1 results used non-streaming throughput, so compare those rows
with that workload difference in mind.
Community Leaderboard
View the full leaderboard with all submitted results:
→ igurss.github.io/mlx-chronos
The leaderboard supports model search plus engine, chip, machine model, memory, and throughput max-token filters so contributors can quickly compare a specific model across local inference engines and Apple Silicon hardware.
Current Release
0.1.2 is a compatibility-preserving patch release over 0.1.1. It adds
sustained benchmark runs, cooldown metadata, throughput token-bound metadata,
client-observed decode throughput when reliable usage data is available, and
clearer warnings for fallback token counts and unknown engine versions.
Quick Start
# Install
pip install mlx-chronos
# Check available engines
mlx-chronos engines
# Validate setup before a run
mlx-chronos validate --engine omlx --model "Qwen3.5-4B-OptiQ-4bit"
# Run benchmark (JSON by default)
mlx-chronos run --engine omlx --model "Qwen3.5-4B-OptiQ-4bit"
# Optional: request throughput output token bounds
mlx-chronos run --engine omlx --model "Qwen3.5-4B-OptiQ-4bit" --max-tokens 100 --min-tokens 80
# Optional: sustained profile for a longer heat/throttling-sensitive run
mlx-chronos run --engine omlx --model "Qwen3.5-4B-OptiQ-4bit" --profile sustained
# Optional: enforce a pause after a recent run in the same output directory
mlx-chronos run --engine omlx --model "Qwen3.5-4B-OptiQ-4bit" --cooldown-seconds 300
# Optional: write both JSON and Markdown outputs
mlx-chronos run --engine omlx --model "Qwen3.5-4B-OptiQ-4bit" --format all
# Optional: choose a custom output directory
mlx-chronos run --engine omlx --model "Qwen3.5-4B-OptiQ-4bit" --output-dir ~/Desktop/benchmarks
Note: the engine server must be running before you launch mlx-chronos. See CONTRIBUTING.md for setup instructions.
Contributing Your Results
- Run
mlx-chronos runon your Mac - A JSON file is generated in
results/local/(use--format allfor a Markdown summary too) - Check the result without sending it:
mlx-chronos submit --file results/local/your-result.json --dry-run
- Send the JSON to the maintainer inbox:
mlx-chronos submit --file results/local/your-result.json
- The maintainer reviews accepted JSON files and publishes verified results manually
Leaderboard submissions must report throughput using the engine response's
usage.completion_tokens. Local runs can still be saved with a fallback token
estimate, but those results are not accepted for the public leaderboard and are
marked with meta.word_fallback_warning.
Maintainers can override the public inbox endpoint with --endpoint or the
MLX_CHRONOS_SUBMIT_ENDPOINT environment variable. The command sends the JSON
file as result_json plus brief form metadata so the inbox provider does not
classify the submission as blank spam. To include a real contact address, pass
--email or set MLX_CHRONOS_SUBMITTER_EMAIL.
See CONTRIBUTING.md for detailed instructions.
Benchmark Methodology
See docs/methodology.md for a full explanation of what is measured, how, and why.
Roadmap
Completed
- Core benchmark runner with repeated trials, warmup, cache priming, and phase-separated metrics
- Engine support for oMLX, Rapid-MLX, mlx-lm, and Ollama
- Hardware detection for chip, machine model, memory, macOS, Python, architecture, and thermal state
- Strict JSON schema validation with raw-trial consistency checks
- Continuous engine RSS and system RAM peak sampling
- Preflight validation for engine, server, and model access
- GitHub Actions validation for submitted results
- GitHub Pages leaderboard with model search and engine/chip/machine/memory filters
- JSON and Markdown result export
-
mlx-chronos submitfor sending validated JSON results to the maintainer inbox - Published Apple M2 sample results refreshed with the current benchmark protocol
- Warnings for battery mode, Low Power Mode, non-nominal thermal state, and unavailable thermal state
- Integration tests against mock OpenAI-compatible servers
- Larger fixed cold-prompt pool with optional p95 reporting for larger runs
- Request-throughput timing metadata and client-observed streaming decode throughput
- Phase timing metadata and lightweight continuous thermal monitoring
- Sustained benchmark profile, cooldown metadata, and max-token leaderboard filter
Next
- Add richer benchmark condition metadata without breaking the v0.1 JSON contract
Future
- Evaluate a clearer TTFT naming model without breaking the v0.1 JSON contract
- Add tool-calling success-rate benchmarks
- Explore anti-spoofing checks for community submissions
- Document external contributor branch workflow when community PRs start arriving
- Collect more results from M3, M4, and M5 systems
License
Apache 2.0 — see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mlx_chronos-0.1.2.tar.gz.
File metadata
- Download URL: mlx_chronos-0.1.2.tar.gz
- Upload date:
- Size: 59.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97bc6e655b9344ba597a4122db220b95caf73bfc489403705790c443227758f0
|
|
| MD5 |
22cf33537386c73cc32391c1cc01a1cb
|
|
| BLAKE2b-256 |
df9a51f650ab1ae54a5fd7f35c21542ae36060abdb6c21802a2aad3306b38f12
|
Provenance
The following attestation bundles were made for mlx_chronos-0.1.2.tar.gz:
Publisher:
release.yml on igurss/mlx-chronos
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mlx_chronos-0.1.2.tar.gz -
Subject digest:
97bc6e655b9344ba597a4122db220b95caf73bfc489403705790c443227758f0 - Sigstore transparency entry: 1733760999
- Sigstore integration time:
-
Permalink:
igurss/mlx-chronos@9a27b0485d52b3cff921eaed4b047874ec390994 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/igurss
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9a27b0485d52b3cff921eaed4b047874ec390994 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mlx_chronos-0.1.2-py3-none-any.whl.
File metadata
- Download URL: mlx_chronos-0.1.2-py3-none-any.whl
- Upload date:
- Size: 46.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76a16f6baf00bbe86f2b9981111510a642aba8cbb44a1bc5f90e5ee60edc5ff6
|
|
| MD5 |
50115efb52df611819ce3e161f03fe5e
|
|
| BLAKE2b-256 |
c71073df186248ff228d0b5f2debf52953ecf79b8ddb9d65e46bff67b365079f
|
Provenance
The following attestation bundles were made for mlx_chronos-0.1.2-py3-none-any.whl:
Publisher:
release.yml on igurss/mlx-chronos
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mlx_chronos-0.1.2-py3-none-any.whl -
Subject digest:
76a16f6baf00bbe86f2b9981111510a642aba8cbb44a1bc5f90e5ee60edc5ff6 - Sigstore transparency entry: 1733761296
- Sigstore integration time:
-
Permalink:
igurss/mlx-chronos@9a27b0485d52b3cff921eaed4b047874ec390994 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/igurss
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9a27b0485d52b3cff921eaed4b047874ec390994 -
Trigger Event:
push
-
Statement type: