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/detailsas an administrator. If theapplication-databasevalue is notpostgresormysql, 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 themetabase.db.mv.dbfile; 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, eitherMB_DB_CONNECTION_URIor the separateMB_DB_HOST,MB_DB_PORT,MB_DB_DBNAME,MB_DB_USERandMB_DB_PASSvariables. 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.
- 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.
- Confirm connectivity. From the host that will run the migration, confirm it can reach the target PostgreSQL database with the Metabase role.
- Announce a change window and stop Metabase. The guide says to shut Metabase down so that nobody creates content during the migration.
- Back up the H2 file. Copy
metabase.db.mv.dbto safe storage. This copy is your rollback point. - Run the migration. With
MB_DB_TYPE=postgresand the connection settings exported, run the same-version JAR with theload-from-h2command and the path to the H2 file without the.mv.dbextension. For Docker, the guide runs this as a one-off job with the same-version JAR, and Metabase exits when the load is complete. - Start Metabase on PostgreSQL. Start Metabase with the PostgreSQL settings and without
load-from-h2. For Docker, start a new container with theMB_DB_*variables, then remove the old container once you are satisfied. - 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.
- 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 downcommand 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
- Migrating from H2
- Configuring the Metabase application database
- Backing up Metabase application data
- Upgrading Metabase
- Encrypting your database connection
- Metabase version support
- Metabase license
- How to run Metabase at scale
- metabase/metabase releases
- metabase/metabase LICENSE.txt
Related pages
More insights
Comparisons & Decisions
Moving a PostgreSQL Application to YugabyteDB: Compatibility Testing and Migration Planning
YSQL reuses the PostgreSQL query layer, but it is not a drop-in replacement. How to test compatibility, redesign the schema and choose a migration route.
PostgreSQLYugabyteDB
Architecture Patterns
YugabyteDB Multi-Region Topologies: Synchronous Replication, xCluster or Read Replicas
Synchronous replication, geo-partitioning, xCluster and read replicas solve different problems. What each does, what it costs and how to choose.
YugabyteDB
Operations & Reliability
YugabyteDB LTS and STS Releases: Upgrade Planning and the PostgreSQL 15 Path
v2024.2, the last PostgreSQL 11-based LTS series, leaves maintenance in December 2026. How to choose a target series and plan the YSQL major upgrade.
YugabyteDB
Read article : YugabyteDB LTS and STS Releases: Upgrade Planning and the PostgreSQL 15 Path→
Discuss This With an Architect
Map these trade-offs against your workloads, constraints and operating model.
