Skip to content
shellmap

Time how long a command takes

Measure the wall-clock (and optionally CPU / RSS) time of a single command run, for ad-hoc perf checks or regression testing.

How to time how long a command takes in each shell

Bashunix
time curl -s https://example.com >/dev/null

Bash `time` is a RESERVED WORD (not a command) — it can time pipelines (`time cmd1 | cmd2`) and shell functions. Output goes to stderr as `real`/`user`/`sys`. For detailed stats (max RSS, page faults, voluntary context switches), use `/usr/bin/time -v cmd` — the standalone GNU binary, distinct from the bash builtin. macOS BSD `/usr/bin/time` uses `-l` instead of `-v` (different flag set).

Zshunix
time curl -s https://example.com >/dev/null

Zsh `time` is also a reserved word with the same pipeline-timing capability. Customise the output format with `TIMEFMT="%E real %U user %S sys"` (zsh-specific format spec). Like bash, the standalone `/usr/bin/time -v` gives more detail.

Fishunix
time curl -s https://example.com >/dev/null

Fish `time` is a builtin (fish 3.2+ — earlier versions punt to `/usr/bin/time`). Times the full command including any pipes. Output format `Executed in 234.56 millis fish ...` is fish-specific. For `/usr/bin/time -v` parity, call it explicitly: `command time -v curl ...` (the `command` builtin bypasses the fish builtin).

PowerShellwindows
Measure-Command { Invoke-WebRequest https://example.com }

`Measure-Command` runs the script block and returns a `[TimeSpan]` — but it SUPPRESSES the script block's stdout. If you need both timing AND output, capture: `$out = Measure-Command { $r = Invoke-WebRequest ...; $script:result = $r }; $out; $result`. For high-resolution timing inside scripts: `$sw = [Diagnostics.Stopwatch]::StartNew(); …; $sw.Stop(); $sw.Elapsed`.

cmd.exewindows
powershell -NoProfile -Command "Measure-Command { curl https://example.com }"

No native cmd timer. The classic batch hack: `echo %TIME% & cmd & echo %TIME%` captures HH:MM:SS.MS at start/end (no subtraction built-in — pipe through PowerShell to subtract). Robocopy ships with `/L /MT:1` timing as a side-effect, but that's overspecific. Best path: pwsh shim above, or `where ptime` if a portable PTime tool is installed.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • Bash/zsh `time` is a RESERVED WORD, NOT the `/usr/bin/time` binary. The two have different flag sets and output formats. `time -v cmd` ERRORS with the builtin (unknown option `-v`) but works with the binary. To force the binary: `/usr/bin/time -v cmd` or `command time -v cmd`. The difference matters when you need RSS / page-fault stats that the builtin doesn't emit.
  • `Measure-Command` suppresses the inner script block's output stream — this is the #1 surprise for newcomers. If you wanted both the timing AND the result, you need to capture via a script-scoped variable inside the block. The `[Diagnostics.Stopwatch]` alternative is verbose but doesn't swallow output.
  • Cold-start vs warm: a single `time cmd` measures one run, which includes any cold disk-cache penalty. For meaningful benchmarks, run a warmup pass first, then average ≥3 runs: `for i in 1 2 3; do time curl ...; done 2>&1 | grep real`. For statistically rigorous benches, `hyperfine` (`brew install hyperfine`, `cargo install hyperfine`) auto-warmups and reports mean±stddev with outlier detection.
  • Resolution is limited: bash `time` reports milliseconds (real time = wall clock from `gettimeofday`). For sub-millisecond timing, drop to `perf stat -r 5 cmd` (Linux only, more accurate) or `time -p` (POSIX-formatted seconds with three decimals). PowerShell `[Stopwatch]` claims tick-level resolution (~100ns on Windows) but kernel scheduling jitter usually dominates.

Related commands

Related tasks