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 test

When 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: 10

A step that times out fails the job, unless it also has continue-on-error: true.

What usually hangs

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.

More guides