The tool in your stack that quietly went end-of-life
End-of-life is a date someone published, you just weren't subscribed to it. A watch on your stack's lifecycle surfaces the sunset while you still have room to move.
Apollo Space Research
Apollo Space
The outage started with a green build. Tests passed, the deploy went out, traffic flowed. Three days later a payment library stopped accepting a TLS handshake an upstream provider had quietly retired, and the checkout page started returning errors no one had touched in months. The post-mortem found the cause in four minutes: the library had been declared end-of-life eleven months earlier, with a published sunset date, a migration guide, and a banner on the project’s homepage. Nobody on the team had ever seen any of it.
That’s the part worth sitting with. The failure wasn’t a surprise. It was an announcement nobody was subscribed to.
End-of-life is a date someone published. You just weren’t subscribed to it. This post is about why that gap exists in every stack, why the usual fixes don’t close it, and what it looks like when something watches the lifecycle of your tools the way a good ops engineer would, if a good ops engineer never slept and never got bored.
The naive version: you’ll notice when it matters
Ask most teams how they track the end-of-life of the things they depend on, and the honest answer is: they don’t. They notice.
The model is reactive by design. A library gets pulled in because it solved a problem on a Tuesday. A SaaS vendor gets a contract because someone needed the feature that quarter. A runtime version gets pinned because it was the latest at the time. Then all three recede into the background, and the background is where they’re supposed to live. You don’t think about your foundation. That’s the whole point of a foundation.
The trouble is that the foundation has an expiry date you never wrote down. The library maintainer moves on. The vendor gets acquired and sunsets the product line. The runtime version drops out of security support. The cloud provider posts a deprecation notice for an API your code calls forty times a second. Each of these is announced, on a changelog, a status page, a release-notes RSS feed, a one-line note in a minor version. And each announcement lands in a place no human on your team reads, on a day no one was looking.
So “you’ll notice when it matters” turns out to mean “you’ll notice when it breaks.” Those are not the same moment. By the time it matters in the way you can feel, the window where moving was cheap is already closed.
The cost here isn’t the migration. Migrations are normal work. The cost is when you’re forced to do it: under an incident, with the page down, with no time to test, choosing the fastest patch instead of the right one. A sunset you saw coming is a sprint. A sunset that surprises you is an outage with a migration bolted onto the front of it.
Why the obvious fixes don’t hold
The reasonable objection is: this is a solved problem. Run an audit. Pin a dependency scanner. Put it on the quarterly checklist. Here’s why each of those leaks.
The audit is a snapshot, and lifecycles are a moving target. You audit in January, everything’s supported, you close the ticket. In March a maintainer posts a sunset notice for a thing that was fine in January. The audit didn’t miss it. The audit was just over by the time the news arrived. A point-in-time check against a continuous risk is always one announcement behind.
The dependency scanner catches a different thing. Scanners are built for known vulnerabilities, a CVE lands, the tool flags the affected version. That’s real and worth having. But end-of-life isn’t a vulnerability. It’s a status change. A library can be perfectly secure today and end-of-life today; the scanner sees no CVE and says nothing, right up until the unpatched vulnerability that will arrive has nowhere to land because the project is dead. The scanner watches for the bug. Nobody’s watching for the sunset.
The quarterly checklist fails for the most human reason of all. It depends on a person remembering to look, in the right place, across dozens of vendors and hundreds of dependencies, while doing their actual job. The first quarter it’s thorough. By the fourth it’s a rubber stamp, because checking the lifecycle status of every line in a lockfile by hand is exactly the kind of work humans are worst at, high-volume, low-stakes-until-it-isn’t, and invisible when done right. You only find out the checklist rotted on the day the thing it was supposed to catch goes down.
The bottleneck never disappears. It just moves, from “is this announced?” (it always is) to “is anyone listening?” (almost never).
The shape of the fix: subscribe to the lifecycle, not the breakage
Here’s the reframe the whole thing turns on. The announcement exists. The migration guide exists. The date exists. The only missing piece is a standing subscription that connects the thing being sunset to the place you depend on it and tells you while the date is still in the future.
End-of-life is a date someone published. You just weren’t subscribed to it. So build the subscription.
That decomposes into three jobs, and none of them is glamorous, which is exactly why no human does them reliably.
Know what you actually depend on. Not the dependencies you remember, the ones you have. The lockfile, the runtime version, the list of vendors with a contract, the cloud APIs your code calls, the third-party services behind your integrations. This is the part most lifecycle tracking skips, because it’s tedious to assemble and it drifts the moment someone adds a package. It has to be read from the source of truth, continuously, not transcribed into a spreadsheet once.
Watch where sunsets get announced. Changelogs, release notes, vendor status pages, deprecation feeds, the version where “deprecated” first appears in a docstring. These sources are public and machine-readable and almost entirely unread. A watch reads them on a schedule, not because the reading is hard, but because doing it every day across every source is precisely the work attention can’t sustain.
Match the two and rank by time-to-bite. A sunset notice for a library you don’t use is noise. A sunset notice for the runtime three services share, with a date inside your next planning window, is the most important thing in your week. The value isn’t the list of announcements. It’s the join, this notice, against this dependency, lands this close, so move now and not later.
Do those three continuously and the surprise goes away. Not because nothing gets sunset, things get sunset constantly, but because the sunset reaches you as a date on the calendar instead of a stack trace in production.
Why a watch, and not a smarter scanner
The temptation is to make this another scan, run it nightly, diff the output, alert on changes. That’s closer, but it still misses the thing that makes the failure expensive.
A scan tells you the state today. A watch understands the trajectory. The difference matters because end-of-life is rarely a single event, it’s a glide path. A version goes from “current” to “maintenance” to “security-only” to “end-of-life” to “actively dangerous,” each step published months apart. A scan that only fires on the final state hands you the emergency. A watch that’s been reading the trajectory tells you in the maintenance phase, when you have quarters, not the dangerous phase, when you have hours.
And a watch can reason about what the sunset means for you specifically, which a generic alert can’t. “Library X is end-of-life” is a fact. “Library X is end-of-life, you depend on it in the checkout path, the maintainer’s migration guide points at library Y, and three of your services would need the same change” is a brief, the kind a careful engineer writes after an hour of digging, except it’s waiting for you before you knew to dig.
That’s the move Apollo is built around: not a faster query against your stack, but a standing agent that reads the lifecycle sources, holds a live map of what you depend on, and speaks first when a date is closing in. The brain remembers what you’re running. The watch reads the world for changes to it. The agent composes the join into something you can act on, and files it as work, with the migration guide already linked, before the sunset becomes an incident.
It’s not that the machine knows something you couldn’t find. It’s that it found it before you needed it, while the announcement was still fresh and the date was still far.
What “in time” is actually worth
Put a number on it the only honest way, as a shape, not a claim. Suppose a runtime you depend on posts its end-of-life eighteen months out, the way mature platforms usually do. Caught at announcement, the migration is a planned epic: scheduled, tested, spread across a quiet sprint, shipped with confidence. Caught at the deadline, it’s the same migration done in a weekend under a deprecation cliff. Caught after, when the first unpatched vulnerability lands on the dead version, it’s the migration plus an incident plus an audit plus the conversation with a customer about why the thing was down.
Same migration, three prices. The work didn’t change. Only the warning did.
That’s the general law under this whole topic. The expensive part of a sunset was never the moving. It was the not knowing in time to move calmly. Every dollar the surprise costs is a dollar the subscription would have saved, not by doing the migration for you, but by handing it to you while it was still a choice instead of a crisis.
And it compounds across a stack. One library is a checklist item. A hundred dependencies, a dozen vendors, three runtimes, and a fleet of cloud APIs, each with its own lifecycle clock ticking on its own schedule, is a surface no person can hold in their head. The watch doesn’t get tired at dependency number forty. It reads all of them with the same attention, every day, and only speaks when one of them is about to matter.
The turn: stop being the calendar nobody updates
Strip away the changelogs and the lockfiles and here’s what’s really going on.
In most companies, the person tracking end-of-life is no one, and on the rare team where it’s someone, that someone is carrying a calendar in their head that they have to manually keep current against a world that changes without telling them. They’re the engineer who half-remembers that the auth library “might be getting deprecated,” the ops lead who meant to check the runtime support window last quarter, the founder who finds out a vendor sunset their plan from the cancellation email. It feels like diligence. It’s actually a standing anxiety with no system behind it.
That work was never a good use of a person. Remembering a date that lives in someone else’s changelog is not judgment, and judgment is the only thing your people are irreplaceable at. The point of subscribing the system to the lifecycle isn’t to replace the engineer who’d have caught it. It’s to free the engineer who was catching it, by stress, by luck, at 2am, to spend that attention on the migration’s design instead of its discovery.
The sunset is coming for something in your stack right now. It’s been announced. The only open question is whether you read it on a Tuesday with months to spare, or on a Saturday with the page down.
That’s what we’re building at Apollo Space, not a louder alert after the break, but a watch that reads your stack’s lifecycle while it’s still quiet and hands you the sunset as a date you can plan around. End-of-life is a date someone published. The good news is you don’t have to be the one who remembers to go looking for it.
Apollo runs your company's repetitive ops so your team doesn't.
Join the waitlist for early access, founding-user pricing, and a front-row seat as we ship.
Join the waitlistThe slow death of a marketer's voice
You publish one real piece a week and quietly translate it into ten, and each translation is a tiny chance to sound a little less like yourself. We built the OS because nothing on the market was guarding that.
Product ThinkingThe day someone quits, your company forgets how it works
Onboarding isn't broken because training is bad. It's broken because your company can't remember, and we got tired of watching the answer walk out the door.
Product ThinkingThe first thing a new hire should do is read the company
A great onboarding doesn't hand you docs, it already knows who you are by the time you log in.