GitHub Actions timeout-minutes: the 6-hour default and how to set it
A hung job runs for 360 minutes by default. How timeout-minutes works for jobs and steps, how to pick a value, and what usually hangs.
If a job doesn't set timeout-minutes, GitHub Actions lets it run for 360 minutes before killing it. A test that waits forever on a port, or a command waiting for input nobody will type, holds a runner for six hours, and on private repos those are billed minutes. In our scan, 1,329 of 2,181 CI jobs (60.9%) had no timeout.
Set it on every job
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
- run: npm testWhen the limit is hit, the job is cancelled and marked as failed with a clear message, so a hang shows up as a red check in minutes instead of a yellow dot all afternoon.
Picking the number
Look at the job's recent durations in the Actions tab and use roughly 2× the normal run time, rounded up. A job that usually takes 6 minutes gets 15. That leaves room for a slow runner or a cold cache without letting a real hang run for hours. Revisit it when the job grows.
Step-level timeouts
timeout-minutes also works on a single step. Use it for the one step that is known to hang, such as end-to-end tests or waiting for a service, so the rest of the job keeps its normal budget:
- name: E2E tests
run: npx playwright test
timeout-minutes: 10A step that times out fails the job, unless it also has continue-on-error: true.
What usually hangs
- Waiting for a server that crashed on startup (
wait-on, health-check loops) with no timeout of its own. - Interactive prompts:
npxasking to install a package, a CLI asking for confirmation. Usenpx --yesor the tool's non-interactive flag. - Test runners in watch mode, for example a
testscript that passes--watchexplicitly. - Open handles: a database connection or timer that keeps the test process alive after the tests finish.
- Network calls with no timeout to a registry or API that stops responding.
Self-hosted runners
The 360-minute default applies to self-hosted runners too. There a hung job doesn't cost billed minutes, but it blocks a machine that other jobs are queued for, so the timeout matters just as much.