timeout: Bound a Command’s Runtime in CI
timeout DURATION CMD runs CMD and sends it a signal if it has not finished in time, exiting 124 when it had to kill the command.
A hung step that runs to the job’s overall timeout wastes runner minutes and gives a vague failure. Wrapping the risky command in timeout fails fast with a clear, distinct exit code.
What it does
timeout starts a command and a timer. If the command finishes first, its own exit code is returned. If the timer fires first, timeout sends SIGTERM (or -s SIG) and exits 124. -k DURATION schedules a follow-up SIGKILL if the command ignores the first signal. Durations take a suffix: s, m, h, d.
Common usage
timeout 30s ./flaky-integration-test
timeout 5m npm test
timeout -k 10s 5m ./server # TERM at 5m, KILL 10s later if still alive
timeout -s KILL 30s ./stubborn # send SIGKILL directlyOptions
| Flag | What it does |
|---|---|
| DURATION | Time limit, e.g. 30s, 5m, 1h (no suffix = seconds) |
| -s <SIG> | Signal to send on timeout (default TERM) |
| -k <DUR> | Send SIGKILL this long after the first signal |
| --preserve-status | Exit with the command’s code, not 124 |
| -v | Print a diagnostic when the timeout fires |
In CI
Exit code 124 specifically means timeout killed the command, distinct from the command’s own failures, so you can tell a hang from a test failure. Use -k because a process that traps and ignores SIGTERM would otherwise survive; the follow-up SIGKILL guarantees it dies.
Common errors in CI
Exit 124 is timeout firing, not a bug in your command. Exit 125 means timeout itself failed to run (bad usage). Exit 126/127 mean the command was not executable or not found. If the command keeps running after the timeout, it ignored SIGTERM; add -k to force SIGKILL, or use -s KILL from the start for processes you know trap TERM.