Skip to content

Documentation · Observability

Cancelling a job

The Cancel job button on a job's page, and cancelling a whole run on github.com: what each stops, what is billed, and what GitHub shows afterwards.

There are two places to stop a build. The job page here stops one job, and cancels the workflow run around it only when it has to, as below; github.com always stops the whole workflow run.

A job that is queued or running has a Cancel job button, shown to the organisation's owners and admins. It asks you to confirm first, because the click cannot be undone. Then:

  • A queued job is cancelled at once. Nothing of it ever ran, so nothing is billed.

  • A running job is stopped by tearing down its machine. The note beside the button says Stopping, with the time by which the machine has to be gone. While that happens the job's status still reads Running; it reads Cancelled once the machine is gone. The time it ran is billed, unless it falls within your free allowance. Whether it is billed is decided by whether a runner had picked the job up, and the page tells you which when you press the button rather than leaving you to find it on the invoice.

What happens on GitHub depends on whether a runner had picked the job up, and on what else is still going in its workflow run:

  • A runner had it, no other job in its run is still going, and none finished in the last 30 seconds. We ask GitHub to cancel the whole workflow run first, and only then tear the machine down. GitHub shows the job, and the run, as cancelled: a grey check, not a red one. Nothing else in the run is affected, because nothing else in it was still going. Because GitHub has to accept the cancel before the machine goes, this stop takes a couple of seconds longer to answer than the others. The note beside the button says which outcome you got.

  • A runner had it, and other jobs in its run are still going. We stop only this job and leave the others running. We tear the machine down, GitHub sees the job's runner go away, and ends that job on its side within seconds as failed. That is a red check on the commit or pull request, even though you cancelled it. GitHub cannot cancel a single job, and cancelling the run would cancel your other jobs with it, so we take the red check instead. Anything that depends on the stopped job behaves as it would after any failed job.

  • A runner had it, and another job in its run finished in the last 30 seconds. No other job is still going, but GitHub creates the jobs that wait on a job only after it finishes, so one may be about to start, and cancelling the run then could take it before it starts. So we do not cancel the run: we stop only this job, and GitHub marks it failed, a red check, as in the case above. The note beside the button says this is why.

  • No runner had it yet. GitHub's copy is still waiting for a machine, and nothing we do to our side ends it. Left there, it would be handed the next runner we start for the repository and run the build you stopped. So we ask GitHub to cancel the whole workflow run, within seconds of your click.

The button says all of this before you confirm, and the note afterwards says which one happened.

If GitHub is still showing the job as running about 90 seconds after your click — the machine was slow to go, or the job ended up on a runner we were not tearing down — we cancel the whole workflow run.

GitHub cancels runs, not jobs. Whenever we cancel the run for a job that was not the last one going, any other job of that run still going is cancelled with it; the button says so before you confirm.

Cancelling needs the actions: write permission on our GitHub App.

  • A job a runner had, with nothing else in its run going. If your account has not accepted that permission, or GitHub does not give us an answer within a few seconds of your click, we stop only the job, and GitHub marks it failed. Your stop never fails because of GitHub; at most it waits a few seconds for GitHub's answer before going ahead without it.

  • A job no runner had yet. A failed or unanswered request to GitHub is retried in the background, with a growing wait between tries (15 seconds, then 30, then a minute and so on, up to six tries). Only two refusals are not retried, because nothing on our side can change them: your account has not accepted the actions: write permission, or GitHub has suspended the installation. In those two cases GitHub's copy stays where it is until you cancel the run on github.com.

This is the way you stop any Actions run. We react to it: each of our jobs in it reaches cancelling while its machine is torn down, then cancelled. GitHub cancels runs, not jobs, so stopping a run stops every job in it, including the ones of ours that are part way through. That is GitHub's unit of cancellation and not something we can narrow from our side; the button above is the way to stop one job and leave the rest, once a runner has picked that job up.