DevelopmentPlaybook18 min readPublished August 20, 2026

Outage of 7h 47m · cause stated, no component named · retries made recovery harder

GitHub’s Outage Postmortem: Client Retries Made It Worse

GitHub published its retrospective on the August 17 outage on Thursday, August 20. In its own words, a critical infrastructure component in its Central US data center failed to scale when traffic hit a new peak, and a client-side retry loop then raised traffic during recovery, which GitHub had to mitigate before it could safely restore service. The fix list is large: more than 3 million CPU cores, 120 petabytes of storage, an Azure migration GitHub now puts at roughly 58% of platform load, and, first on the list, consistent retry limits and retry budgets. This post reads the postmortem for what it establishes, surfaces where it differs from day-of tracking, and turns GitHub’s own remediation language into a retry-budget standard for the agent fleets, CI bots and webhook consumers that are the next generation of retrying clients.

DA
Digital Applied Team
Senior strategists · Published Aug 20, 2026
PublishedAug 20, 2026
Read time18 min
Sources8
Outage duration
7h 47m
GitHub’s postmortem · Aug 17, 2026
CPU cores added since
3M+
plus 120 PB high-speed storage · GitHub-stated
Platform load on Azure
~58%
up from ~12% in May · dates approximate
~46 pts vs May
Copilot Token Service, peak
70–100k RPS
vs 7–9k normal · GitHub incident summary

GitHub’s August 17 outage postmortem, published on August 20, 2026, does something day-of status updates never can: it names the mechanism. In GitHub’s words, the outage began when traffic reached a new peak and a critical infrastructure component in its Central US data center failed to scale with it. Then, as those services threw errors, a client-side retry loop increased traffic during recovery, and GitHub had to mitigate that behavior before it could safely restore traffic. The outage lasted 7 hours and 47 minutes.

That second sentence is the one worth reading twice. A capacity failure is a vendor problem. A retry loop that makes recovery harder is a client problem, and every team that runs CI bots, webhook consumers, agent fleets or orchestrator retry wrappers against GitHub is a client. GitHub’s first listed remediation uses the phrase “retry budgets” and “retry storms” directly, which means the vocabulary for fixing this is GitHub’s own, not something we are importing.

This post covers what the postmortem establishes and what it deliberately leaves generic, where its figures differ from our own day-of tracking, the scale of the remediation, Copilot as a separate failure domain, and then a retry-budget standard grounded in the AWS Architecture Blog, a second Amazon engineering write-up and Google’s SRE book, with an audit checklist you can run against your own harness this week.

Key takeaways
  1. 01
    GitHub names a capacity failure plus a retry loop.The postmortem says a critical infrastructure component in its Central US data center failed to scale when traffic hit a new peak, and that errors there triggered a client-side retry loop that increased traffic during recovery. GitHub had to mitigate the loop before it could safely restore traffic.
  2. 02
    Retry budgets are GitHub’s words, not ours.The first remediation item reads: consistent retry limits, retry budgets, and variable timeouts across service-to-service interactions to prevent retry storms and cascading load. The standard in this post operationalizes exactly that language for clients.
  3. 03
    The retrospective runs 11 minutes longer than day-of tracking.Our August 17 post recorded 7 hours 36 minutes from a 13:40 UTC open. GitHub’s postmortem states 7 hours and 47 minutes, and its incident summary puts the start at 13:28 UTC. Both are presented here with sources; the difference is a measurement start point, not an error.
  4. 04
    The remediation is measured in millions of cores.GitHub says it has since added more than 3 million CPU cores, 120 petabytes of high-speed storage and significant network capacity, and that Azure now serves roughly 58% of platform load and half of all Git operations, up from 12% of platform load in May.
  5. 05
    Agent fleets are the next retrying client.GitHub does not identify the retrying clients, and nothing in the postmortem points at AI agents. Forward-looking, though, agent fleets, CI bots, webhook consumers and orchestrator retry wrappers are exactly the class of client that retries on 5xx. Full-jitter backoff, per-process budgets, circuit breakers and honouring Retry-After are the fix.

01The postmortemWhat GitHub actually said on August 20.

The post is titled “The August 17 outage, and the work ahead” and it opens without hedging: “On August 17, GitHub experienced an outage that lasted 7 hours and 47 minutes.” The same opening names every affected surface in one sentence: “It disrupted github.com, authentication, GitHub Actions, APIs, pull requests, issues, and Copilot, affecting developers and organizations around the world.” GitHub also frames the event as “our second significant incident in August, following an actions failure on August 6,” a detail we note as context only.

The root-cause paragraph is short and specific about the where, and deliberately generic about the what: “Our investigation found that the outage began when traffic reached a new peak, and a critical infrastructure component in our Central US data center failed to scale with it.” No component is named. The next two sentences are the heart of this post.

“Errors in those services triggered a client-side retry loop that increased traffic during recovery. We had to mitigate that behavior before we could safely restore traffic.”— GitHub, “The August 17 outage, and the work ahead,” August 20, 2026

Three things follow from that wording. First, the retry loop is described as a recovery problem, not the trigger: capacity failed first, retries made the way back harder. Second, GitHub says it had to mitigate the loop before it could safely restore traffic, which means the retry behavior was on the critical path to recovery, not a side effect. Third, GitHub does not say which client was retrying, and it keeps that abstraction throughout the post. We keep it too.

The tone is unusually direct for a company postmortem. “If you were trying to ship software that day, we let you down,” GitHub writes, and the closing line commits to earning trust “through the scaling and reliability of the platform.” Whether that lands depends on the remediation list in section 04, which is where the numbers are.

Established
Root cause
Central US data center · failed to scale at a new traffic peak

A critical infrastructure component failed to scale when traffic reached a new peak. GitHub names the data center and the failure mode, not the component.

github.blog · Aug 20, 2026
Established
Recovery amplifier
client-side retry loop · increased traffic during recovery

Errors in the affected services triggered a client-side retry loop that increased traffic during recovery. GitHub had to mitigate that behavior before it could safely restore traffic.

github.blog · Aug 20, 2026
Established
Copilot as a separate domain
most services recovered earlier · some Copilot services took longer

GitHub confirms that most services recovered earlier in the day while some Copilot services took longer, which is what our day-of tracking showed from the outside.

github.blog · Aug 20, 2026

02MechanismHow a retry loop turns a partial failure into a pile-on.

The mechanism GitHub describes is the textbook cascading-failure shape. A backend starts returning errors because it cannot scale. Clients see the errors and retry. Each retry is a fresh request against a backend that is already at or over capacity, so the error rate rises, so more clients retry, and the load the backend must absorb to recover keeps climbing precisely because it has not recovered. Google’s SRE book calls this out directly: without randomization, “a small perturbation (e.g., a network blip) can cause retry ripples to schedule at the same time, which can then amplify themselves.”

GitHub’s own incident summary, which we read via its Community Discussions mirror of the status-page record, gives one concrete measure of how far that amplification went. The Copilot Token Service normally serves 7,000 to 9,000 requests per second. During the incident it saw 70,000 to 100,000 requests per second. Taking the ends of both ranges, that is between roughly 8 and 14 times normal, which is to say an order of magnitude of extra traffic arriving at a service that was already struggling. We use that figure because it is GitHub’s, it is about a named internal service rather than a named client, and it illustrates amplification without asserting who caused it.

Normal load
Copilot Token Service baseline
7–9k RPS

The request rate GitHub’s incident summary describes as normal for the Copilot Token Service. Source: GitHub’s own incident-thread summary, read via the Community Discussions mirror of the status-page record.

GitHub incident summary
Peak during incident
Copilot Token Service under the retry loop
70–100k RPS

Roughly 8 to 14 times the normal range, computed from the two stated ranges. GitHub reports the service fully recovered by 21:02 UTC, 13 minutes before the incident formally closed at 21:15 UTC.

GitHub incident summary
Peak error rates
Web and API traffic
~20%

Roughly 20% of web and API traffic errored at peak, and roughly 50% of archive and raw-content downloads, both per GitHub’s status-page incident summary. These are the figures our day-of post also reported as vendor-stated.

~50% archive / raw downloads
What the postmortem does not say
GitHub’s August 20 post does not name the component that failed to scale, does not identify which clients were retrying, and does not describe the retry loop in any more detail than the two sentences quoted above. A considerably more detailed mechanism has circulated in secondary coverage since August 18 and 19, often attributed to an earlier GitHub incident report distinct from the company blog. That mechanism is not in GitHub’s own postmortem, so this post does not repeat or evaluate it. Nothing in GitHub’s post points at AI coding agents either. The agentic angle here is forward-looking: the class of client that retries on 5xx now includes agent fleets.

That abstraction matters for the lesson. If the post had named a single client, the temptation would be to file this as that client’s bug. Because it did not, the useful reading is the general one: any client that retries a failing request without a budget is a potential amplifier, and the only defense a platform has against an unbudgeted client is to throttle it, which is what “mitigate that behavior” means in practice. For the client-side half of the story, our API error handling and resilience reference covers the retriable-versus-non-retriable distinction that every retry policy has to start from.

03The deltaDay-of tracking versus the retrospective.

On August 17 we published GitHub Came Back Before Copilot Did, built from the 36 updates on GitHub’s status-page incident record. That post recorded the incident opening at 13:40:03 UTC and resolving at 21:15:46 UTC, for 7 hours 36 minutes, and stated that no root cause had been published. The August 20 postmortem gives a different duration, 7 hours and 47 minutes, and GitHub’s incident summary puts the start at 13:28 UTC with the same 21:15 UTC close. We are presenting both rather than silently overwriting our own published figure, because the difference is itself the story of what a retrospective adds.

Comparison of the figures in Digital Applied’s August 17 day-of post, GitHub’s August 20 postmortem, and GitHub’s incident summary as mirrored in Community Discussions: start time, end time, duration, root cause, retry behavior, Actions recovery and Copilot recovery.
FigureOur Aug 17 post (live tracking)GitHub postmortem (Aug 20)GitHub incident summary (mirror)
Timing
Start (UTC)13:40:03 (status page “Investigating”)Not stated as a timestamp13:28
End (UTC)21:15:46Not stated as a timestamp21:15
Duration7 h 36 m (computed from timestamps)7 h 47 m (stated)7 h 47 m (13:28 to 21:15)
Cause and mechanism
Root causeNone published at time of writingCentral US component failed to scale at a new traffic peakCentral US datacenter named
Retry behaviorMitigation note on partially disabling auth token retriesClient-side retry loop increased traffic during recoveryCopilot Token Service 7–9k RPS normal, 70–100k RPS peak
Component recovery
Actions recoveryMitigated at 16:59 UTC, stayed clearNot stated as a timestampDegradation resolved ~18:03 UTC
Copilot recoveryCleared only at incident resolution, 21:15 UTC“Some Copilot services took longer” than most servicesToken Service fully recovered by 21:02 UTC

The two start times are 12 minutes apart and the two durations are 11 minutes apart. The most likely reading, and it is our inference rather than anything either source states, is that the two figures measure from different start points: the moment the status page was first marked as investigating versus the moment GitHub’s own telemetry says traffic crossed the new peak. We are not going further than that. Both sources that give an end timestamp agree on 21:15 UTC. One further delta sits in the table: our day-of post recorded Actions mitigated at 16:59 UTC and staying clear, while GitHub’s incident summary puts an Actions degradation resolving around 18:03 UTC. We present both with their sources, as with the duration.

The larger lesson is about what each kind of source is for. A live-tracked timeline tells you when the vendor knew and what it said; a retrospective tells you what actually happened and when it started. Both are legitimate, and an incident review on your side should keep both columns rather than backfilling the retrospective number over the day-of one. The agentic workflow incident-response playbook has a runbook template that keeps those columns separate by design.

04RemediationThree million cores, 120 petabytes, and roughly 58% of platform load on Azure.

The remediation section is where the postmortem stops being a narrative and becomes a capacity plan. One sentence carries the headline figures: “We have since added more than 3 million CPU cores, 120 petabytes of high-speed storage, and significant network capacity.” Those are two clauses of a single sentence, not separate initiatives, and GitHub gives no breakdown of where the cores went.

The second figure is the Azure migration, and it is stated as two metrics in one breath: “Today, Azure serves roughly 58% of GitHub’s platform load and half of all Git operations, up from 12% of platform load in May.” GitHub gives no date within May for the 12% baseline and no date for “today” beyond the August 20 publish date, so both ends should be read as approximate. Taken at face value, that is a move of roughly 46 percentage points of platform load across a May-to-August window. GitHub does not break that shift down by month and does not say the migration changed pace, so nothing in the pair of figures isolates anything that happened after August 17. The signal is the size of the move, not its timing.

Share of GitHub served from Azure · May vs August 2026

Source: GitHub, “The August 17 outage, and the work ahead,” Aug 20, 2026. Dates approximate as stated by GitHub.
Platform load on Azure, May 2026GitHub-stated baseline · no date within May given
~12%
Platform load on Azure, “today”As of the Aug 20 post · no more precise date given
~58%
Git operations on Azure, “today”Second metric in the same sentence · “half of all Git operations”
~50%

Then come the engineering changes, and the order matters. First: “we are applying consistent retry limits, retry budgets, and variable timeouts across service-to-service interactions to prevent retry storms and cascading load.” Second: “we are reviewing lower-priority CPU and memory alerts to identify components that could fail during sudden traffic spikes.” The post also describes architecture work toward “unlimited read operations,” rolling out gradually beginning with the largest monorepos, which is framed as ongoing rather than complete.

Note the scope of that first item. GitHub is applying retry budgets to its own service-to-service calls, which is the internal half of the problem. The external half, the clients that retry against GitHub, is the half only clients can fix, and it is the half the rest of this post is about.

Reading the remediation honestly
Three million cores and 120 petabytes answer the capacity failure. They do not answer the retry loop, because no amount of backend capacity stops a client from sending ten requests where one would do. GitHub’s own first remediation item is the retry-budget work, and it comes before the hardware in the list. That ordering is the clearest statement in the post about what GitHub thinks the controllable lesson is.

05Failure domainsCopilot recovered on its own clock, and GitHub now says so.

Our day-of post argued, from the outside, that the AI assistant in a developer loop sits on a different dependency chain from git hosting and recovers on a different clock. The postmortem confirms it from the inside in one sentence: “Most GitHub services recovered earlier that day, but some Copilot services took longer.” GitHub’s incident summary adds the detail that the Copilot Token Service, the service whose request rate spiked by an order of magnitude, was fully recovered by 21:02 UTC, 13 minutes before the incident closed at 21:15 UTC, while the status-page record had shown the Central US data center recovering by 16:36 UTC. We are not re-telling the outage day here; the timeline, the 16:59 UTC mitigation list and the relapses are all in the August 17 post. What the two GitHub sources add together is that the service which took longest to recover was also the one whose request rate spiked by an order of magnitude. GitHub does not connect those two facts explicitly, and neither do we beyond noting them side by side.

06The standardA retry-budget standard, grounded in primary engineering references.

“Retry budget” has a precise meaning, and it predates this outage by a decade. Google’s SRE book describes two distinct budgets. In the cascading-failures chapter it is process-wide: “Consider having a server-wide retry budget. For example, only allow 60 retries per minute in a process, and if the retry budget is exceeded, don’t retry; just fail the request.” In the overload chapter it is a per-client ratio: “Each client keeps track of the ratio of requests that correspond to retries. A request will only be retried as long as this ratio is below 10%.” The payoff of the ratio budget is stated directly: “layering on the per-client retry budget (a 10% retry ratio) reduces the growth to just 1.1x in the general case.”

Backoff shape comes from the AWS Architecture Blog’s “Exponential Backoff and Jitter”, Marc Brooker’s 2015 post that is still the canonical reference for the technique. It compares three jitter formulas and finds that Full Jitter did the least total client work of the three, because in a simulation of 100 contending clients plain exponential backoff without jitter produced synchronized retry spikes, and jitter spread those out to an approximately constant rate with less total client work. The post does not prescribe a cap or a maximum attempt count; those come from the SRE references. A separate Amazon write-up, “Timeouts, retries, and backoff with jitter”, supplies the rule for where retries belong: in a five-deep stack of service calls with three retries at each layer, it says the load on the database at the bottom increases 243 times, “making it unlikely to ever recover,” which is why Amazon states that “for low-cost control-plane and data-plane operations, our best practice is to retry at a single point in the stack.” The table below combines those four references with what GitHub’s own postmortem and REST API documentation say.

Retry-budget standard: for each mechanism, what GitHub’s August 20 postmortem or REST API documentation says, what the AWS Architecture Blog, Amazon’s timeouts-and-retries write-up and Google’s SRE book add, and which class of client it applies to.
MechanismWhat GitHub saysWhat AWS / Google SRE addApplies to
Shape and limits of a single client’s retries
Backoff shape“Variable timeouts” across service-to-service interactions (postmortem, first remediation item)Full Jitter: sleep = random_between(0, min(cap, base × 2^attempt)) (AWS); “Always use randomized exponential backoff” (SRE)Every client, every layer
Per-request cap“Consistent retry limits” (postmortem)Up to three attempts per request, then let the failure bubble up to the caller (SRE, overload chapter)Every call site
Process-wide budget“Retry budgets” (postmortem)Illustrative 60 retries per minute per process; past the budget, fail the request instead (SRE, cascading failures)CI runners, workers, agent processes
Per-client ratio budget“Retry budgets” (postmortem)Retry only while retries are below 10% of requests; caps growth at roughly 1.1× in the general case (SRE, overload)Long-running clients and fleets
Interaction with the platform and with other layers
Multi-layer amplification check“Prevent retry storms and cascading load” (postmortem)A request at the top layer can produce as many attempts as the product of the attempts at each layer; retry at one layer only (SRE, cascading failures); Amazon’s worked example is 243× the load at the bottom of a five-deep stackOrchestrators that wrap sub-agents
Retry-After and rate-limit headersWait the retry-after seconds; if x-ratelimit-remaining is 0, wait for x-ratelimit-reset; otherwise wait at least a minute (REST API docs)Server-supplied waits outrank any client schedule; they are the platform’s own throttling signalAnything calling the GitHub API
Circuit breaker and load shedding“Mitigate that behavior before we could safely restore traffic” is the platform-side breaker (postmortem)Adaptive throttling: self-throttle once requests reach K × accepts, K = 2 preferred; shed by criticality tier (SRE, overload)Fleet-level controllers

The three jitter formulas are short enough to show in full, and they are the part teams most often get wrong by implementing plain exponential backoff and calling it done.

Least client work
Full Jitter
sleep = random_between(0, min(cap, base * 2 ** attempt))

The AWS post’s own algorithm, and the one that did the least total client work in its 100-client simulation. Spreads synchronized retries across the whole backoff window.

AWS Architecture Blog, 2015
Alternative
Equal Jitter
sleep = temp/2 + random_between(0, temp/2), temp = min(cap, base * 2 ** attempt)

Keeps a guaranteed minimum wait of half the window and randomizes the other half. Useful when a floor on the wait is required, at the cost of more total client work than Full Jitter in the post’s simulation.

AWS Architecture Blog, 2015
Alternative
Decorrelated Jitter
sleep = min(cap, random_between(base, sleep * 3))

Derives each wait from the previous one rather than from the attempt count. In the post’s 100-client simulation it needed slightly more total client work than Full Jitter but slightly less time; the post calls the choice between the two “less clear”.

AWS Architecture Blog, 2015

None of this is new, and that is the point. The references are a 2015 blog post, a continuously maintained book and Amazon’s own write-up on timeouts, retries and backoff. GitHub’s postmortem is a reminder that a platform at record scale still had to add consistent retry limits and retry budgets to its own internal calls in August 2026, which makes it unlikely your harness has them either. Our API rate-limiting reference covers the server side of the same contract.

07Forward-lookingAgent fleets are the next retrying client.

To be precise about what follows: GitHub does not identify the clients behind the August 17 retry loop, and nothing in its post suggests AI coding agents were involved. This section is about what comes next, not what happened. The class of client that retries on a 5xx has grown. A year ago it was CI runners, webhook consumers and a handful of integrations. Today it also includes agent fleets that clone, push, open pull requests and poll Actions on their own schedule, orchestrators that wrap those agents in their own retry logic, and tool-calling loops that treat a failed API call as something to try again immediately.

That last layer is where multi-layer amplification lives. Google’s SRE book warns that when retries happen at multiple levels, “a single request at the highest layer may produce a number of attempts as large as the product of the number of attempts at each layer.” An orchestrator that retries a task three times, wrapping a sub-agent that retries its tool call three times, wrapping an HTTP client that retries three times, is multiplicative by construction. The fix is structural: retry at one layer, and make every other layer fail fast and report.

GitHub’s REST API documentation already tells clients how to behave when the platform pushes back. Authenticated requests get 5,000 per hour, unauthenticated 60 per hour, and a GitHub Actions GITHUB_TOKEN gets 1,000 per hour per repository; secondary limits cap concurrency at 100 requests and content-generating requests at 80 per minute. On a 403 or 429, the documented behavior is to wait the number of seconds in the retry-after header if present, to wait until the x-ratelimit-reset timestamp if x-ratelimit-remaining is zero, to wait at least one minute when neither applies, and to use exponential backoff for continued failures. The docs also warn that continuing to make requests while rate-limited can result in the integration being banned. Read the rate-limits page as a contract your fleet has already agreed to. GitHub’s companion best-practices page adds two more rules: wait at least one second between each request when making a large number of POST, PATCH, PUT or DELETE calls, and, when a request keeps failing against a secondary limit, back off exponentially and “throw an error after a specific number of retries” rather than retrying indefinitely.

CI bots and runners
Scheduled, bursty, many in parallel

Dozens of runners hitting the same endpoints at the same minute is the synchronized-retry case the AWS post simulates. Full Jitter on every retry, a hard cap of three attempts per request, and a per-process budget so a red build fails visibly instead of hammering the API.

Full Jitter + per-request cap + process budget
Webhook consumers
Inbound events that you acknowledge

The risk is on the write path: a retried handler that re-runs a side effect. Idempotency keys on every write, acknowledge fast, process asynchronously, and never retry the upstream call from inside the handler. See our webhook reliability reference.

Idempotency keys + async processing
Agent fleets
Long-running, autonomous, tool-calling

An agent loop that treats a 5xx as a reason to call again is an unbudgeted client by default. The per-client 10% retry ratio from the SRE overload chapter is the right primitive here: it scales with the agent’s own traffic, and it caps growth at roughly 1.1× rather than letting a partial outage become a pile-on.

Per-client ratio budget + Retry-After
Orchestrator retry wrappers
Retries that wrap other retries

The multiplicative case. Decide which single layer owns retries, make the other layers fail fast, and put a circuit breaker at the orchestrator so that once a dependency is clearly down the whole fleet stops calling it rather than each agent deciding independently.

One retry layer + circuit breaker

Looking forward, the asymmetry is the thing to plan for. A platform can add three million CPU cores; it cannot make an unbudgeted client behave. Agent fleets, CI bots, webhook consumers and orchestrator retry wrappers all retry without a person watching the counter, and every one of them needs the discipline GitHub is now applying to its own services. The teams that treat retry budgets as part of the harness, rather than as something the HTTP library probably handles, are the ones whose fleets will still be making progress during the next partial outage instead of being throttled out of it. If that harness work is on your roadmap, our AI transformation engagements start from exactly this kind of reliability audit.

08AuditSeven questions to run against your own harness.

Six of the seven questions below map to a row of the standard in section 06. The seventh, on idempotent writes, has no row there, because it guards the write path rather than the retry rate. Run them against CI bots, webhook consumers and orchestrator retry wrappers specifically, because those are the clients most likely to have inherited a default retry policy nobody has read. A “no” on any row is a retry-amplification risk, and the fix column names the reference the fix comes from.

Retry-budget audit checklist for agent harnesses: seven questions, what a failing harness looks like, and the fix with its source reference.
QuestionWhat a failing harness looks likeThe fix and where it comes from
1. Does each process track a retry ratio, or only per-call backoff?Every call site backs off correctly on its own; nothing notices what share of the process’s traffic is now retries.Per-client ratio budget, retry only below 10% (SRE, overload chapter), plus a process-wide cap such as 60 retries per minute (SRE, cascading failures).
2. Is there a hard cap on attempts per logical request?A retry-until-success loop, or a cap that resets when the task is re-queued.Up to three attempts, then bubble the failure up to the caller (SRE, overload chapter).
3. Does the client honour Retry-After and x-ratelimit-reset?Retries on a fixed schedule regardless of what the 403 or 429 response says.Wait the retry-after seconds, or until x-ratelimit-reset when remaining is zero (GitHub REST API docs).
4. Is backoff jittered, or fixed-interval?Sleep 1 s, 2 s, 4 s, 8 s with no randomization, so every runner retries in the same second.Full Jitter: random_between(0, min(cap, base × 2^attempt)) (AWS Architecture Blog).
5. Do retries stack across layers?The orchestrator retries a task whose sub-agent already retried the call whose HTTP client already retried.Retry at one layer only; attempts multiply across layers (SRE, cascading failures).
6. Is there a circuit breaker for a dependency that is clearly down?Each agent decides independently; the fleet as a whole keeps calling a service that has been failing for ten minutes.Adaptive throttling at K × accepts with K = 2, plus a fleet-level breaker (SRE, overload chapter).
7. Are retried writes idempotent?A retried request opens a second pull request, posts a duplicate comment, or re-triggers a workflow.Idempotency keys on every write so a retry cannot double-execute a side effect (see our webhook reference).

For the full surface, our 70-point agentic workflow resilience audit folds these seven into a broader review, and the webhook reliability and idempotency reference goes deep on question seven. If you would rather have the audit run for you, it is a standard part of our web development engagements for teams shipping agent-driven pipelines.

09ConclusionThe controllable half of a platform outage.

What the postmortem settles

Capacity is the vendor’s problem. Retry budgets are yours.

GitHub’s August 20 postmortem settles the questions our day-of post could not. The outage began when a critical infrastructure component in the Central US data center failed to scale at a new traffic peak; a client-side retry loop then increased traffic during recovery and had to be mitigated before service could be safely restored; the whole event ran 7 hours and 47 minutes by GitHub’s count, 11 minutes longer than the 7 hours 36 minutes we tracked live from a later start point. The remediation is more than 3 million CPU cores, 120 petabytes of storage, an Azure migration that GitHub puts at roughly 58% of platform load and half of all Git operations, and, first on the list, consistent retry limits and retry budgets.

What GitHub does not say is as instructive as what it does. It names no component and no client, and a more detailed mechanism circulating in secondary coverage is not in GitHub’s own account, so it is not in ours. The generic framing is the useful one: any client without a retry budget is a potential amplifier, and platforms defend themselves against unbudgeted clients by throttling them.

The forward-looking point is that the population of retrying clients is changing. Agent fleets, CI bots, webhook consumers and orchestrator retry wrappers are exactly the class of client that retries on 5xx, usually with no person watching the retry counter. Full-jitter backoff, a per-request cap, a per-process or per-client budget, a single retry layer, a circuit breaker, honoured Retry-After headers and idempotent writes are a decade-old standard. GitHub is now applying it to its own services. The next partial outage will sort fleets that did the same from fleets that got throttled.

Harden your agent harness

A retry without a budget is a request to be throttled.

Our team audits and hardens the retry, rate-limit and idempotency behavior of agent fleets, CI pipelines and webhook consumers, so your automation keeps making progress during the next partial outage instead of amplifying it.

Free consultationExpert guidanceTailored solutions
What we work on

Reliability engagements for agentic pipelines

  • Retry-budget audit against the seven-question checklist
  • Full-jitter backoff, caps and circuit breakers in your harness
  • Retry-After and rate-limit header compliance for GitHub API clients
  • Idempotency keys and safe retries on every write path
  • Incident runbooks that keep day-of and retrospective figures separate
FAQ · GitHub outage postmortem

The questions engineering teams are asking this week.

In GitHub’s own words, the outage began when traffic reached a new peak and a critical infrastructure component in its Central US data center failed to scale with it. Errors in those services then triggered a client-side retry loop that increased traffic during recovery, and GitHub says it had to mitigate that behavior before it could safely restore traffic. The post states the outage lasted 7 hours and 47 minutes and disrupted github.com, authentication, GitHub Actions, APIs, pull requests, issues and Copilot. GitHub does not name the component that failed to scale and does not identify the retrying clients; its account stays at that level of abstraction throughout, and this post does the same.
Related dispatches

Continue exploring reliability engineering.