I have been using Heroku for the last decade and it has served me well. At the time it was released it was pretty revolutionary and The Twelve-Factor App principals were ahead of it’s time. However, Salesforce bought Heroku back in January 2011 (almost 15 years ago) and the platform has hardly evolved since. It feels like it has been in maintenance mode for years. That stagnation shows up in the pricing, too; what felt right for 2011 no longer makes sense in 2025.
Pricing aside, Heroku is strict about its dynos and you don’t get full server access which makes it hard matching versions of Ruby or Node with the buildpack configuration and can turn into a puzzle.
Meanwhile, tools like Kamal have matured and providers like Hetzner make cheap, powerful servers easy to access. I have been weighing alternatives to Heroku for a few years. Kamal is appealing, but I still like having a slick Heroku-style UI for configuring my apps.
With all that in mind, I decided to try Hatchbox. I kept seeing people rave about it, and knowing that Chris Oliver from GoRails built it gave me confidence it was worth testing. I used Laravel Forge back when I shipped Laravel apps a decade ago, and Hatchbox immediately felt familiar in the best ways.
Long story short: I switched all of my apps from Heroku to Hatchbox in a single day and came away impressed. I deployed a very modern app—Friends Weekly—running Rails 8.1 and Ruby 3.4, and it worked without a hitch. I also deployed a slightly older app—Bootstrap Email—running Rails 6 and Ruby 2.7, and it worked on the first try. I honestly couldn’t believe it just worked. I was struggling to even get the app running on my laptop or on a newer Heroku stack, yet Hatchbox handled it flawlessly. I was extremely impressed and wanted to share the migration process in case it helps others do the same.

Here are the steps we will go through to set up and migrate from Heroku to Hatchbox:
Servers, click New Cluster, and select Hetzner.Default project, choose Security in the left nav, switch to the API Tokens tab, and click Generate API Token. Give it Read & Write access.
Apps and click New App.Create App.Environment settings in Hatchbox. Whether you use .env style variables or Rails credentials, it all works the same. When using credentials, the RAILS_MASTER_KEY variable decrypts the production credentials file. Make sure you copy over the SECRET_KEY from Heroku, or delete the SECRET_KEY if it’s in credentials, so sessions and users stay logged in through the migration.DATABASE_URL on Heroku. Copy that variable as well; we will deploy to Hatchbox while still pointing at the Heroku database for now.Deploy in Hatchbox to deploy your new app. Check the recent logs to confirm it deployed successfully. Click the View App button in Hatchbox to ensure the app is running properly in the browser 🎉Domains & SSL and add your site’s domain name. Hatchbox will generate a domain and IP address pair.ssh-keygen -t ed25519 in your terminal.cat ~/.ssh/id_ed25519.pub to print the public key and copy it.SSH Keys in Hatchbox and click New SSH Key and paste the newly generated public key into Hatchbox and save it.SSH from the left tab. You will see a line that looks something like this ssh [email protected], paste it into your terminal and you should be able to connect to the server following the steps.Import from URL.Databases and create a new unmanaged database for your app. Click View in the database you just created and copy the database url.Import from URL to set it up. It will fill out the connection form but you need to click the Over SSH button to tunnel through your ssh connection.ssh [email protected]. So for example the username would be deploy and the ip 10.20.30.40.50.Use SSH Key box and select the private key you generated on your computer at ~/.ssh/id_ed25519.pub.
Settings in the left nav.Enable Maintenance Mode at the top. This temporarily takes your app offline, and you should see a maintenance page if you visit your site.

File > Backup and backup and save the Heroku database somewhere on your computer. In my Heroku Postgres instance there were several databases, so make sure you select the one that matches the connection shown in the TablePlus status bar.File > Restore, select the Hatchbox database as the destination, add the restore options --no-owner --no-privileges --single-transaction, and choose the backup file you created from Heroku.

Environment settings, rename DATABASE_URL to HEROKU_DATABASE_URL and save. You could delete it, but renaming keeps it handy in case you need to revert quickly.RED_DATABASE_URL, which points to the Hatchbox database we created. Rename that one to DATABASE_URL so Rails uses it as the primary database.Settings and disable maintenance mode.One of the best things about Hatchbox is the flat fee per server. You get access to every feature, unlike Heroku where only certain premium dynos or database tiers unlocked the good stuff.
One of my favorite features is continuous database backups to S3, R2, or any compatible storage service. Since the database is unmanaged, having an automated safety net matters. I set mine to back up the database daily to a Cloudflare R2 bucket that keeps 30 days of history and automatically prunes older backups so I am not paying for stale data. Each database gets its own subfolder, so I use one R2 bucket to backup all of my app databases in one place.
Another feature I appreciate is Cron Jobs. I used to lean on the Heroku Scheduler add-on to run scripts cheaply, but it was pretty limited. Hatchbox gives you full cron support, so migrating any scheduled tasks from Heroku is easy and you get complete control over timing and frequency.
Thank you to Chris Oliver for not only creating a great product, but also answer my questions on X and making me excited about my Rails servers again!