Skip to main content

Bassirah Technology

Operations & Reliability

Moving Metabase From H2 to PostgreSQL: A Production Setup Runbook

Metabase stores its questions and dashboards in an application database. How to move it from H2 to PostgreSQL safely, then upgrade.

What this article covers

Self-hosted Metabase Open Source Edition, using the Metabase documentation for version 64 and the version support page, read on 26 October 2026. Pro, Enterprise and Metabase Cloud are out of scope.

Metabase is quick to start because it ships with an embedded H2 database for its own application data. That convenience becomes a risk once people rely on the questions and dashboards stored in it. The Metabase documentation says to avoid the embedded H2 application database in production and recommends PostgreSQL.

This article explains what the application database holds, how to prepare PostgreSQL for it, and how to run the documented load-from-h2 migration with a rehearsal and a rollback point. It covers the self-hosted Metabase Open Source Edition, using the Metabase documentation for version 64 and the version support page, read on 26 October 2026.

What the application database holds

Metabase keeps two kinds of data apart. Your data warehouse and other databases hold the data people query. The application database holds Metabase itself. The application database documentation says it stores information about user accounts, questions and dashboards, and that it is separate from your data warehouse.

The backup documentation is more direct: Metabase uses a single SQL database for all of its runtime application data. If that database is lost or corrupted, you lose the work your users have built, even though the data sources are untouched. The H2 migration guide warns that without a production database and regular backups, the application database can become corrupted, putting questions, dashboards and collections at risk.

That is why the choice of application database is a production decision, not a detail. A file inside a container or next to a JAR is easy to lose during a redeployment, and hard to back up consistently while Metabase is running.

Check your starting point

Before planning anything, confirm three facts about the current instance.

  • Which application database is in use. The H2 migration guide describes calling GET /api/bug-reporting/details as an administrator. If the application-database value is not postgres or mysql, the instance is on H2.
  • The exact Metabase version and edition. Metabase uses a version prefix of 0 for the Open Source Edition and 1 for the Enterprise Edition, according to the version support page. Note the full version string.
  • Where the H2 file lives. For a container, the backup guide gives the path /metabase.db/metabase.db.mv.db. For a JAR, the guide refers to the metabase.db.mv.db file; confirm where your installation keeps it.

Also check where that version sits in the lifecycle. The version support page states that every Metabase release receives bug fixes and security updates until its end-of-life date, that long-term support (LTS) releases are supported for 14 months, and that other releases usually reach end of life after two months.

Release Type End of life listed on 26 October 2026
Metabase 65 Standard (beta on GitHub) January 1, 2027
Metabase 64 LTS December 1, 2027
Metabase 63 Standard November 1, 2026
Metabase 59 to 62 Standard September 1, 2026
Metabase 58 LTS February 17, 2027

The lifecycle matters because the migration and the upgrade should be separate changes. More on that below.

Prepare the PostgreSQL application database

The application database documentation recommends PostgreSQL for production and also supports MySQL and MariaDB. The two documentation pages word the PostgreSQL version requirement differently: the H2 migration guide lists PostgreSQL 14 or later, and the configuration page refers to supported PostgreSQL versions. Choose a PostgreSQL version that is current and within the PostgreSQL community’s support window, and check it against both pages for your Metabase version.

Prepare the database with these points in mind:

  • Start empty. The migration guide says Metabase expects the command to run against a brand-new, empty database. Do not point it at a database that already holds Metabase tables.
  • Use a dedicated database and role. Give Metabase its own database and a role that owns it, and keep other applications out of it.
  • Plan backups before go-live. The backup guide says that, as long as you have a dump of the Metabase database, you can restore the instance. Schedule those dumps, or use your platform’s managed backups, and test a restore.
  • Decide how Metabase will connect. The documented settings are MB_DB_TYPE, either MB_DB_CONNECTION_URI or the separate MB_DB_HOST, MB_DB_PORT, MB_DB_DBNAME, MB_DB_USER and MB_DB_PASS variables. Keep the password in a secret store, not in a shell history or an image.

Plan the encryption key at the same time. The encryption documentation describes MB_ENCRYPTION_SECRET_KEY, which encrypts the connection details Metabase stores for each data source. The key must be at least 16 characters. If you lose or change it, you have to re-enter every connection that was encrypted with it. Existing data is encrypted once with the enable-encryption command, and keys are rotated with rotate-encryption-key. Treat the key as a production secret with its own backup.

For PostgreSQL design, operations and recovery in general, see our PostgreSQL engineering page.

A rehearsed migration runbook

The H2 migration guide describes the procedure for a JAR and for Docker. The rule that matters most is this one: you must use the same version of Metabase throughout the migration. Upgrade only after the migration has succeeded.

  1. Rehearse on a copy. Copy the H2 file to a test environment, create an empty PostgreSQL database there and run the whole procedure. Record how long it takes and what you checked.
  2. Confirm connectivity. From the host that will run the migration, confirm it can reach the target PostgreSQL database with the Metabase role.
  3. Announce a change window and stop Metabase. The guide says to shut Metabase down so that nobody creates content during the migration.
  4. Back up the H2 file. Copy metabase.db.mv.db to safe storage. This copy is your rollback point.
  5. Run the migration. With MB_DB_TYPE=postgres and the connection settings exported, run the same-version JAR with the load-from-h2 command and the path to the H2 file without the .mv.db extension. For Docker, the guide runs this as a one-off job with the same-version JAR, and Metabase exits when the load is complete.
  6. Start Metabase on PostgreSQL. Start Metabase with the PostgreSQL settings and without load-from-h2. For Docker, start a new container with the MB_DB_* variables, then remove the old container once you are satisfied.
  7. Verify. Sign in as an administrator and as a typical user. Check collections, a sample of dashboards and questions, data source connections, users and groups, and any scheduled subscriptions or alerts.
  8. Keep the H2 file. The guide recommends keeping the old H2 file for safekeeping. Retain it until the new setup has been in use and backed up for an agreed period.

If your change process requires reviewing schema changes before they are applied, the guide documents MB_DB_AUTOMIGRATE=false. With it, Metabase prints the SQL migration script and does not start until the changes have been applied manually.

The rollback for a failed migration is simple because nothing has changed in H2: stop Metabase, discard the new PostgreSQL database and start the original instance on the backed-up H2 file.

Upgrade afterwards, as a separate change

Once the instance is running on PostgreSQL and has a tested backup, plan the move to a supported release. On 26 October 2026, Metabase 64 was the newer LTS release, with end of life listed as December 1, 2027. Metabase 58 LTS remains listed until February 17, 2027.

The upgrade documentation sets out the points to plan for:

  • Back up the application database before every upgrade. The documentation treats a backup as the recommended way to roll back.
  • Migrations of the application database run automatically on startup. Do not let an orchestrator stop the process while a migration is running, or the application database may be corrupted.
  • If you run several instances, reduce to a single instance for the upgrade, then scale back. Running several nodes during a major upgrade can cause incorrect behavior.
  • A migrate down command exists for rolling back schema changes. It must be run with the JAR of the higher version. Restoring the backup is the documented first choice.
  • On a long upgrade path, use the latest minor release of each major release along the way.

The version support page also says Metabase does not recommend mutable .x image tags in production. Pin an exact version, so every instance and every redeployment runs the same code.

Scaling out once the application database is separate

A separate application database also opens the way to more than one Metabase instance. The Metabase guide on running Metabase at scale describes horizontal scaling as several instances connected to the same application database, with a load balancer in front. It says Metabase is set up for horizontal scaling out of the box, that load balancers can check /api/health, and that horizontal scaling requires an application database on a separate server.

Keep every instance on the same pinned version, and remember the single-instance rule during major upgrades.

Keep the editions distinct

This runbook applies to the Open Source Edition. The Metabase license page says the Open Source Edition is offered under the AGPL, and that Enterprise Edition binaries are released under the Metabase Commercial Software License. Enterprise features cannot be used without a commercial license. The repository’s license file separates the binaries too: the metabase/metabase image is the AGPL build, and metabase/metabase-enterprise is the commercially licensed build.

Keep the edition unchanged during the migration, and treat any later move to Pro, Enterprise or Metabase Cloud as its own decision, made with Metabase, Inc.

How Bassirah can help

Bassirah provides independent engineering for self-hosted Metabase Open Source Edition. We can rehearse and run the move from H2 to PostgreSQL, set up backups and the encryption key, and plan the following upgrade onto an LTS release. Bassirah is not a Metabase, Inc. partner and does not provide vendor support or Pro and Enterprise features; fixes arrive in Metabase releases, as described in our open-source support model. See our Metabase engineering page for scope.

Independent engineering services

These are independent Bassirah engineering and support offerings. They do not imply upstream vendor or foundation endorsement, official vendor support rights, enterprise feature entitlement or maintenance guarantees.

Sources

  1. Migrating from H2
  2. Configuring the Metabase application database
  3. Backing up Metabase application data
  4. Upgrading Metabase
  5. Encrypting your database connection
  6. Metabase version support
  7. Metabase license
  8. How to run Metabase at scale
  9. metabase/metabase releases
  10. metabase/metabase LICENSE.txt

bassirah

Related pages

More insights

Discuss This With an Architect

Map these trade-offs against your workloads, constraints and operating model.

Talk to an Expert