Node 20 end of life was April 30, 2026, five months ago. If production still runs Node 20, it has had no security releases since then, and the next OpenSSL or HTTP parser advisory will not be backported to it. The upgrade target is Node 24, which is in Active LTS now and supported until April 30, 2028.
The good news: Node major upgrades are rarely hard. The bad news: they are rarely urgent until the week a CVE lands, and then they are very urgent.
Key Takeaways
- Node.js 20 reached end of life on April 30, 2026, per the official Node.js release schedule.
- Go to Node 24 (Active LTS, end of life April 30, 2028). Node 22 is already in maintenance and ends April 30, 2027.
- AWS Lambda deprecated `nodejs20.x` on April 30, 2026; updates to existing functions are blocked from August 31, 2027.
- Most services move in days. A rolling, per-service rollout with a canary keeps the upgrade invisible to users.
Node 20 End of Life and the LTS Schedule
| Version | Status (Oct 2026) | End of life | Lambda deprecation |
|---|---|---|---|
| Node 18 | end of life | Apr 30, 2025 | Sep 1, 2025 |
| Node 20 | end of life | Apr 30, 2026 | Apr 30, 2026 |
| Node 22 | Maintenance LTS | Apr 30, 2027 | Apr 30, 2027 |
| Node 24 | Active LTS | Apr 30, 2028 | Apr 30, 2028 |
| Node 26 | Current, becomes LTS Oct 28, 2026 | Apr 30, 2029 | GA on Lambda targeted Nov 2026 |
Sources: the Node.js Release repository (which notes that "dates are subject to change") and the AWS Lambda runtimes page.
Why not Node 22? It is a fine runtime, but it has seven months of support left. You would repeat this exercise next spring. Why not Node 26? It becomes LTS on October 28, 2026, and Lambda support is still in preview. For most teams, 24 is the boring correct answer. Boring is what you want from a runtime.
What Breaks Going From Node 20 to Node 24
Read the Node 22 announcement and the Node 24.0.0 release notes. The changes that actually show up in production code:
- Stream highWaterMark default rose from 16KiB to 64KiB in Node 22. Usually a free performance win. Occasionally it changes memory behavior in services that hold many open streams.
- `url.parse()` is runtime-deprecated in Node 24, with the advice to "use the WHATWG URL API instead". You get warnings, and some older libraries still call it.
- `tls.createSecurePair` is removed, and so is calling `fs.truncate` with a file descriptor. Rare in app code, more common in old dependencies.
- `AsyncLocalStorage` uses `AsyncContextFrame` by default. If your tracing or request-context code depends on ALS, test it under load.
- npm 11 and V8 13.6 ship with Node 24. Native addons that are not built on Node-API need a rebuild, and old prebuilt binaries may not exist for the new ABI.
- Minimum macOS is now 13.5, and building Node itself from source on Windows needs ClangCL instead of MSVC. The macOS floor is the one that bites: old developer laptops and pinned macOS CI runners.
How to Upgrade Without Downtime
Downtime during a Node upgrade almost never comes from Node. It comes from deploying everything at once. The plan:
1. Pin the version everywhere. `.nvmrc`, `engines` in `package.json`, Dockerfile base image, CI matrix, Lambda runtime setting. Drift between these is the most common source of "works on my machine".
2. Run CI on 20 and 24 in parallel until the suite is green on both.
3. Rebuild native modules (bcrypt, sharp, database drivers) and confirm prebuilt binaries exist.
4. Canary one instance of the least critical service on Node 24 behind the load balancer. Watch error rate, p95 latency and memory for 24 hours.
5. Roll per service, keeping the previous image tagged so rollback is one deploy.
6. Lambdas last, using aliases and weighted traffic shifting so a bad version gets 10% of traffic, not 100%.
A Concrete Version
A marketplace startup runs a Next.js frontend, two Express APIs, a BullMQ worker and nine Lambda functions, all on Node 20. Roughly 90,000 lines of TypeScript, decent test coverage.
- Version pinning, CI matrix, dependency bumps: 2 days.
- Native module rebuilds and one replacement for a dead dependency that used `url.parse()` internally: 2 days.
- Fix tracing breakage from the ALS change, verify under load: 1.5 days.
- Canary and rolling rollout for APIs and worker: 2 days.
- Lambda migration with weighted aliases: 1.5 days.
Total: 9 engineer-days. One engineer, under two weeks of calendar time, with no maintenance window. The only thing users notice is nothing.
The Honest Counterpoint
If Node 20 is running something that is already scheduled to die, do not upgrade it. A legacy API you are replacing next quarter can sit behind your gateway, patched at the edge, until it is gone. Upgrade effort spent on code you are deleting is pure waste. The trade-off is the same one in rewrite versus refactor.
Also, Lambda functions on `nodejs20.x` still run today, and AWS does not block updates until August 31, 2027. That is real breathing room for low-risk internal functions. I would still not count on it for anything customer-facing, because the day you need an urgent fix is the day you discover the block.
What I see most often is that the upgrade is easy and still never gets done, because it competes with features every sprint. That is how small runtime upgrades pile into expensive technical debt. A senior Node engineer can carry the whole thing while your team keeps shipping. Other runtimes on the same clock: Python 3.10 and .NET 8.
Frequently Asked Questions
When was Node 20 end of life?
April 30, 2026. Node 20 no longer receives security releases.
Should I upgrade from Node 20 to Node 22 or Node 24?
Node 24. Node 22 is in maintenance and ends April 30, 2027. Node 24 is Active LTS until October 20, 2026, then in maintenance until April 30, 2028.
Do AWS Lambda functions on nodejs20.x stop working after Node 20 end of life?
No. AWS deprecated `nodejs20.x` on April 30, 2026, but existing functions keep running. New function creation is blocked from July 29, 2027 and updates from August 31, 2027.
The Bottom Line
Node 20 is past end of life, and the upgrade to 24 is usually measured in days, not months. Canary it, roll it per service, and do Lambdas last. If nobody on the team has the days, request a shortlist of senior Node and backend engineers.
Roberto Espinoza is CEO of Ruzora, which helps US startups hire pre-vetted senior LATAM engineers, with a vetted shortlist in 72 hours. See available engineers.
