cube00
5 hours ago
> Errors in those services triggered a client-side retry loop that increased traffic during recovery
Symptomic of a wider trend to avoid showing the user any error at all costs, even if that means they sit watching a spinner for 7 hours.
> Delayed replies to a single internal endpoint triggered a latent retry bug in VS Code that amplified traffic by approximately 10x and caused delayed recovery for the Copilot Token Service.
The detailed root analysis tries to pass this off as a "bug". You can't seriously tell me client retry doesn't have a unit test which ensures the retry back off behaviour is functioning exactly as designed. In this case aggressively to try and hide problems if token service responses become flakey.
ACCount37
4 hours ago
"You can't seriously tell me that the unhappy leg of the code path has no test coverage."
Sometimes I forget how ignorant HN can be of real world software development and the bar of corporate code quality, and then bangers like this remind me of it.
8cvor6j844qw_d6
3 hours ago
"You can't seriously tell me that the unhappy leg of the code path has no test coverage."
Cloudflare outage on December 5, 2025 [1]:
> However, we have never before applied a killswitch to a rule with an action of “execute”.
bbarn
4 hours ago
Exactly this. I've seen production level trading systems grind to a halt over a simple bug and no matter what tests you have in place, it happens.
lbrandy
3 hours ago
I cannot even begin to express how many times I've seen engineers working super hard to optimize happy-paths so that we turn 3 nines of availability into 4 nines but introduce unintended emergent behaviors in unhappy-paths that turn 1 nine into zero nines via thundering herds, retry storms, etc.
Breakthrough
2 hours ago
You have my empathy for this kind of sentiment. Personally this seems somewhat rare in practice. That being said I'm curious if anyone has anecdotes they can share about these kinds of things?
aprdm
an hour ago
Configuring postgres to automatically failover instead of doing it manually. The automated system caused more downtime in a few months than manually doing it did for years before. All in the name of more automations and less downtime
eudamoniac
36 minutes ago
Could you elaborate on why that would cause more downtime?
unscaled
8 minutes ago
I think the "happy path" might be a slightly wrong classification in GP, since the post is in reply to a retry-storm issue and explicitly talks about retry storms and thundering herds.
I've seen many cases where engineers optimize the sad path, but pessimize the wretched path. Or in less flowery language, they cut the occurrence rate of common non-critical failures, but by doing that they introduce code that can make rare failures much worse.
The cases I've seen generally boil down to naive retry logic or poorly tested and poorly maintained fallback paths (such as killswitches that break their environment[1], graceful degradation turned graceless, dormant feature flags that get reactivated).
The case you see with a retry storm here is the most classic one and the one that annoys me the most. I've seen engineers adding aggressive retries even into places where the impact is minor (you could show an error and let the user manually retry instead). Retries that improve user experience can be great if done correctly, but I've never seen the authors of such pull request addressing the risk and mitigation techniques for retry storm or retry amplification.
I've seen cases which had:
1. Retries on the client side (browser or mobile app). 2. Retries on the BFF. 3. Retries on Microservice A used by the BFF. 4. Retries on Microservice B used by Microservice A. 5. Retries on Critical Service C used by Microservice B.
Most of these retries had very short timeouts (e.g. 100ms), in order to keep latency SLOs during normal operations (not a good idea on retries). Every time QA saw a layer without retries, that would be a bug, and adding retries is easy, so we'd get a new retry without much thought. But the first time Critical Service C became overloaded, Microservice B started timing out a couple of times and retrying. This was too much too much for Microservice A that had a short timeout that couldn't hold the 3 retries done by Microservice B, so it making doing its own retries, all of them dropped in the middle of the way. Eventually you'll get a full-blown retry storm where every request from the client side got amplified with 3^5 retries, easily bringing down Critical Service C.
We'd usually introduce a circuit breaker for the particular path that caused the issue, but a variation of this kept happening several times because designing safe retries across a vast collection of microservices takes a lot of effort, and it's always easier to just add a quick-and-dirty retry at any point where you think you might need one and call it a day.
A proper solution (which I've never seen implemented) would be an mandating a corporate-wide inventory of retry-paths, and monitoring it for any path that is at risk of triggering a retry storm, or adding mandatory headers that cross microservices and track the amount of retries done up the chain and the time spent in total waiting for previous retries. You could have a budget for both and automatically stop performing more retries. Both solution require extra effort and a large degree of coordination.
[1] This was the CloudFlare issue mentioned in this thread https://blog.cloudflare.com/5-december-2025-outage/
Dylan16807
44 minutes ago
> Exactly this.
It seems to me like you're saying nearly the opposite of them. You're saying "no matter what tests you have in place, it happens", while they're suggesting low standards and few tests.
swat535
38 minutes ago
More like: those tests are useless because the fundamental system design is garbage thanks to the incompetence of corporations.
bfrog
33 minutes ago
Copilot probably wrote the code confidently and it was never looked at by a human then yolo’d out to meet the pointy haired bosses arbitrarily short timeline to then look good to his boss and so on
dannyw
4 hours ago
It’s been proven that VS Code has product managers who vibe code commits that get merged, including the co-authored with copilot bug. So there’s some problems there.
noir_lord
3 hours ago
That was the final straw that stopped me using it.
I didn’t/don’t want the AI, I didn’t like the telemetry but it could be turned off but the cavalier disregard to just yeeting shit into a tool used by that many people no thanks.
mey
3 hours ago
What do you use now and what is your primary use case?
katbyte
an hour ago
I use jetbrains editors, but mostly goland which might be more stable then others
I recently tried zed but it ddos’d my nas over an smb share lol
john01dav
2 hours ago
I have been using Zed lately and quite liking it. I used Jetbrains for years, but it's gotten absurdly buggy lately so I probably won't renew it. I have also used vscode and I need to use it at work, and it's fine, but I prefer Zed (fewer bugs, faster, mainly).
hirvi74
an hour ago
I always advocate for the "boomer" editors when possible. It doesn't matter which one you choose. People can say what they want about them, but very little software survives almost 60 years. I sure as Hell hope VS Code doesn't.
psunavy03
42 minutes ago
At some point, esoteric UIs may have been needed in the 70s, but that ship has long sailed. I don't need to give myself carpal tunnel syndrome trying to quit vim. If anything, a lot of that is also a problem that continues to plague software to this day: devs who go "well if it works for me, it's good enough for anybody, and if you don't like it, you must not be a Real Developer!"
cube00
3 hours ago
They also charge ahead to prod with known defects and then change their story when they're caught out https://news.ycombinator.com/item?id=48032310
gopher_space
3 hours ago
If you've only worked at a small-to-medium privately held company you'd assume every company ran that smoothly. "Too big to fail" makes sense once you've worked for a behemoth and not before.
TomBombadildoze
4 hours ago
Lots of keyboard warriors here, very few of them solving real problems at scale.
sien
3 hours ago
Ironically wouldn't someone who solves real problems at scale actually be a 'keyboard warrior'?
hirvi74
an hour ago
At least they aren't creating new problems at scale either.
busterarm
3 hours ago
I solve real problems at scale and the engineering practices I see on a daily basis are a clown show.
There's little to no basic understanding of networking, distributed systems, databases, etc. 99% of our engineers were hired from their college internships and never worked anywhere else. Industry hires to improve systems rarely last more than a year and it is almost never their fault.
We're in the next tier down from the biggest tech companies and what we do is hardly uncommon among our peers.
I should be shocked that 99% of engineers I deal with treat all resources as infinite bandwidth, 100% uptime, but I'm not. They NIH super hard and write tons of code for things that a docker container running nginx (or similar) would solve in 5 minutes. There's almost no useful testing and worse documentation.
Welcome to corporate life.
lll-o-lll
2 hours ago
Clearly we have the same employer. Get off hacker news and get back to work!
pmarreck
2 hours ago
This is what I think of when people complain about the quality of code from AI agents.
wat10000
4 hours ago
Test coverage varies a lot, but error paths seem almost universally untested.
jambalaya8
2 hours ago
I think a lot have mostly experienced working for tech companies and do not understand how different that is from working at some other kind of company (particularly something not technically sexy) doing tech (see last parenthetical).
normie3000
an hour ago
Is GitHub a tech company? Because that's who they're criticising.
cube00
4 hours ago
> bar of corporate code quality
It's Microsoft, if they can't afford to do comprehensive unit testing, what hope do the rest of us have?
Olreich
4 hours ago
It's less about "can't afford" and more about "don't want to spend".
999900000999
2 hours ago
Microsoft is very much not FAANG. They’ve been trying to eliminate dedicated QA for years and underpay contractors.
Microsoft can afford to do a lot of things, but why when you can squeeze a bit more profit out.
hirvi74
35 minutes ago
I have never heard anyone ever utter the words, "Microsoft makes great products and services." They basically built an empire on brand recognition and vendor lock-in. Of course, a lot of their success was due to catching lightning in a bottle a few times at the right moments.
It is miraculous how they continue to fail upwards somehow. I suppose it's because they just vampirically sustain themselves by acquiring other companies and sucking them dry until they are a husk of what they once were -- like Github, Activision/Blizzard, LinkedIn, Skype, etc.. I remember when those companies used to actually produce good products and services.
fg137
2 hours ago
> It's Microsoft
That means nothing, especially with all the layoffs.
One thing that I learned over the years is never mystify "code quality". Maybe you can say a certain team/project produces high quality code, and maybe Google's overall quality is better than my company's (considering their bar of hiring), but you want to avoid generalizing that, especially at scale.
The average software engineer at a large company ships just enough code at good enough quality to earn a salary, nothing fancy about it.
beyonddream
4 hours ago
Answer is, you do comprehensive unit testing irrespective of Microsoft or any other company doing it. Also, as the OP of your comment posted, you are over estimating the software quality of these big name corporate companies. It can’t be the bar against which you would want measure your own company standards.
jldugger
3 hours ago
I mean, there are many unserious engineers in corporate America.
jdm2212
4 hours ago
A common pattern in highly available services is that sometimes you should retry immediately (because the node you hit is rolling/broken/overloaded, but the others aren't) and other times you should back off aggressively (because the service is degraded).
If your server indicates with 100% accuracy when to retry immediately vs backoff, AND if all your clients consume that information with 100% accuracy, things go great. But there are lots of situations where one or both of those breaks down.
jordanb
4 hours ago
Anyone who designs such a system should know to use an exponential backoff to avoid the thundering herd. Maybe copilot missed that while it was reviewing its own PR
jdm2212
4 hours ago
Exponential backoff is the wrong answer in a highly available system in the typical case where (a) failure is expected and (b) you have nodes you are supposed to fail over to.
dannyw
4 hours ago
Your highly available system is probably somewhat important, otherwise you won’t have invested in making it HA.
While your premise holds for happy cases, when you do have a cascading series of outages, not using exponential backoff is just adding a self-inflicted DoS to when you do go down.
I don’t really follow your premise and can’t really articulate many cases for when you shouldn’t use exponential backoff. Maybe if you’re working at Jane St or something; or other circumstances where you can deploy immediate changes to the client; and you’re willing to trade ‘better p50 for worse outages’.
But in the case of shipped code that’s run on clients, I’ll continue exponentially backing off all the way, all the time, for everything.
jdm2212
3 hours ago
When you have an outage, you should not retry at all. Exponential backoff is exactly how you get cascading outages. If service A fails a request to service B and decides to exponentially back off, now service A is holding open an end user request that will claim resources on service A. Fast forward ten minutes and the service B degradation has metastasized into a service A degradation. And even after service B has recovered, service A might still be dead.
To handle this correctly you need your RPC framework to accurately communicate retryable vs non-retryable failures to clients. Then service A knows service B is dead, does not retry, and proapgates the failure to clients. This is hard to do perfectly, but there's no alternative that works.
andrekandre
2 hours ago
> To handle this correctly you need your RPC framework to accurately communicate retryable vs non-retryable failures to clients.
basically enumerate your errors, and depending on the type, retry or just return/forward that same "dont retry this" error?jdm2212
9 minutes ago
Pretty much, but ideally it should be transparent to your app developers. App developer writes `rpc.doThing(...)` on one side, and an implementation on the other, and the infrastructure -- the RPC framework or the service mesh or whatever -- transparently handles when/whether to retry and where to route retries.
grim_io
4 hours ago
Why? You can retry, but there is nothing wrong with increasingly waiting slightly longer if we fail many times.
Dylan16807
40 minutes ago
"exponential" and "slightly longer" are very different backoff patterns.
jdm2212
4 hours ago
Try asking Opus or Fable that question. It'll give you a good answer on why microservice architectures work the way they do in order to keep user-facing latency acceptable and minimize downtime. It's a complicated enough topic that I don't feel like explaining it for free to you in a HN comment.
ctvo
3 hours ago
Why are you pretending this is a harder topic than it is and you have some secret insight. And you're a dick on top of it:
Yes, exponential backoffs alone are insufficient. Yes, adding jitter helps randomize the calls across a fleet and should be the default with exponential backoffs. Yes, both of these may be sufficient for most systems. Yes, you can dive more into circuit breakers and adaptive retries to limit thundering herd.
https://aws.amazon.com/blogs/architecture/exponential-backof...
wat10000
4 hours ago
The whole point of exponential backoff is that the first retry can be quick.
jdm2212
4 hours ago
The right answer is for the RPC framework to accurately communicate "try again on another node" vs "don't try again, just hard fail".
When one end user request fans out to hundreds of backend requests (typical for microservices), you can't have each of those backend requests do its own exponential backoff. If they do it in parallel, they're a thundering herd, and if they do it in serial, the end user request will time out before you finish all the work, at which point you're doing a bunch of slow expensive work for no gain (and the enqueued slow expensive work will make your outage worse).
vlovich123
3 hours ago
> because the node you hit is rolling/broken/overloaded, but the others aren't
Retries in such a situation should be handled internally with the client at most responsible for failing over with a circuit breaker to another zone. Having the client auto retry right away is not something that behaves well as shown here, even if in the happy path it happens to stimulate increased availability without actually investing in the proper architecture for it
dapperdrake
4 hours ago
CAP theorem. Pick one of those.
MrWiffles
6 minutes ago
We used to be able to afford two! Acronym letters cost as much as houses nowadays!
bluerooibos
3 hours ago
> You can't seriously tell me client retry doesn't have a unit test which ensures the retry back off behaviour
That wouldn't be a unit test - that's more like an end-to-end or integration test.
Have you ever worked anywhere that had perfect test coverage? It just doesn't happen, nor is it possible unless you're building a calculator app or todo list.
hirvi74
31 minutes ago
My employer has 0% test coverage lol. I've begged and pleaded, but the claim is that "risk is low" and "that's what QA is for." Hell, I've complained to senior management about how there are senior devs that forgo backend validation. It's truly Hell in the trenches sometimes.
Some days, I would seriously rather work at Wendy's.
sqquima
5 hours ago
Maybe the retry logic was vibecoded instead of using an existing hardened library. After all, according to Twitter, nobody is looking at the code anymore.
skissane
3 hours ago
> instead of using an existing hardened library
A lot of retry libraries I’ve seen require the user to configure them. You can use a library with all the right settings, but if you configure it wrong, you are really no better off than if you hadn’t
tclancy
an hour ago
> You can't seriously tell me client retry doesn't have a unit test which ensures the retry back off behaviour
Not to join the parade, but what would a unit test that confirms a cycling behavior across all the instances in-flight even look like? I mean, besides "Not a unit test".
Lammy
2 hours ago
> a wider trend to avoid showing the user any error at all costs
And in fact you can see the degradation of software over the previous decade-plus via Google Trends search for ‘something went wrong’ lol: https://trends.google.com/trends/explore?date=all&q=%22Somet...
tverbeure
an hour ago
They added 3 million CPUs. You reduce the complexity of their systems to a unit test…
giancarlostoro
4 hours ago
Backend API rate limiting has to surely kick in and force you to wait x amount of time before you try again… Discords bot API actually sends you how long before you retry.
chasd00
2 hours ago
As a client you can hit a server as much and as often as you like. The only thing the server can do is return an error code or try to hold the socket open (which the client can then close on their own).
XorNot
5 hours ago
Except the other side of this is interrupting a service which would otherwise have succeeded: there's a lot of unattended or minimally attended processes where an interruption is just asking the user to do the only thing they were going to do anyway - retry it.
In GitHub's case this is especially relevant - the only reason to throw an error message at the user is the hope they - the human - give up and walk away (or you break all the CI/CD builds and the time it takes humans to hit "retry" gives you some breathing room).