You know the ritual. Mid-refactor, you need to know if the new version of your script is actually faster, so you run time npm run build and get 12.4 s. You run it again: 16.1 s. Again: 13.0 s. Which number is the truth?
None of them. A single run of any command is mostly noise — disk caches, CPU frequency scaling, whatever else your laptop happened to be doing that second. One sample is a rumor. You need a distribution.
That's the gap hyperfine fills. It's a command-line benchmarking tool written in Rust that runs your command many times and reports the mean, the standard deviation, and a heads-up when a run looks like an outlier. Version 2.0.0 landed on October 7, 2026, so this isn't a dusty utility — it's a tool mid-redesign, and the redesign is worth knowing about.
The basics
hyperfine 'sleep 0.3' is enough to get going. It picks its own run count: at least 10 runs, and enough of them to total roughly 3 seconds. If you want a fixed number, hyperfine --runs 20 'npm run build'.
The real payoff is comparison. Pass several commands and it benchmarks them back to back:
hyperfine 'hexdump file' 'xxd file'
The first command is the reference; every later result shows its change and factor against it. That's the difference between "I think it's faster" and a number a reviewer can't argue with.
Making the numbers honest
Two flags matter more than the others. Disk-bound commands lie depending on cache temperature, so:
-w 3(warmup) executes the program a few times before timing, for warm caches.-p 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches'(prepare) runs before each measurement, for cold ones.
Also new in 2.0: benchmarked commands run directly, with no intermediate shell, by default. That removes shell startup from the equation — and when you do opt back in with -S for pipes and friends, hyperfine measures the shell's startup time and subtracts it. It is annoyingly thorough, in the best way.
Benchmark one parameter at a time
Threads are the classic case:
hyperfine -P num_threads 1 12 'make -j {num_threads}'
-P scans a numeric range (step size via -D), and -L takes a list of values. A favorite trick from the README: benchmark branches directly.
hyperfine --parameter-list branch main,perf-improvements \
--setup 'git switch {branch}' 'python main.py'
The branch switch happens in --setup, before timing, so you're measuring the code, not the checkout.
Results you can share
--export-markdown results.md produces a table with mean, change, and factor — perfect for a PR description, which forces whoever touches the code next to see the number. --export-json gives per-run detail, and hyperfine ships Python scripts (plot_histogram, plot_whisker) you can run straight from the repo. If you want it in CI, Bencher consumes hyperfine output to catch regressions on every commit.
Speaking of 2.0: the default report is now wall-clock time plus peak memory, and --metrics can swap in CPU cycles, instruction counts, cache misses, or branch misses on Linux. Note that hardware counters require shell-free mode — another reason the no-shell default is the right call.
The tool is named for the hyperfine levels of caesium-133, the atomic transition that defines the second. Which is a lovely way of saying: it exists to make your timing honest. Stop counting on the stopwatch; let it take the measurement.
Happy benchmarking. That's the gap hyperfine fills. It's a command-line benchmarking tool written in Rust that runs your command many times and reports the mean, the standard deviation, and a heads-up when a run looks like an outlier. Version 2.0.0 landed on October 7, 2026, so this isn't a dusty utility — and its new defaults will surprise you if you learned the 1.x way. The tool is named for the hyperfine levels of caesium-133, the atomic transition that defines the second. It's a lovely way of saying the tool exists to make your timing honest. So stop hand-timing — let hyperfine keep time for you.