Skip to content

Bound how long a wedged CI job can run - #71

Merged
smb merged 2 commits into
mainfrom
ci/job-timeouts
Sep 5, 2026
Merged

smb merged 2 commits into
mainfrom
ci/job-timeouts

Conversation

@smb

@smb smb commented Sep 5, 2026 •

Copy link
Copy Markdown
Collaborator

No job in ci.yml declares timeout-minutes, so every one inherits GitHub's
default of 360 minutes. #39 records the UI test job wedging with no output and
no crash — in this configuration that holds a runner for six hours before
anything stops it.

Values are measured against every retained CI run: 151 runs, 946 jobs.

job median max observed limit
lint 0.3 min 9.9 min 20
test (matrix) 0.7 min 2.9 min 20
swscale 2.6 min 6.5 min 25
windows 3.5 min 5.8 min 30

The lint maximum is the interesting one, and not for the reason it first
appears. Its uv sync --locked --all-groups step took 9.6 minutes while every
other job in the same run synced in 0.1 minutes — the cache was warm, and
this was a one-off stall fetching packages. Across all 946 sync steps the median
is 4 seconds and exactly one exceeded two minutes.

A genuinely cold cache does not appear in the retained window at all: the
repository builds daily, so the cache never reaches its eviction age. The limits
therefore allow the slowest run on record plus a ten-minute stall on the
dependency step
— the largest interruption this repository has actually
observed.

Per job rather than one shared number: the spread between lint and Windows is a
factor of twelve.

This does not fix #39 — a hang still costs a rerun. It costs twenty minutes of
runner time instead of six hours, and the failure arrives while the change that
caused it is still in front of someone.

release.yml is left alone on purpose. Its packaging jobs compile a frozen
bundle and build a media stack from source; a limit guessed rather than measured
would abort a real release.

Refs #39

🤖 Generated with Claude Code

smb and others added 2 commits September 5, 2026 22:48
No job in the CI workflow declares timeout-minutes, so each one inherits
GitHub's default of 360 minutes. That default is harmless while jobs finish,
and expensive the moment one does not: issue #39 records the UI test job
wedging with no output and no crash, and a wedged job in this configuration
holds a runner for six hours before anything stops it.

Each job now carries a limit with generous headroom over its observed
duration - lint 18s under 10 minutes, the test matrix 32s to 1m17 under 15,
swscale 2m37 under 20, and Windows 4m16 under 30. The values differ per job
rather than being one shared number, because the spread between them is a
factor of fourteen and a single limit would be either useless for lint or too
tight for Windows.

This does not fix #39. A hang still costs a rerun; it now costs minutes of
runner time instead of a working day, and the failure arrives while the change
that triggered it is still in front of someone.

release.yml is deliberately left alone. Its packaging jobs compile a frozen
bundle and build a media stack from source, and a limit guessed rather than
measured would abort a real release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The first values came from a single run and were too tight. Measured against
every retained CI run instead - 151 runs, 946 jobs - the lint job once took
9.9 minutes against a limit of 10.

That run is worth recording, because it is not what it looks like. Its
dependency step, uv sync --locked --all-groups, took 9.6 minutes while every
other job in the same run synced in 0.1 minutes, so the cache was warm and this
was a one-off stall fetching packages. Across 946 sync steps the median is 4
seconds and exactly one exceeded two minutes. A genuinely cold cache does not
appear in the window at all: the repository builds daily, so the cache never
reaches its eviction age.

The limits now allow the slowest run on record plus a ten-minute stall on the
dependency step, which is the largest interruption this repository has actually
observed: lint 20, the test matrix 20, swscale 25, Windows 30. Windows is
unchanged; its 5.8 minute maximum is test execution rather than setup, and it
had the headroom already.

This still cuts a wedged job from six hours to twenty minutes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@smb
smb merged commit d143c13 into main Sep 5, 2026
17 of 18 checks passed
@smb
smb deleted the ci/job-timeouts branch September 5, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tests/ui occasionally wedges instead of failing, with no output and no crash

1 participant