On February 6, 2026, Heroku's chief product officer published a short post titled "An Update on Heroku." It landed on a Friday afternoon — the slot PR people call "taking out the trash" — and it made official what the industry had whispered for years: Heroku is transitioning to a sustaining engineering model. No new features. No new Enterprise contracts. The Register's headline was characteristically blunt: "Salesforce puts Heroku out to PaaSture."
Here are the operative facts, stripped of corporate gentleness: the platform now runs for "stability, security, reliability, and support" instead of new features. Teams paying by credit card in the dashboard see no changes today. Enterprise Account contracts will no longer be offered to new customers, while existing Enterprise subscriptions "will continue to be fully honored and may renew as usual." Product and engineering investment is being redirected toward AI products elsewhere in Salesforce.
That last sentence holds the consequence dashboard payers keep missing: there is no longer an upgrade path. The day your security review requires Private Spaces-style isolation, Shield-level compliance, or Enterprise contract terms, that contract does not exist for you as a new buyer. The ceiling is now permanent.
This post is the phased counterpart to a weekend cutover runbook: a 90-day exit playbook for teams that need to leave carefully rather than quickly — what "sustaining engineering" meant for other Salesforce products before sunset, the audit to run before your next incident, the week-by-week migration sequence for a Postgres plus web plus worker stack, and the real cost of moving versus waiting.
What "sustaining engineering" has meant at Salesforce before
"Managed decline" is the phrase one consultancy used within days of the announcement, and Salesforce's own history gives the pattern its shape. The company has retired products before — Social Studio most recently — and the choreography is consistent:
| Stage | What Salesforce does | Social Studio precedent |
|---|---|---|
| 1. Freeze | Stop new sales and new investment; keep existing customers running | Pre-2024: roadmap quietly stalls |
| 2. Retirement date | Publish an end-of-access date | Retired November 18, 2024 |
| 3. Contract-end cutoff | Access ends at your contract end or the retirement date, whichever comes first | Exactly the published terms |
| 4. Data deletion | Customer data deleted after a grace window | 90 days after access ends |
Heroku today is at stage 1: the February 2026 announcement is the freeze, with existing behavior and billing unchanged. Salesforce has announced no retirement date, and this post will not invent one. But the pattern matters for planning because of what it implies about notice: Social Studio customers got a date and a contract-end cutoff, not a negotiation. A team that starts its 90-day exit now does it on a schedule it controls. A team that waits for a stage-2 announcement migrates against somebody else's deadline, alongside every other Heroku customer hiring help in the same quarter.
The softer precedent sits inside Heroku itself: the free tier shut down in November 2022, feature work visibly slowed through 2023–2025, and a major outage in June 2025 further eroded confidence. February formalized the trajectory; it did not start it. Sustaining mode is not a pause before a comeback — comebacks do not begin by closing Enterprise sales to new customers.
The audit: inventory your footprint before your next incident
The most dangerous property of a frozen platform is that nothing breaks today. Pressure arrives as slow clocks, not incidents — until one of them becomes an incident, and then there is no roadmap fix coming, only your own runbook. Run this audit this week, before you need it. Every row is a question your team should be able to answer without opening the dashboard:
| # | Inventory item | Why it matters now | Where to look |
|---|---|---|---|
| 1 | Stack and its EOL date | When a Heroku stack reaches end of life, apps keep running but new builds are blocked until you upgrade — the Heroku-18 precedent from May 2023. A whole new stack generation is uncomfortably close to a "new feature," so your current stack's EOL is the most important date on your Heroku calendar. | heroku stack -a APP, stack update policy |
| 2 | Dyno formation and tier | Basic ($7) dynos are always-on but cannot scale horizontally; Standard-1X ($25) is the first tier with real production behavior. Your formation determines both the bill and the migration target size. | heroku ps -a APP, billing invoice |
| 3 | Postgres plan, version, and connection limit | Essential-0/1 allow 20 connections, Essential-2 allows 40, Standard-0 allows 200. Follower-based upgrades are unsupported on Essential tiers. Note the upstream PostgreSQL EOL for your major version — sustain mode does not pause it. | heroku pg:info -a APP |
| 4 | Redis / key-value store plan and version | Same forced-march dynamics as Postgres: upstream EOLs keep their own schedule regardless of Heroku's freeze. | Add-on dashboard |
| 5 | Every add-on and its vendor health | Retirements do not need Heroku's permission. An add-on whose maintainer stopped investing — logging, monitoring, email, queues — is a migration you will do under time pressure later. | heroku addons -a APP, vendor changelogs |
| 6 | Buildpacks and runtimes | No new language runtimes or buildpack generations will ever ship. Pin what you have and confirm it still receives security updates. | heroku buildpacks -a APP |
| 7 | Config vars and secrets | The classic migration failure is a var set three years ago that code reads but docs never mention. Export now. | heroku config -s -a APP |
| 8 | Pipelines, review apps, and CI coupling | Review apps and pipeline promotions are Heroku-shaped conveniences your destination must replace with preview environments and a promotion flow. | Pipeline dashboard, app.json |
| 9 | Scheduler jobs and one-off dynos | Billing reconciliation, nightly exports, cleanup crons — each needs a cron equivalent on the other side. | Scheduler add-on, heroku run history |
| 10 | Custom domains, TLS, and DNS | Automated certificate management is the kind of invisible feature you only miss during cutover. List every domain and its termination. | heroku domains -a APP |
| 11 | Enterprise-only dependencies | Private Spaces networking, Shield compliance features, SSO/SAML at the Enterprise tier — anything you use today but could not buy tomorrow. | Enterprise contract, security review docs |
| 12 | Backup posture | When did you last restore from a backup, not just capture one? An untested backup is a rumor. | heroku pg:backups -a APP |
Rows 1, 3, and 11 turn migrations-by-choice into migrations-by-incident: a stack EOL blocks deploys, a Postgres major-version EOL forces a downtime-window upgrade on a shrinking team, and row 11 is the Enterprise door closing behind you.
The 90-day playbook, phase by phase
Twelve weeks is deliberately unheroic: it fits a team that still has a product to ship, leaves room for one failed rehearsal per phase, and ends inside a single quarter. Each phase has an exit criterion — do not advance until it is met.
| Phase | Days | Work | Exit criterion |
|---|---|---|---|
| 1. Audit and landing zone | 1–14 | Complete the 12-row audit; pick the destination (managed Heroku-style successor or self-hosted fleet); stand up a staging equivalent; export config vars and capture a first backup | Staging deploy of the current release passes smoke tests on the destination |
| 2. Data layer | 15–45 | Migrate Postgres first — it is the longest pole. Rehearse dump/restore, then execute; move Redis after | Production data verified on the destination, restore-from-backup tested there |
| 3. App and workers | 46–75 | Migrate web dynos, worker dynos, scheduler jobs, and review-app equivalents; shadow production traffic if possible | Full formation running on the destination under realistic load |
| 4. Cutover and decommission | 76–90 | Lower DNS TTLs, cut over, hold a rollback window, then delete Heroku resources and cancel add-ons | Zero production traffic on Heroku; Heroku bill at $0 |
Phase 1 is mostly decisions: a managed successor with Heroku-like developer experience (fastest onboarding, dyno-rhyming per-service pricing) or a self-hosted fleet on owned hardware (lowest steady-state bill, highest operational ownership). Either is defensible; skipping the staging equivalent is not. Your first deploy to the destination surfaces every Heroku-ism hiding in the codebase — DATABASE_URL assumptions, ephemeral-filesystem writes, release-phase tasks — and you want that discovery in week two, not week eleven.
Phase 2 deserves its length. Heroku Postgres does not offer logical replication to an external follower, so the standard path is dump and restore with a downtime window:
heroku pg:backups:capture -a YOUR_APP
heroku pg:backups:download -a YOUR_APP
pg_restore -d "$DEST_DATABASE_URL" latest.dump --no-owner --no-aclThe --no-owner --no-acl flags are not optional: Heroku's role names do not exist on the destination, and without them the restore fails on grants it cannot apply. Two gotchas apply. First, Essential-tier databases cap connections at 20–40, so schedule the dump when nothing else competes for connections. Second, follower-based near-zero-downtime upgrades are unsupported on Essential plans — the dump window is the plan, so rehearse it on staging and time it. For databases too large for an acceptable window, budget either a dual-write period or an announced maintenance window back in phase 1. Move Redis after Postgres with the same rehearse-then-execute discipline; cache layers are faster but eviction and persistence settings still need verification.
Phase 3 moves the compute. Containerize from your buildpacks rather than rewriting: most buildpack apps produce a working container with minimal changes. Map each formation row explicitly — web dynos to web services, workers to background workers, Scheduler entries to cron jobs, review apps to preview environments — and keep a checklist, because the failure mode is always the row somebody forgot. If your destination supports traffic shadowing, use it here; a week of mirrored production traffic catches the drift that smoke tests miss.
Phase 4 is cutover mechanics. Lower DNS TTLs to 60 seconds at least 48 hours before the switch. Cut over writes first (database, then workers), then web traffic. Hold the Heroku app in maintenance mode — not deleted — for one full billing cycle as your rollback parachute, with a tested reverse-restore path for data written to the new primary. Only then decommission: delete the app, cancel each add-on individually (deleting the app does not always cancel every billing line), and confirm the next invoice reads $0. The classic post-migration surprise is a $50 Postgres line still billing three months later because nobody removed the attachment.
The money: web plus worker plus Postgres, costed honestly
Anchor the comparison where the title's payer lives: the $7 Basic dyno. Two formations cover most of the Heroku footprint — the side project that grew up, and the small production app. Heroku figures are September 2026 list prices; the self-hosted column is a Cluster API-managed fleet on Hetzner, using three CX22 machines (2 vCPU, 4 GB RAM each) at €3.79 per month net, or about $4.10 at typical rates.
Formation A: side project that grew. One Basic web dyno ($7), one Basic worker ($7), Essential-1 Postgres ($9). Heroku total: $23/month. The same workloads bin-pack onto a single CX22-class node at roughly $4/month — with the honest caveat that one node is not highly available. This formation migrates in days, and the playbook above compresses accordingly.
Formation B: small production app. Two Standard-1X web dynos ($50), one Standard-1X worker ($25), Standard-0 Postgres ($50), Redis Mini ($15), and routine logging/monitoring add-ons ($15–30). Heroku total: roughly $155–170/month, about $1,900/year. The equivalent on three owned nodes runs about $12/month in hardware — a ~13× infrastructure reduction matching published migration invoices.
Both comparisons above are infrastructure-only, which is exactly how migration math lies. The honest first-year ledger for Formation B looks like this:
| Line | Stay on Heroku | Migrate to self-hosted |
|---|---|---|
| Infrastructure, 12 months | ~$1,900 | ~$150 |
| Migration labor (one-time) | $0 | $2,800–8,400 |
| Ongoing ops delta, 12 months | $0 | $1,200–3,600 |
| First-year total | ~$1,900 | ~$4,150–12,150 |
The labor line assumes 28–56 engineering hours across the four phases (audit 4–8, data layer with rehearsal 8–16, app migration 8–24, cutover plus hypercare 8) at a loaded $100–150/hour. The ops delta assumes 1–3 hours a month of fleet care the platform used to absorb. Year one on self-hosted hardware costs more — payback arrives in year two, when the $1,750/year infrastructure delta compounds against a labor line that does not repeat.
That sensitivity runs on team shape, not stack shape. A team already comfortable with containers and infrastructure-as-code lands near the bottom of the labor range and breaks even in months. A team whose entire ops knowledge is git push heroku main lands near the top — and for that team, a managed Heroku-style successor (typically $40–75/month for Formation B, near-zero ops delta) often beats both staying and self-hosting on first-year total. Size the destination to the team you have, not the team the pricing page assumes.
What waiting costs
Staying is billed in risk instead of dollars. Every item below is already true and permanently unfixable by the vendor:
- The 30-second router timeout, daily dyno restarts, and AWS-only US/EU regions are now load-bearing walls. If any of them already hurts, no relief is coming — improvement is a feature, and features are frozen.
- Your stack's EOL date blocks deploys, not just patches. When a stack reaches end of life, new builds stop until you upgrade. Audit row 1 is a calendar item, not a backlog item.
- Add-on drift compounds. Every partner-maintained add-on follows its own roadmap, and partners invest where growth is. Each quiet deprecation is a future migration compressed into an incident window.
- The Enterprise door stays closed. Growth into compliance, isolation, or contract requirements you cannot buy is the most common forced exit — and it arrives as a failed security review, not a vendor notice.
- Hiring drag accrues. Every engineer you onboard from now on learns a platform the industry press describes in past tense, and explains it to the next interview loop.
None of these is an argument for panic — Heroku works today. They are an argument for a calendar: ninety days on your schedule beats the same ninety days against somebody else's retirement notice.
Start with the audit. Twelve rows, one afternoon, no destination decision required. By row 12, you will know whether you are planning an exit or scheduling one — before your next incident decides for you.
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 90-day clock just started, star the repo on GitHub or deploy your first app today.



