What's New

New updates and improvements to Hatchbox.io

jemalloc is on by default for new apps

Improvement

New apps on native clusters now start with LD_PRELOAD=libjemalloc.so.2 in their environment variables, so Puma and Sidekiq run on jemalloc instead of glibc malloc. Rails apps typically see noticeably lower and flatter memory use with no code changes.

It's an ordinary environment variable, so you stay in control:

  • Existing apps can opt in by adding LD_PRELOAD with the value libjemalloc.so.2 on the app's Environment Variables page. It takes effect on the next deploy or restart.
  • New apps can opt out by deleting the variable.
  • Docker apps are unaffected. The Dockerfile owns the container environment, and Rails' default Dockerfile already sets jemalloc up.

The library is already installed on every Hatchbox server, so there's nothing to provision.

Smaller, single-file database backups

Improvement

Database backups are now written as a single compressed file per database rather than a dump inside a .tar.gz. A backup now needs about one compressed copy's worth of free disk instead of room for the dump and its tarball together. Postgres dumps also stop being compressed twice.

New backups are named:

  • PostgreSQL: <database>.dump, restore with pg_restore
  • MySQL: <database>.sql.gz
  • Redis/Valkey: <database>.rdb.gz
  • SQLite: <database>.sqlite3.gz

Existing databases keep their current .tar.gz backups until you switch them. To switch, open the database, choose Backups → Configure and click Save. You don't need to change anything. New databases and backup settings use the new format automatically. If you use the API or MCP, updating a database's backup configuration does the same.

If you have scripts that look for *.tar.gz files in your bucket or in /home/deploy/backups, update them before you switch.

Each database page now has a How to restore this backup section under Backups, with the exact commands for your engine and server. Docker clusters get docker exec versions. Older .tar.gz backups still work and get their own restore steps.

PgHero query stats and a user per database

Update

This applies to PostgreSQL servers that Hatchbox installs, on regular and Dockerfile clusters. Managed DigitalOcean databases aren't affected.

Each database gets its own user

Until now, every database's user was a Postgres superuser. A superuser can read every other database on the server and run shell commands on it, so one leaked DATABASE_URL exposed everything on that server.


New databases now belong to their own user, without superuser. That user can still run your migrations and enable the common extensions, like pgcrypto, citext, hstore, pg_trgm and uuid-ossp. Existing databases keep the user they have.


Extensions that need a superuser, like postgis or timescaledb, can't be created from a migration anymore. Install them on the server and create them once as postgres. After that, enable_extension in your migrations finds the extension already there and moves on.

PostGIS

SSH into the database server and install the package for your PostgreSQL version (18 here), then create the extension in your app's database:

sudo apt install postgresql-18-postgis-3
sudo -u postgres psql -d your_database -c "CREATE EXTENSION postgis;"

TimescaleDB

Install it with Timescale's Ubuntu instructions. TimescaleDB also has to be preloaded, so add it next to pg_stat_statements, restart PostgreSQL, and create the extension:

sudo -u postgres psql -c "ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements', 'timescaledb';"
sudo systemctl restart postgresql
sudo -u postgres psql -d your_database -c "CREATE EXTENSION timescaledb;"

These steps are for regular clusters. Dockerfile clusters run the official postgres image, which doesn't include PostGIS or TimescaleDB.

PgHero query stats work out of the box

New PostgreSQL servers load pg_stat_statements, and each new database has it installed, so PgHero's Queries page works with no setup. Each app only sees its own queries.


On an existing server, click Update on the server's page to turn it on. This restarts PostgreSQL, so pick a quiet time. Then run CREATE EXTENSION pg_stat_statements; in each existing database you want stats for, or use PgHero's Enable button.

If you customized shared_preload_libraries

Hatchbox now sets shared_preload_libraries when it updates a PostgreSQL server. It keeps the libraries your server already loads and adds pg_stat_statements, so nothing you set is removed. Where you set your list matters:

  • On the existing shared_preload_libraries line in postgresql.conf: nothing to do. Hatchbox copies your libraries into conf.d/hatchbox.conf next to pg_stat_statements.
  • At the end of postgresql.conf, under CUSTOMIZED OPTIONS: your line still wins, so pg_stat_statements won't load. Add it to your list, for example shared_preload_libraries = 'timescaledb,pg_stat_statements', and restart PostgreSQL.
  • With ALTER SYSTEM, including on Dockerfile clusters: your setting wins as well. On a Dockerfile cluster, Hatchbox adds pg_stat_statements to your list for you. On other servers, include it in your own ALTER SYSTEM list.

Questions? Email us.

Ruby 4.0.9, 3.4.12, and 3.3.13 support

New

Ruby 4.0.9, 3.4.12, and 3.3.13 are now precompiled and ready to deploy on Hatchbox.

These are security releases. They fix memory corruption bugs in Ruby's regular expression engine that GitLab reported as CVE-2026-89078, CVE-2026-93577, CVE-2026-97229, and CVE-2026-110264. Apps that build regular expressions from user input should upgrade as soon as possible. See the Ruby announcement for more details.

Ruby 4.0.8 support

New

Ruby 4.0.8 is now precompiled and ready to deploy on Hatchbox. This is a routine bugfix release. See the GitHub release notes for more details.

Hatchbox is now $15 per server per month

Update

As of October 1st, Hatchbox is $15 per server per month. This applies to all customers, new and existing.

We emailed everyone ahead of the change, but here's the reasoning in case you missed it.

Why we raised prices

For years, GoRails, the education side of our business, subsidized Hatchbox development. AI has been brutal to most education businesses and we're no exception. We'll have fewer new GoRails customers in 2026 than in our first year in business.

Knowing that was coming, Collin and I have focused on Hatchbox for the last 12 months. We shipped a lot:

  • Cluster visualizations
  • Caddy metrics
  • Load balancer health checks & retries
  • Colored logs
  • Database metrics & backup downloads
  • A revamped API and an MCP server
  • Better static site support
  • On-Demand TLS

We hoped Hatchbox would grow enough to be sustainable on its own. Growth has been slower than we were aiming for, which left us with two options: raise prices and keep working on Hatchbox full-time, or put it on the back burner and get jobs.

We chose to keep building.

Why $15, and why everyone

When we launched the current version of Hatchbox, we priced it low to make it more accessible and didn't think hard enough about long-term sustainability. Ironically, lower pricing makes Hatchbox less accessible in the long run, because we have fewer resources to reinvest in making it better.

Hatchbox Classic was $15 per server, so this is basically a return to our original pricing.

I thought hard about grandfathering existing customers. But that would lock in the exact problem we're trying to fix: most of our revenue would stay at the old rates.

I never wanted to raise prices on the people who backed us from the start. But I'd rather charge fairly and keep building Hatchbox than keep it too cheap and slowly let it go.

Questions?

We'd love to hear from you. Email us if you have questions, concerns, or just want to share how you're using Hatchbox.

Thank you for trusting us with your deploys.

— Chris & Collin

Moving build & deploy scripts to Git

Update

Custom build and deploy scripts are really powerful, but having them stored in your app configuration can be worrisome. What if someone accidentally cleared it out? What did the previous version look like?

To solve these problems, you can now specify build and deploy scripts inside your Git repository. This lets you version control them to track changes, but it also means the scripts live right along with the rest of your code in one place so they can't get lost.

Hatchbox now looks in the .hatchbox folder of your Git repository when deploying. If it finds a matching script, it will execute it.

Screenshot 2026-08-27 at 1.15.59 PM.png
Build & Deploy scripts in your Git repository

While you'll most commonly write these in Bash, you can also specify any language in the shebang if you want to use Ruby, Python, etc.

Easier Git repository selection

Improvement

For the longest time, ​Hatchbox​ had simple text fields to enter the Git organization/repository name and branch.

This worked fine for a long time, but it was prone to errors. You might mistakenly paste in a URL or make a typo and your deployment would fail.

We've revamped this process to use the GitHub, GitLab, and Bitbucket APIs to load repositories and branches so you can easily find the repository and branch you want to deploy.

Zight Recording 2026-08-25 at 08.42.17 AM.gif
Zight Recording 2026-08-25 at 08.42.17 AM.gif 1.32 MB

Deploy an app to give it a try!

Cluster Visualization

New

As your clusters grow, it can be hard to keep track of which servers are responsible for what. You have a load balancer, many web servers, background workers, database servers, etc. It gets to be a lot.

So this week, we've introduced a new visualization for clusters that visually shows how they connect in the cluster.

Screenshot 2026-08-24 at 11.20.05 AM.png
Cluster visualization

Internet facing servers like load balancers and web servers show how traffic flows from the internet. Backend servers are grouped in their own section and show their roles and responsibilities as well, separate from the web-facing servers.

Full control over your Hatchbox infrastructure — from chat

New

The Hatchbox MCP server is live in beta. Point Claude Code or Claude Desktop at your Hatchbox account, and it can read and act across all of it.

We built an MCP server for Hatchbox: @hatchbox/hatchbox-mcp, available on npm today.

This isn't a status-check bot. Claude can read and act across your whole Hatchbox account — apps, deploys, databases, servers, domains, env vars, logs — and cross-reference it against other tools you already have open in the same conversation, like GitHub.

What it looks like in practice

"Is my lumio-app running the latest code?"

Claude checks the commit Hatchbox has deployed, compares it against the latest commit on GitHub, and — if they've drifted — can trigger a deploy on Hatchbox to close the gap. One question, two systems, one answer, and an action if you want it.

What it covers

The server wraps Hatchbox's /api/v1 API with one tool per operation, so Claude can work across:

  • Apps & deploys — create, update, restart, deploy, toggle auto-deploy
  • Databases & backups — inspect app and cluster databases, create backups, attach/detach
  • Servers & clusters — inspect servers and the clusters they belong to
  • Domains & env vars — create, update, delete domains; manage environment variables
  • Logs — follow deploy, restart, and backup jobs through to completion

Every write operation is annotated so Claude (and you) can tell read-only calls apart from destructive ones before anything runs.

Setup

1. Get an API token. Log into Hatchbox, go to /api_tokens → New API Token, name it, and copy the value.

2. Point your MCP client at it. No install step — npx fetches and runs the package on demand.

Claude Code:

claude mcp add hatchbox -- npx -y @hatchbox/hatchbox-mcp

Then set HATCHBOX_BASE_URL and HATCHBOX_API_TOKEN for that server (see claude mcp add --help, or edit .mcp.json directly).

Claude Desktop (claude_desktop_config.json):

{
"mcpServers": {
"hatchbox": {
"command": "npx",
"args": ["-y", "@hatchbox/hatchbox-mcp"],
"env": {
"HATCHBOX_BASE_URL": "https://hatchbox.io/api/v1",
"HATCHBOX_API_TOKEN": "your-token-here"
}
}
}
}

HATCHBOX_BASE_URL is always https://hatchbox.io/api/v1 — the same for every account, not something you need to look up.

Every developer authenticates with their own Hatchbox API token. Nothing is shared across a team, and there's nothing for us to provision on our end.

A note on the token

Your API token has no scoping — it's effectively full access across your accounts, gated only by your subscription status. Treat it like a password: don't commit it, don't share it, and use your MCP client's env-var handling rather than pasting it into a prompt.

This is a beta

Claude Code support is done and verified end-to-end against production. Claude Desktop works today too, but only through the manual config above — a one-click install bundle is coming next.

That means the rough edges are still visible, and we'd rather hear about them now than after a wider release. If something's confusing, missing, or breaks, tell us — that's exactly what the beta period is for.

npm i @hatchbox/hatchbox-mcp

SQLite Database Backups

New

While Hatchbox has always supported deploying apps with SQLite databases, we didn't have any way to add them to the Hatchbox UI.

Starting today, each application server gets it's own SQLite database cluster. You can add a database pointing to the path on disk where the database lives. Adding the database enables SQLite backups and the ability to associate the database to applications with environment variables.

Load Balancer Upstream Health

New

For load balancers, you can now see the health of each upstream in the reverse_proxy configuration in the server's Caddy tab. This makes it easy to spot unhealthy hosts and fix issues that arise.

Screenshot 2026-07-22 at 12.06.09 PM.png
Screenshot 2026-07-22 at 12.06.09 PM.png 106 KB

Logs now support ANSI colors

Improvement

Hatchbox now supports ANSI color codes in logs. This makes spotting important information like errors or statuses much easier!

Screenshot 2026-07-22 at 10.23.34 AM.png
Hatchbox Logs with ANSI colors

The Hatchbox API has a new, simpler structure

Improvement

We've reorganized the Hatchbox API around your apps directly. Endpoints that previously required an account ID in the URL — like /api/v1/accounts/:account_id/apps/:app_id/domains — now live at /api/v1/apps/:app_id/domains.

Since your API token already identifies you and your app ID is unique, the account ID was redundant. Along the way we've filled in some gaps: you can now list your apps, list and inspect your processes, and read individual domains. Check out the API documentation for the full reference.

The old account-scoped endpoints still work, so nothing you've built will break today. That said, they're now deprecated and we'd encourage you to move over when you get a chance — the new endpoints are a straight swap in most cases, just drop the /accounts/:account_id segments. We'll give you plenty of notice before anything is turned off.

Better On Demand TLS support for custom domains on Load Balanced clusters

Improvement

Some applications need to respond to custom domains with SSL. Users specify the domains they want to use in your application and configure their DNS to point to your domain with a CNAME record.

Hatchbox supports this with On Demand TLS and asks your application for permission to generate an SSL certificate when a request hits the server with an unknown domain.

Previously, you could set a URL in Hatchbox for these SSL domain permission requests. This endpoint is checked during the initial HTTP request from the user, so they need to execute quickly.

One issue with our old configuration was these requests had no way of setting headers. In a load balanced cluster, a request to an upstream web server for this endpoint wouldn't be able route to the correct application because it couldn't set a Host header. The upstreams would also try to redirect to SSL because there was no X-Forwarded-Proto header.

We've refactored our configuration to solve these problems and make it easier to configure.

To configure On Demand TLS for your Hatchbox cluster now, it's 3 easy steps:

  1. Set the default application for the cluster. This application responds when a request to an unknown domain is received (like customer-domain.com).
  2. Set the On Demand TLS app. This is where SSL permission requests are sent. You can have multiple apps in the cluster, so you'll have to choose one to handle these requests. Typically, it's the same as the default application.
  3. Choose a path to send On Demand TLS requests. Something like /check-domain that responds with a 200 OK to approve or a 422 to deny.

That's it! Everything stays within the internal network allowing you to respond lighting fast to these requests, providing a seamless SSL experience for applications that support custom domains.

DigitalOcean Server Tags

New

Servers on DigitalOcean will now be tagged with the cluster slug and roles. You can use these tags to automatically add servers as Trusted Sources with DigitalOcean Managed Databases. When a server is tagged or untagged, the database's firewall rules will be updated seamlessly.

Screenshot 2026-07-15 at 9.27.54 AM.png
Example server tags on DigitalOcean

Ruby 4.0.6

New

Ruby 4.0.6 is now precompiled and ready to use on Hatchbox. This is a regular bugfix release that includes quite a few fixes. See the GitHub release for more details.

Download the latest database backup directly from Hatchbox

New

Navigating cloud storage to download a copy of your latest database backup can be a pain. You can now download the latest database backup directly from Hatchbox! 🎉

For existing databases, re-configure backups to enable this feature. This will update the backup script to send the remote storage location when it notifies Hatchbox of a successful backup and will add a Download button to your database in the UI.

This is currently supported for Amazon S3 and S3-compatible backups. We'll be adding support for the rest of our backup storage providers in the coming days.

Shoutout to Neil for suggesting this feature!

Better static site errors

Improvement

Static sites now properly render 404 errors when deployed with Hatchbox. 🎉

Previously, accessing invalid URLs on a static site would return 502 errors. If Caddy couldn't find a matching file on disk, it would forward the request to the reverse proxy. Since static sites don't have a process to listen for HTTP requests, Caddy returns a 502 error since it didn't get a response from an upstream server.

We've adjusted our Caddy configuration to only include the reverse proxy when there is a process with the "web" role. Caddy now renders 404s because it doesn't have an upstream to check.

Error handling is also adjusted for static sites so to render 404.html if present.

Better load balancer health checks and retries

Improvement

We've updated our load balancer configurations with several improvements to provide your users a better experience.

Least Connections Policy

We've changed the default load balancer policy to use a least connection policy instead of random. Requests will now be forwarded to the least busy upstream server which works well with unpredictable traffic. This should be an improvement from Caddy's default random policy.

Of course, you can always choose a specific load balancer policy in your cluster settings if you'd prefer a different strategy.

Retries on by default

Previously, load balancers would retry a request only if active health checks were enabled. Retries are now always enabled.

Passive health checks

We've also introduced passive health checks. When a request is forwarded to an upstream server and fails, the upstream is marked as unhealthy. Combined with active health checks, you can ensure that requests are only forwarded to healthy upstreams.

Combined with retries, requests will be sent to the next healthy server to help ensure users don't see errors.

Try it out

Update your load balancer servers to update to the latest configuration.

For more details on how load balancers are configured in Hatchbox, see our load balancer documentation.