Skip to main content

Heroku's Shutdown Isn't Announced — Your Contingency Checklist Should Be Done Anyway

11 min readDora NodaDora Noda
Share
On this page

Salesforce buried the news on a Friday afternoon. On February 6, 2026, Heroku chief product officer Nitin T. Bhat published a short post titled "An Update on Heroku" announcing the platform was moving to a "sustaining engineering model" — no new features, no new Enterprise contracts, engineering investment redirected toward AI elsewhere in Salesforce. The Register, which called the timing "taking out the trash," ran the headline "Salesforce puts Heroku out to PaaSture." Three days later, InfoWorld's Anirban Ghoshal published the read every Heroku team has been arguing about since: "Salesforce may be prepping to phase out Heroku."

To be fair to the vendor, quote its framing in full before drawing any inference. Heroku's announcement describes "an actively supported, production-ready platform, with an emphasis on maintaining quality and operational excellence rather than introducing new features." Existing Enterprise subscriptions "will continue to be fully honored and may renew as usual," dashboard customers see no change, and the platform keeps its stability, security, and reliability commitments. No shutdown has been announced. No sunset date exists.

Here is the announced-versus-inferred line this post holds throughout. Announced: the roadmap is frozen and the team that would have built Heroku's future now works on Salesforce's AI bets. Inferred — by InfoWorld's reporting and the analysts it quotes, one of whom expects Heroku's Postgres to be absorbed into Data Cloud while the dyno-based compute layer is phased out in favor of Agentforce: that sustaining mode is the waiting room before a phase-out, not a permanent steady state.

You do not have to agree with the inference to act on it. If the analysts are wrong, the work below costs you a few focused days and leaves you with the best-documented estate you've ever had. If they are right, it is the difference between executing a plan and discovering your dependencies under a deadline.

This is not a migration guide. It is the audit you run while everything still works: the export-ready inventory of every Heroku-coupled artifact a shutdown notice would strand — buildpacks and slugs, your Cedar-versus-Fir generation split, data and container images, config, and the add-on disentanglement order. Do it in three tiers: this week, this month, this quarter.

Tier 1 — this week: the app inventory nobody has written down

Most teams running on Heroku for years cannot answer three basic questions without opening the dashboard: which generation each app is on, which stack each app runs, and what builds it. A shutdown notice turns each unknown into a discovery task on someone's worst week. Collect the answers now, while the CLI still answers patiently.

Start with the census. heroku apps --all lists everything the account can see, and heroku apps:info --app <name> reports each app's generation, stack, and region. Record all three per app, because the generation split is the single most consequential fact in your estate.

Cedar-generation apps run classic buildpacks (or Docker images) on Heroku's EC2-based runtime; Fir-generation apps — generally available since April 2025 — run Cloud Native Buildpacks as OCI containers on Amazon EKS backed by Graviton ARM instances. The two generations cannot share a pipeline, do not deploy the same way, and do not retire the same way. Any contingency plan that treats "the Heroku apps" as one uniform thing is wrong on page one.

Next, the stack audit, because Heroku has already shown you exactly what its sunsets look like. When Heroku-20 reached end of life on April 30, 2025, apps on it kept running but stopped receiving security updates — and no new builds could be performed until each app upgraded to a supported stack. "Keeps running, cannot deploy" is the house style of a Heroku ending: not a shutdown, a freeze that arrives disguised as someone else's routine. Today's map is Heroku-22 deprecated and supported through April 2027 (Cedar only), Heroku-24 the default through April 2029, and Heroku-26 supported through April 2031. Flag every app still on Heroku-22 now; its EOL is the closest thing to a hard date your contingency plan has, and it arrives whether or not a shutdown notice ever does.

Then the build inventory: heroku buildpacks --app <name> for the ordered buildpack list, heroku stack --app <name> to confirm the stack, and a note of each app's slug size and language runtime versions. Pay special attention to anything exotic — a vendored buildpack URL, a pinned legacy runtime, a Docker-deployed app. Standard buildpacks are portable knowledge; the weird ones are the migration risks, and "weird" is only discoverable by listing. One wrinkle worth recording: Heroku extended Cloud Native Buildpack support to Cedar-generation apps in September 2026, so a Cedar app's build story may be classic buildpacks, CNBs, or Docker — three different export paths from what the dashboard shows as one app type.

Tier 1 done means a one-page table: every app, its generation, stack, region, buildpacks, and anything exotic. If that table takes more than a day to assemble, that itself is a finding — it measures how much of your platform knowledge lives in people's heads.

Tier 2 — this month: data and images, the things you cannot recreate

Applications are replaceable; data and built artifacts are not. Tier 2 exports everything a shutdown notice would put on a clock, starting with the database drill most teams have never actually run.

Run a full Postgres backup rehearsal, not just a backup. heroku pg:backups:capture --app <name> followed by heroku pg:backups:download proves the export path works and tells you the dump size, the restore time, and the Postgres version and extensions (heroku pg:info lists them; PostGIS, pgvector, and pgcrypto each add migration work) while nobody is waiting on the result. Time the restore into a scratch database and write the number down — that duration is your minimum cutover window, and learning it during a drill instead of during a migration is the entire point.

Do the same review for Heroku Data for Redis with heroku redis:info: is it cache you can drop and rewarm, or persistent state with a backup story you need to rehearse? Cache and persistent store look identical in the add-on list and nothing alike in a contingency plan.

Then the container images, which are Tier 2's least obvious trap. Heroku's Container Registry is Cedar-only and amd64-only: Docker deploys are not supported on Fir-generation apps at all, and every image in the registry is x86_64. If any of your apps deploy from Docker, those images live in exactly one place — a registry attached to the legacy generation of a frozen platform.

Re-pulling every image to a registry you control is a one-afternoon job today that becomes a forensic exercise the day the old registry is unavailable. Pull them with heroku container:pull or plain docker pull from registry.heroku.com, push them to your own registry, and record the Dockerfiles and base images alongside. While you are there, note each app's release history (heroku releases --app <name>): the last-known-good slug or image per app is the rollback target your runbook will reference.

Tier 2 done means: a tested Postgres dump-and-restore with a timed window, a Redis persistence verdict per app, every container image mirrored to your own registry, and a recorded rollback release per app. None of this migrates anything. All of it converts "we think we can leave" into measured fact.

Tier 3 — this quarter: config and the add-on disentanglement order

With apps inventoried and data exportable, Tier 3 extracts the connective tissue: config vars and the add-on catalog, in an order that mirrors how a real migration would consume them.

Extract twelve-factor config first, because every destination needs it on day one. heroku config --shell --app <name> dumps the full config-var set; store it encrypted, outside Heroku, per app — and then do the harder pass the dump enables. Classify every var: secret (rotate it after export so the backup never becomes a second live credential), pointer (anything ending in _URL that names a Heroku add-on, which is really a migration dependency in disguise), or plain setting. Teams routinely discover config vars pointing at add-ons nobody remembers provisioning, which is precisely why this step precedes the add-on audit rather than following it.

Then list every add-on per app with heroku addons --app <name> and sort the catalog into disentanglement order — the sequence in which a migration would actually replace them:

  1. Data stores first (Postgres, Redis, Kafka, search): they hold state, set the cutover window, and everything else points at their URLs. Choose each one's future home before touching anything downstream.
  2. Stateful platform services (queues, object storage via add-on, Heroku Connect syncs): they hold configuration and backlogs that must drain or transfer deliberately.
  3. Stateless SaaS (email delivery, error tracking, monitoring, log drains): usually a matter of new API keys and repointed drains — but enumerate every heroku drains --app <name> entry and custom domain (heroku domains --app <name>, plus certificate subjects) now, because DNS and TLS are where migrations lose their weekends.
  4. Heroku-only constructs last (Scheduler jobs, release-phase tasks, review apps, pipelines): these have no vendor to port — they must be redesigned onto cron, CI preview environments, and the new platform's pipeline shape. List every scheduled job's command and cadence; "a scheduler runs something nightly" is not documentation.

Tier 3 done means: encrypted per-app config with secrets rotated, every _URL pointer mapped to its replacement decision, and every add-on assigned to one of the four tiers above with its replacement named. At that point you have not migrated a single workload — and you have done most of the thinking a migration requires.

The fire drill: a shutdown notice arrives on Monday

The test of a contingency plan is whether a hypothetical notice becomes an execution trigger instead of a discovery project. Walk it through. Monday's notice announces an eighteen-month sunset — generous, Heroku-20-shaped, "keeps running, then stops." Your Tier 1 table answers the first leadership question (what do we have, and which generation is the long pole?) in the first meeting, not the third week. The Heroku-22 apps were already flagged; their April 2027 EOL was going to force action regardless, so they lead the queue.

Months one to three consume Tier 2: the rehearsed Postgres restores set each cutover window from measured timings, the mirrored container images mean Docker-deployed apps rebuild from your registry on day one, and the Redis verdicts tell you which caches can simply be dropped. Months three onward consume Tier 3 in disentanglement order — data homes first, Heroku-only constructs redesigned last — with config extraction already done and secrets already rotated. Review apps get their replacement (CI preview environments) designed once, not rediscovered per team. DNS cutovers follow the domain inventory instead of a frantic heroku domains session.

Notice what never appears in that sketch: a discovery phase. Every "we need to find out" task was completed during calm quarters, which is the whole argument. A shutdown notice with this plan in hand schedules work; without it, it schedules panic with the same deadline.

Writing the plan is scoping the migration

Step back and look at what the three tiers produced: a per-app inventory with generation and stack verdicts, measured data-export windows, mirrored images, classified config, and every add-on mapped to a replacement in migration order. Now compare that against the first half of any competent migration estimate — to Render, to Railway, or to owned Hetzner hardware running a git-push platform of your own. They are the same document. The contingency plan does not precede the migration scope; it is the migration scope, written early enough to be careful instead of frantic.

That is why the announced-versus-inferred line from the top of this post barely matters for what you do this quarter. If Heroku runs for another decade as an actively supported platform, you spent a few days producing the definitive map of your estate — the map every security review, cost audit, and onboarding doc has always wanted. If InfoWorld's read proves right and the dyno layer winds down while Postgres folds into Data Cloud, you start executing on day one while everyone else starts discovering. Either way, the checklist is the highest-leverage Heroku work your team can do this year. Start Tier 1 this week.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. If your contingency plan ends with "owned hardware," star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex