# GitHub Actions Outage: How GitHub Restored Service After 9 Hours

> A deep dive into the GitHub Actions outage that lasted 9 hours, affecting Copilot, Pages, and more - and how GitHub resolved it.
> By Dave · 2026-08-07
> Source: https://otf-kit.dev/blog/github-actions-outage-resolution

On August 6, 2026, at 15:22 UTC, GitHub reported degraded performance in Actions. Twenty minutes later, the platform was failing: workflow runs not starting, REST API calls returning errors, developers slammed with unexpected rate limiting. The incident lasted roughly nine hours and cascaded into Copilot's code review, GitHub Pages, and webhook delivery. Root cause, per GitHub: invalid job assignments in the scheduling layer.

Most teams' CI/CD strategy was built around an assumption this outage quietly broke.

## GitHub Actions is genuinely good — and that's why this hurts

GitHub Actions isn't a fashionable CI system. It's the connective tissue of a working GitHub workflow. Pull request checks, branch protection gates, OIDC tokens for cloud deploys, secret rotation, matrix builds across OS and runtime — every part of that pipeline lives behind the same scheduling layer. When that layer works, the integration story is unmatched: your CI knows your code, your reviewers, your protected branches, and your deploy targets without you wiring it together.

That's the real product. It's not the runner — it's the scheduling and orchestration that ties a code change to a deployed artifact. The August 6 outage wasn't a runner problem. It was a scheduler problem, and the scheduler is something you can't replace.

## The nine-hour cascade

The timeline moved fast. At 15:22 UTC on August 6, GitHub flagged degraded performance. By roughly 15:42, the failure was concrete: workflow runs failing to start, REST API calls erroring, unexpected rate limiting on accounts that hadn't been hitting limits. The blast radius wasn't contained to Actions. Copilot's code review and coding agent degraded alongside CI/CD, GitHub Pages went down, and webhook delivery backed up across the platform.

GitHub's mitigation statement was thin: "engineers have applied a number of mitigations and are rolling out a further fix." Hours into the disruption. The Register reported that Enterprise Importer migration jobs were still suspended after the main fix was deployed — so even after the scheduler recovered, pieces of the system stayed broken.

## The self-hosted runner assumption

The most damaging misconception in this space: that self-hosted runners insulate you from platform outages. They don't.

Self-hosted runners do not pull jobs autonomously. They register with GitHub, then wait for GitHub's scheduling service to assign them work. When the scheduling layer breaks, your runners — wherever they physically sit — register the same errors and hit the same rate limiting as hosted ones. They sit idle.

Hacker News developers confirmed it within an hour of the outage starting: "Even self hosted workers don't work during these outages." The August 6 incident bore this out precisely. Your runner at home, your runner on AWS, your runner behind the firewall — none of them are a failover for GitHub's scheduler, because the scheduler is upstream of every job assignment.



![self-hosted runner registers with GitHub scheduler; GitHub scheduler assigns jobs; runner ](https://cdn.otf-kit.dev/blog/github-actions-outage-resolution/inline-1.png)



The escape hatch doesn't exist. Not because GitHub designed it badly, but because the integration that makes Actions valuable is exactly what makes it impossible to bypass.

## This isn't bad luck

A nine-hour outage is bad. The volume of incidents around it is worse.

GitHub logged 26 incidents in July 2026. Before that: 23 in June, 23 in May. February 2026 hit 37 incidents in a single calendar month — roughly 1.3 per day. IncidentHub's tracking shows the platform averaged just six consecutive incident-free days at its best in April 2026 — the same month it hit approximately 86% monthly uptime.



![monthly incidents across 2026 with a February spike and sustained elevation through summer](https://cdn.otf-kit.dev/blog/github-actions-outage-resolution/inline-2.png)



That's not a string of unlucky days. That's a reliability profile. If your CI/CD strategy assumes GitHub Actions is available, your strategy needs to acknowledge the new floor. Plan for roughly 14% of the month to involve some form of degraded service. That's the planning horizon.

## How to make this hurt less

You can't fix GitHub's scheduler. You can build around it. Five concrete moves, ordered by effort:

**1. Watch the status API yourself.** Don't wait for GitHub's email. Pull the feed into your own alerting:

```bash
curl -s  \
  | jq '.incidents[] | {name, impact, started_at}'
```

**2. Run critical workflows locally with `act`.** It's not a full replacement, but it keeps you unblocked when scheduling is degraded:

```bash
brew install act
act -j build                       # run the build job from .github/workflows/ci.yml
act --secret GITHUB_TOKEN=$(gh auth token)
```

**3. Maintain a thin fallback CI for deploys.** You don't need to mirror every workflow — just the path from green commit to running artifact. A second provider (Buildkite, CircleCI, GitLab CI) for the deploy workflow is cheap insurance against a 9-hour block.

**4. Decouple deploy from CI.** Workflows that can be re-triggered by hand from a laptop survive a CI outage. Workflows that only run from `on: push` to main don't. Design your release process so the failure mode of "CI is down" doesn't equal "we can't ship."

**5. Cache aggressively and pin what you cache.** Most partial outages don't take caches down. A warm dependency cache gets you most of the way through a 30-minute degradation.

None of this is novel. All of it becomes necessary when you assume one CI provider will eventually be down for hours in any given month.

## The part that doesn't depend on the scheduler

There's a clean line between the parts of your stack that are vendor-replaceable and the parts that aren't. CI is vendor-replaceable. Your code is not. Your UI components are not. The behavior your users actually touch — the button, the form, the page that has to work the same on iOS and Android and web — is load-bearing in a way the pipeline isn't.

The pipeline is interchangeable. The product isn't. Most teams get this backwards — they spend more time hardening the CI than hardening the components that ship to users. The August 6 outage is a useful reminder to invert the priority.

The cross-platform UI layer is exactly the kind of thing that should be stable across vendor churn. Whether your build runs on GitHub Actions, Buildkite, or a developer pressing Enter in a terminal, the rendered component shouldn't care. The behavior your users see on web, iOS, and Android should be identical — and that identity doesn't depend on who scheduled the build.

That's the durable layer. Use the platforms. Own the parts that don't move when the platforms do.

The nine-hour outage wasn't a surprise to anyone tracking incident counts. What it did was make the cost of assuming otherwise visible. Self-hosted runners don't bypass GitHub's scheduler. Multi-vendor CI blunts the impact but doesn't eliminate it. The real resilience isn't in the pipeline — it's in treating the pipeline as replaceable and the product as load-bearing.

Build with Actions. Subscribe to the status feed. Keep a fallback runner warm. And own the parts of your stack that should outlive any one vendor's bad Tuesday.