- Shell 93.7%
- Dockerfile 6.3%
- bench.sh → bench.zsh with #!/usr/bin/env zsh - Uses zmodload zsh/datetime EPOCHREALTIME instead of bash time + bc - No more bash wrappers, no bc dependency, no time output parsing - Dockerfile stripped: removed hyperfine, fzf, wget (unused deps) - Removed __zsh_timed helper captures elapsed time in zsh-native math - All globs use (N) null-glob qualifier for err_exit safety - README updated to note the script is written in zsh |
||
|---|---|---|
| results | ||
| bench.zsh | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
| references.md | ||
Zsh Plugin Manager Benchmarks
Reproducible Docker benchmarks for zsh plugin manager startup performance.
This repo accompanies the article Oh My Zsh Alternatives on magnus919.com. The benchmarks measure shell startup time (time zsh -i -c exit) for several plugin managers with a standardized set of plugins, running inside a Docker container on Ubuntu 22.04.
What's Measured
- Cold start: First shell load after clearing
.zcompdumpand cache files. Represents the first shell you open after a reboot. - Warm start: Subsequent loads, averaged over 5 runs. Represents what you see in day-to-day use after the first terminal is opened.
Important caveat:
time zsh -i -c exitmeasures total process runtime, not user-visible latency. For a more accurate picture of perceived performance (first prompt lag, first command lag), see romkatv/zsh-bench.
Plugin Managers Tested
| Manager | Version | Install Method |
|---|---|---|
| Oh My Zsh | latest from HEAD |
Git clone |
| Antidote | latest from HEAD |
Git clone |
| Zinit | latest from HEAD |
Git clone |
| Zim | latest from HEAD |
Git clone |
Sheldon was omitted from the Docker benchmarks because prebuilt binaries aren't available for arm64. If you're on x86_64, uncomment the Sheldon section in bench.sh to include it.
Standard Plugin Set
All managers (except the "minimal OMZ" case) load these plugins:
colored-man-pages,docker-compose,gh,git,rsync,ssh,brew(via OMZ)zsh-users/zsh-autosuggestionszsh-users/zsh-syntax-highlighting
This matches the plugin profile from the original oh-my-zsh alternatives article.
How to Run
Prerequisites: Docker.
# Clone this repo
git clone https://git.brandyapple.com/magnus/zsh-plugin-manager-benchmarks.git
cd zsh-plugin-manager-benchmarks
# Build the Docker image
docker build -t zsh-bench .
# Run the benchmarks
docker run --rm zsh-bench
The benchmark takes ~5 minutes to run (mostly cloning repos and warming caches). Results are printed to stdout.
The benchmark script (bench.zsh) is written in native zsh — no bash wrappers, no bc for math, no time output parsing. It uses zsh/datetime's EPOCHREALTIME sub-second timers and zsh-native arithmetic.
Results (May 2026)
Run on: Docker for Mac (Apple Silicon) — Linux arm64, zsh 5.8.1
| Configuration | Cold Load | Warm Avg (5 runs) |
|---|---|---|
| Bare zsh (baseline) | 0.121s | 0.037s |
| Oh-My-Zsh (stock, 7 plugins) | 0.278s | 0.072s |
| Oh-My-Zsh (minimal, 1 plugin) | — | 0.070s |
| Antidote (9 plugins) | 0.320s | 0.315s |
| Zinit (9 plugins) | 0.307s | 0.300s |
| Zim (2 modules) | 0.109s | 0.028s |
Key Observations
-
OMZ's overhead is the framework, not the plugins: OMZ with 7 plugins (0.072s) barely differs from OMZ with 1 plugin (0.070s). The startup tax comes from
oh-my-zsh.shitself, not what you load on top of it. -
Antidote and Zinit trade off: Both are consistently around 0.3s per load because their static file generation and compinit run on every shell start with this configuration. The tradeoff is they give you far more control over what you load and when.
-
Zim's caching is excellent: After the first run, Zim drops to near-baseline performance (0.008s vs bare 0.017s).
-
These numbers are best-case: Real-world startup times are dominated by NVM,
pyenv init,brew --prefixcalls, and other plugin-side overhead — not by the plugin manager itself. See this analysis for a deep dive.
Methodology
The benchmark runs inside a clean Ubuntu 22.04 Docker container with no pre-existing zsh configuration. Each plugin manager is installed fresh and configured with the standard plugin set. The container runs on the host's kernel, so results are comparable across Docker-supported platforms.
Bare zsh is included as a baseline to measure framework overhead.
License
MIT