Heroku and Vercel: when the bill exceeds the value
Heroku was the reference for frictionless deployment for startups and agencies since the late 2000s. The platform absorbed infrastructure complexity in exchange for a predictable monthly subscription. Since the Salesforce acquisition and the removal of the free plan in November 2022, the value proposition has deteriorated: a Standard-1X dyno costs $25/month, a Standard-2X dyno reaches $50/month, and an application with a web dyno, a worker, and a Postgres add-on easily exceeds $100/month. Vercel followed a similar trajectory: the Pro plan is $20/month per developer, but overages on Serverless Functions, Edge Requests, and bandwidth accumulate quietly at month's end. In September 2026, a Hacker News thread titled 'Should I run plain Docker Compose in production in 2026?' (discussion #47962032, Sept 22 2026) gathered hundreds of comments, revealing a clear trend: mid-sized teams are returning en masse to self-hosting — not out of ideology but arithmetic. A $10-20/month VPS with Coolify installed reproduces 90% of the Heroku experience — Git-push deployment, rollbacks, environment variables, custom domains — without the usage-based pricing that penalizes growth. The question is no longer 'is it technically possible?' but 'when does the opportunity cost become unsustainable?'
5 signals that it's time to migrate
- PaaS bill > $80/month — Beyond this threshold, an entry-level VPS + Coolify pays for itself in under two months. Add up all dynos, workers, and add-ons before comparing.
- Unpredictable scaling costs — Usage-based platforms (bandwidth, invocations, Edge Requests) make monthly budgets hard to forecast; a VPS offers a fixed cost with scaling under your control.
- Vendor lock-in — Proprietary Heroku buildpacks, non-portable Procfile, Salesforce ecosystem add-ons: if your stack can't run elsewhere without rewriting, that's a critical dependency signal.
- No root access — Some needs (kernel tuning, kernel modules, low-level performance tools) are impossible on managed PaaS; a VPS gives full machine access.
- Imposed CI/CD — Heroku and Vercel favor their own build pipelines; on a VPS with Coolify, you connect GitHub Actions or GitLab CI on your own terms and trigger deployments via webhook.
- Degraded support — Several users report longer Heroku support response times since the Salesforce transition; self-hosting your stack frees you from this dependency for common incidents.
Break-even: Heroku Pro vs VPS + Coolify
Scroll the table
| Heroku Pro | VPS Start + Coolify | |
|---|---|---|
| Monthly cost | ~$50/dyno | 99 DH/month |
| Scalability | Paid dynos per unit | RAM/CPU adjustable on the fly |
| Buildpacks | Native Heroku buildpacks | Nixpacks (Heroku-compatible) |
| Root access | No | Yes |
| Zero-downtime deploy | Basic health checks | Built-in Coolify |
| Database add-ons | Heroku Postgres (paid) | Self-managed PostgreSQL free |
| Logs | Logplex (limited) | Full journald / Docker access |
Coolify vs Dokploy vs Kamal
Scroll the table
| Coolify | Dokploy | Kamal | |
|---|---|---|---|
| Heroku buildpacks (Nixpacks) | Yes | No | No |
| Zero-downtime deploy | Yes | Yes | Yes |
| Web interface | Yes | Yes | No (CLI) |
| Multi-server | Yes | Yes | Via SSHKit |
| Native Docker Compose | Yes | Yes | No |
| License | AGPL-3.0 | MIT | MIT (Basecamp) |
| Server requirements | 2 vCPU / 2 GB RAM | 1 vCPU / 1 GB RAM | Ruby + Docker |
Coolify on VPS: the most Heroku-compatible option
Coolify is today the self-hosting tool closest to the Heroku experience, as open source under the AGPL-3.0 license. Its main feature is support for Nixpacks, the open source buildpack engine created by Railway that understands Heroku Procfiles and builds Docker images without you having to write a Dockerfile. In practice, a Node.js, Python (Django, FastAPI), Ruby on Rails, or PHP application deployed on Heroku can be imported into Coolify by pointing to the same Git repository, without modifying the code. The minimum recommended prerequisite from Coolify's official documentation is 2 vCPU and 2 GB RAM, which exactly matches the profile of an entry-level VPS. The web interface offers environment variable management per project, automatic deployments on Git push, one-click rollbacks, TLS certificates via Let's Encrypt, and custom domain management. Coolify also supports Docker Compose directly: if you already have a Compose stack for local development, you can deploy it as-is. Installing on a fresh VPS takes under ten minutes via the official script, and Coolify updates itself via its own built-in update mechanism in the interface. For teams that want to manage multiple servers from a single dashboard, Coolify has supported multi-server natively since version 4.
Migrate a Heroku app to Coolify in 7 steps
Install Coolify on your VPS
SSH into your VPS and run the official script:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash. The installation configures Docker, installs Coolify, and starts the interface on port 8000. Then openhttp://<VPS-IP>:8000to create your admin account.Create a project in Coolify
In the Coolify interface, click 'New Project' and give it the same name as your Heroku application. Then add a 'Resource' of type 'Application' within that project. Coolify will ask for the source: choose 'GitHub' or 'GitLab' depending on your repository, then authorize access via OAuth.
Connect the Git repository and choose the build pack
Select your repository and production branch. Coolify automatically detects the application type via Nixpacks. If your project has a
Procfile, Coolify reads it and configures the web process. You can also force an existing Dockerfile or switch to Docker Compose mode if you have adocker-compose.yml.Configure environment variables
Retrieve your variables from Heroku with
heroku config -a <app-name>. Copy them into the 'Environment Variables' tab in Coolify. Pay special attention toDATABASE_URL— the Heroku format (postgres://user:pass@host/db) is generally compatible, but if you're also migrating the database, update the URL to point to your self-managed PostgreSQL.Launch the first deployment
Click 'Deploy'. Coolify builds the image via Nixpacks, pushes it to its internal registry, and starts the container with a health check. Monitor logs in real time in the 'Deployments' tab. If the build fails, the error is displayed line by line — look first for missing system dependencies (C libraries, native binaries) that Heroku buildpacks included implicitly.
Change DNS
In Coolify, add your custom domain in the application settings. Coolify automatically generates the TLS certificate via Let's Encrypt. Then update the DNS entry (A or CNAME) to point to your VPS IP. Propagation takes between a few minutes and 48 hours depending on the zone TTL.
Validate for 24-48 hours in parallel before deleting Heroku
Keep your Heroku application active for at least 24 to 48 hours after the DNS cutover. Test all critical features (payments, notifications, incoming webhooks, scheduled tasks) on the new instance. Only once validation is complete should you cancel the Heroku subscription and shut down the dynos.
Keep your Heroku subscription active for 48 hours after the DNS migration to have an immediate rollback option. Don't cancel as soon as DNS points to the new server — third-party webhooks, scheduled tasks, and in-progress user sessions require validation over time before permanently cutting the old platform.
Common mistakes during migration
Migrating from Heroku to a VPS with Coolify concentrates a few recurring pitfalls worth knowing in advance. The first is Procfile conversion: Heroku uses a web: node server.js format that Nixpacks reads, but if your application uses release processes (automatic migrations on deployment), these hooks need to be reconfigured in Coolify startup scripts or via a custom Docker entrypoint. The second pitfall concerns missing environment variables: Heroku automatically injects certain variables (DYNO, PORT, HEROKU_APP_NAME) that your code may read without having explicitly declared them — verify your application doesn't depend on these implicit variables. The third issue is health check timeout: Coolify defaults to HEALTHCHECK --interval=30s --timeout=10s, and a slow-starting application will be considered failed and restarted in a loop. Increase --start-period to 60 or 120 seconds for large applications. Finally, the DATABASE_URL format can differ: Heroku uses the postgres:// scheme, while some modern libraries require postgresql:// — a simple substitution in the environment variable resolves the issue. For databases, avoid migrating Heroku Postgres and application data at the same time as the infrastructure: first run the application on the new VPS still pointing to the Heroku database, then migrate the database in a second step using pg_dump and pg_restore.
After migration — optimizations
Once the application is stable on the VPS, several optimizations achieve a reliability level exceeding what Heroku offered by default. The first priority is automated backups: configure daily VPS snapshots via your hosting provider's panel, and add application-level backups for PostgreSQL with a cron-scheduled pg_dump or through Coolify's interface (which includes a database backup manager since version 4.0). The second step is monitoring: install Uptime Kuma on the same VPS or a second one to monitor application availability with alerts via email, Telegram, or Slack. For more comprehensive system monitoring (CPU, RAM, disk, network), Beszel is a lightweight, modern alternative to Netdata designed for self-hosters. The third optimization concerns CI/CD: rather than triggering deployments only from the Coolify interface, configure a webhook in your GitHub Actions pipeline to automate production deployments after tests pass. Coolify exposes a per-application webhook that accepts an HTTP POST with a token — wire it in as the last step of your CI workflow. This architecture delivers a complete pipeline: push → tests → build → automatic deployment → health check, entirely under your control with no dependency on an external platform.
Migrating from Vercel — the SSR frontend special case
Vercel is designed for static and SSR frontend deployments, particularly Next.js of which Vercel is the editor. If you host a Next.js application on Vercel, Coolify supports Next.js via Nixpacks and can deploy the application in next start mode inside a Docker container. Migration is straightforward for projects that don't use Vercel Edge Functions or the distributed Edge CDN network. However, if your application relies heavily on Edge Functions — authentication logic, geo-based redirects, CDN-level A/B testing — a 1:1 migration to Coolify isn't immediate, as Coolify deploys to a single server and doesn't replicate the distributed edge topology. In that case, two approaches are viable: use Dokploy for full-stack applications with fewer Vercel-specific dependencies, or adopt Kamal (from Basecamp) combined with Nginx for teams preferring a pure CLI approach without a web interface. For Nuxt.js, SvelteKit, or Astro frontends without Edge Functions, Coolify is the simplest migration: these frameworks generate either a static build or a standard Node.js server that Nixpacks detects and containerizes automatically. The savings on a Vercel Pro stack with multiple developers can exceed $60-80/month by moving to a single VPS with Coolify, without perceptible degradation for end users in the vast majority of use cases.