Yes. Set an explicit timeout on every job, close to its normal run time. Platform limits are generous: GitHub allows 6 hours per job on GitHub-hosted runners, and GitLab's default job timeout is 60 minutes. A tight timeout stops a hung, looping or hijacked job from holding a runner and its credentials for hours.
Documented limits
| Platform | Limit | Source value |
|---|---|---|
| GitHub, hosted runner | Job execution time | 6 hours |
| GitHub, self-hosted runner | Job execution time | 5 days |
| GitHub | Workflow run, including waiting and approval | 35 days |
| GitLab | Default job timeout | 60 minutes, minimum 10 minutes, less than one month |
GitLab adds that if a runner timeout is also set, the lower value wins, and jobs with no output for one hour are dropped regardless of the timeout. GitHub documents a timeout-minutes setting in workflow syntax for jobs and steps.
Why this is a security setting, not just a cost setting
- Credential exposure window. A job that hangs after reading a deploy token keeps that token in memory and environment until it stops.
- Resource abuse. Anyone who can get a job to run, through a pull request or a compromised dependency, can use the runner for other work for as long as the limit allows. Self-hosted limits of days make that worse.
- Detection. A job that suddenly runs ten times longer than usual is a signal. A tight timeout turns that signal into a failed build somebody looks at.
I am not claiming timeouts stop an attacker. They shrink the time and the cost an attacker gets from a job.
How to pick a number
- Look at the last 20 successful runs of the job.
- Take the slowest and add a margin, for example 50 percent.
- Set the timeout at the job level, and set tighter ones on steps that call the network.
- Revisit when the job legitimately grows.
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- run: make test
Related controls
Pair timeouts with concurrency settings so superseded runs are cancelled, and with ephemeral runners so a stuck job leaves nothing behind. GitHub notes that concurrency groups allow at most one running job or workflow per group, and cancel-in-progress can stop older runs.
Quick check
Is a short timeout risky for flaky jobs?
It can fail a slow but healthy run. Set it from real run times with a margin, and fix the flakiness instead of raising the limit.
Do timeouts apply to self-hosted runners?
Yes, you can set them in the workflow. The platform maximum for GitHub self-hosted jobs is 5 days, so set your own.
Safeguard policies and gates can fail a pull request on findings before long-running jobs even start. Try the free scan.
Sources
Last reviewed: 19 October 2026.