On November 12, 2026, Outlook, Exchange Online, Teams, and Copilot went down for hundreds of thousands of people, starting with a spike in outage reports around mid-morning on the East Coast and not settling into a stable recovery until the early hours of the next day. Downdetector logged almost 130,000 reports at its peak. Government offices in Los Angeles County, city governments from Malibu to West Hollywood, and businesses across six major metro areas lost email access for most of a workday.
What's interesting about this one isn't that Outlook went down. Outlook goes down sometimes. What's interesting is that Microsoft's own explanation of the cause describes a failure pattern I'd just finished reading about for a distributed systems assignment two weeks earlier: a health check feedback loop that turns a small, survivable problem into a self-inflicted outage. So instead of a "what happened" recap, here is the mechanism hiding inside Microsoft's statement, explained so that you don't need to be an engineer to follow it, and the part that made it worse than it needed to be.
The short version. (1) A few servers started failing their automatic health checks. (2) Their traffic moved to the remaining servers, which became overloaded and failed their checks too, one after another. (3) Restarting everything at once overloaded the servers again as soon as they came back. The fix that works is slower: bring servers back gradually and spread out the retries.
What Microsoft Actually Said
Stripped of the corporate phrasing, Microsoft's incident updates said three things. First, part of its infrastructure started seeing elevated load because a number of servers had become unexpectedly unavailable, which pushed extra load onto whatever was left. Second, the affected servers then started failing their own automated health checks and dropped out of service. Third, the investigation pointed at a specific internal component responsible for processing those health checks in the first place, not the mail-serving code itself.
Read that again slowly, because the order of events matters: servers became unavailable, then the survivors got overloaded, then the health check system itself started failing. That's a feedback loop, not a single point of failure. It's the same shape as a problem I'd normally expect to see in a toy example on a whiteboard, except this one took down Exchange Online for the better part of a day.
The Part Everyone Builds and Nobody Load-Tests
Here's the piece that almost never makes it into a system design course: a health check isn't a passive observer. It's a decision-maker with real consequences, wired directly into the load balancer's routing table. When it says a server is unhealthy, that server stops getting traffic immediately, and every request that would have gone to it gets redistributed to whatever's still marked healthy. That's the entire point of a health check. It's also the exact mechanism that makes a health check system dangerous when it's the thing that's wrong.
Think of a supermarket with eight checkout lanes and a manager who closes any lane whose line looks too long. On a normal day that rule is harmless. But close two lanes, and their shoppers join the other six lines. Now those lines look too long, so the manager closes another lane, and its shoppers make the remaining lines even longer. Within minutes the store has no open lanes, even though no extra shoppers walked in. That is the whole outage in one picture.
That bottom loop is the whole outage. Traffic into Exchange Online didn't spike on November 12. Nobody sent a flood of extra email that morning. What changed was the number of servers sharing the normal, everyday load. It dropped, because the servers responsible for setting up secure connections got overloaded and started failing health checks. Each server that dropped out pushed its share of the work onto the servers that hadn't failed yet, which made them more likely to fail too. You don't need a traffic spike to cause a cascading failure. You just need the pool of healthy servers to shrink faster than the system can compensate.
| Servers still in service | How busy each one is (same total traffic) | What happens |
|---|---|---|
| 8 | 65% | Normal: room to spare |
| 6 | 87% | Busy, plus users retrying their failed requests |
| 5 | 104% | Over capacity: health checks start failing |
| 4 | 130% | Fails faster, and pushes the rest over |
Illustrative numbers, not Microsoft's: the same traffic divided over fewer servers.
Below is that same loop as a small simulation. Each blue dot is a user's request. Watch the bars: when a server goes past 100%, the health check (the dashed line) pulls it out of rotation, and its requests land on the others. You can click any step to jump to it.
Why "Just Restart Everything" Made It Worse
By early afternoon, Microsoft said it was restarting the affected servers and had deployed an alternate health check method, presumably to stop the health check component from flagging servers that were actually fine. On paper, that's the correct move: get the broken signal out of the loop, bring capacity back online, done. In practice, Microsoft's updates describe something that will sound familiar to anyone who has ever brought a crashed service back up during an incident. Servers came back, recovery looked promising for a while, and then some of the same servers went unresponsive again almost as soon as real traffic hit them.
This has a name, and it's a nastier problem than the original overload: the thundering herd. Picture a store reopening its doors after a power cut, with a crowd that has been waiting outside for an hour. Everyone rushes in at the same second, and the store is overwhelmed before the registers have even started up. When you restart a server and immediately route it a full share of production traffic, every client that was queued up, retrying, or waiting on a timeout hits it at once, before it's finished warming up caches, re-establishing database connections, or doing whatever setup work it needs. A server that would have been perfectly healthy under a gradual ramp-up gets flattened by the exact traffic it was brought back to serve. Microsoft's own updates, phrased carefully, described this as seeing "positive results" that weren't sustained, more than once, over the course of the day. That's what a thundering herd on recovery looks like from the outside: get better, get worse, get better, get worse, until the traffic shifting and ramp-up logic finally wins.
In one sentence: recovering from a cascading failure is not the same problem as preventing one, and a fix for the first can actively cause the second. Bringing capacity back online all at once recreates the conditions that caused the outage in the first place, just with a smaller pool of servers and a more impatient set of retrying clients. Good incident response plans for this explicitly: gradual traffic ramp, connection draining, and health checks that want several passes in a row before a server gets its full share of traffic, so a server isn't declared healthy and immediately buried.
The Boring Fixes That Would Have Capped the Blast Radius
None of this is exotic. Every technique that limits how far a cascade spreads is a standard, textbook part of production distributed systems, which is exactly why this outage is worth writing about instead of shrugging off as "cloud stuff breaks sometimes":
- A sanity check on the health checks. Engineers call this a circuit breaker. If a health check component itself starts failing at an anomalous rate, that's a signal to question the health check, not to trust it and start draining servers.
- Retries that wait longer each time, at random moments (exponential backoff with jitter). Every Outlook client that got a connection failure and immediately retried was, in aggregate, generating the thundering herd that hit the recovering servers. Staggered, randomized retry timing spreads that load out instead of concentrating it at the exact moment a server comes back.
- Gradual traffic ramp-up after a restart, sometimes called a canary or slow-start pattern: route 1% of traffic to a recovered server, confirm it holds, then 10%, then 50%, instead of flipping it straight back into the full rotation.
- Spare servers for the day a health check is wrong, not just for peak traffic. The traffic on November 12 wasn't unusual. The failure was entirely about supply, not demand, which is a different capacity problem than the one most load tests are designed to catch.
Every one of these exists specifically because "turn it off and on again" is a genuinely dangerous instinct at scale. It's the right instinct, aimed at the wrong pace.
Where This Actually Lands
As of this writing, Microsoft hasn't published the full post-incident report, and the honest version of this post has to say so: some of what's above is Microsoft's own characterization of the cause, not an independently verified root cause. What's confirmed, across Microsoft's updates and outage tracking from multiple independent sources, is the shape of the failure: a health-check component that stopped reliably telling the truth, a pool of servers that shrank under normal load instead of excess load, and a recovery that fought its own restart logic for the better part of twenty hours before it held.
That's not really a story about Outlook. It's a story about what happens when the system you built to detect failure becomes the failure, and I'd bet a decent fraction of the engineers inside Microsoft reading their own postmortem this week are having the exact same realization.
Srikanth Badavath