

Which database strategy should you use for preview environments?
Which database strategy should you use for preview environments?
- Isolated fork per PR: Best for schema changes, migrations, and production-like testing.
- Copy-on-write branching: Best for fast, isolated database previews with lower storage overhead.
- Shared database: Best for simple previews that do not modify the schema or shared data.
- Seeded database: Best for clean, reproducible previews that do not need production data.
Northflank is a runtime platform for applications that lets you create isolated preview environments with their own databases. This makes it easier to test database changes and migrations without affecting other environments. You can also deploy it in your own cloud with BYOC when you need more control over your infrastructure and data. Get started with Northflank or book a demo.
Preview environments without databases are only half a test. You can spin up an isolated application, give it a live URL, and validate the UI, but if it shares a database with other pull requests, the results may not reflect what the application will actually encounter in production.
The database strategy is where preview environments get more complicated. Databases carry state, so every approach involves a tradeoff between isolation, cost, migration safety, and how closely the preview reflects production.
A database strategy defines how each preview environment gets its database, what state that database starts in, and what happens to it when the environment is torn down.
For stateless services, this is straightforward: clone the service configuration, point it at the new environment, and you're done. Databases are different because they carry state. Your strategy determines whether one PR's database changes can affect other previews, whether migrations run against realistic data or an empty schema, how much your preview environments cost as PR volume grows, and whether sensitive data ends up in a test environment.
A service is configuration. A database is configuration plus data. That distinction drives every tradeoff in preview environment database strategy.
- The state problem: When two PRs share a database, any change one makes is visible to the other. A migration run by PR-A changes the schema that PR-B is testing against. A seed script run by PR-A inserts rows that PR-B's tests did not expect. The more PRs are open simultaneously, the worse this interference becomes.
- The migration problem: Schema migrations are one of the most important things to validate in a preview environment. A migration against an empty database does not reveal how it behaves with existing production-like data, while a migration against shared staging can affect other previews. An isolated copy of realistic data provides a safer way to test these changes.
- The data residency problem: Using production data in preview environments creates compliance exposure. GDPR, HIPAA, and PCI DSS all have implications for where customer data can be processed and who can access it. A preview environment that pulls from a production backup and is accessible to a contractor reviewing a PR is a compliance event waiting to happen.
- The cost problem: Full isolation, one database per PR, is the safest strategy. It is also the most expensive. At ten engineers with three open PRs each, you are running thirty concurrent database instances. The cost of doing this right has to be managed deliberately.
The best database strategy depends on the type of changes you need to test and how closely your preview should reflect production. The four most common approaches are isolated database forks, copy-on-write branching, shared databases, and empty databases with seed data.
Every pull request gets its own database instance, created when the PR opens and removed when it merges or closes. The database can be forked from a backup of your staging or production database, giving the preview a realistic starting state.
How it works: When a PR is opened, the preview platform creates a new database from an existing backup, runs any pending migrations on the isolated database, and connects it to the preview environment. When the PR closes, the database is removed.
Why it works: Each PR has its own database, so changes cannot affect other previews or staging. Migrations can be tested against realistic data, while application and test data remain isolated between environments.
The tradeoffs: The main constraint is cost. Each PR requires its own database instance, so costs increase with the number of concurrent previews. Automatic teardown, idle detection, and TTL rules can help control resource usage.
Best for: PRs that change the database schema, applications that need strong data isolation, and teams that want to test migrations against realistic data.
Copy-on-write branching creates an isolated database branch without immediately duplicating all of the parent's underlying data. Changes made by the branch are stored separately, reducing the storage required for multiple database environments.
How it works: A database branch is created from a parent database, typically staging or development. The branch starts with the parent's data and schema, while subsequent changes are isolated to the branch.
Why it works: Branches can be created quickly and use less storage than independent database instances, making this approach useful when you need many concurrent preview environments.
The constraint: Database branching depends on capabilities provided by the database platform. PostgreSQL platforms such as Neon provide copy-on-write branching, while other database types may require separate instances or different cloning strategies.
Best for: Teams that use a database with native branching support and need fast, isolated previews without provisioning a full database instance for every PR.
All preview environments connect to the same database, typically a shared staging database. No separate database is created for each PR.
Why teams use it: It is the simplest and cheapest option. It can work well when previews mainly test frontend or application changes that do not modify the database schema.
Why it breaks down: A migration from one PR changes the schema that every other preview is using. Changes to shared data can also affect tests and application behaviour in other environments, making previews less predictable as the number of concurrent PRs grows.
Making it safer: Separate database schemas or PR-specific test data can reduce some conflicts, but these approaches add complexity and do not provide the same isolation as separate databases.
Best for: Small teams, stable schemas, and preview environments where database changes are uncommon.
Each preview gets a fresh database populated with a known dataset when the environment starts. The seed data provides the minimum state required to run and test the application.
Why it works: Every preview starts from a predictable state without copying data from another environment. This makes tests reproducible and avoids depending on whatever data happens to exist in staging.
The limitations: Seed data may not reflect the volume or edge cases found in production. Maintaining seed scripts also becomes more difficult as the application's schema and data relationships evolve.
Best for: Test-driven workflows, applications with simple data models, and teams that need deterministic preview data without copying production or staging data.
The right strategy depends on what the PR changes, how much database isolation you need, and whether the data can be used in preview environments.
- If the PR changes the schema or database logic: use an isolated fork or copy-on-write branch. Both give the PR its own database, so migrations and database changes cannot affect other previews. Forks are a better fit when you need multiple database types or closer production parity.
- If the PR is frontend-only or does not change the database: a shared staging database may be enough. Per-PR isolation adds cost and complexity when the application is not changing its database behaviour.
- If you handle regulated or sensitive data: sanitise the source data before using it in preview environments. A common approach is to create a sanitised staging snapshot and use it as the source for database forks or branches.
- If you use PostgreSQL and want lower-cost isolation: copy-on-write branching can create isolated databases without duplicating the entire dataset. This can be a good option for teams with many concurrent previews, although it depends on database platforms that support branching.
- If your application uses multiple database types: consider how each database will be isolated. Forking PostgreSQL while sharing Redis, for example, still leaves session, cache, or queue state shared between previews.
Northflank is a runtime platform for applications that lets you provision isolated databases alongside each preview environment, so the application, database, and supporting services can be created and removed together.
- Database forking: When a preview environment is created, its database can be forked from an existing database snapshot rather than sharing the staging database. This gives each preview its own database instance, so migrations and test data stay isolated from other environments.
- Preview blueprints: You can define the application services, databases, configuration, and other resources in a reusable blueprint. When a PR creates a preview environment, the required resources are provisioned together and can be torn down when the preview is no longer needed.
- Teardown scheduling: Preview environments can be configured to shut down during periods when they are not needed, such as nights and weekends. This helps reduce the resources running for inactive previews without requiring developers to delete them.
- Cost controls: Teams can also use lifecycle policies such as automatic teardown after a defined period to prevent abandoned preview environments and their databases from running indefinitely. This becomes particularly useful as the number of concurrent PRs grows.
- Multiple database types: Northflank supports PostgreSQL, MySQL, MongoDB, Redis, MinIO, RabbitMQ, and more, allowing the database layer to be included alongside the rest of the preview environment.
- BYOC: If you need to keep preview infrastructure in your own cloud, Northflank's BYOC model lets you deploy the environment into your own AWS, GCP, Azure, or on-premises infrastructure.
Build preview environments directly from AI coding workflows
Northflank can also be used from AI coding workflows to provision preview environments while you build. This lets an AI coding agent create the application environment, provision the required database, and deploy the changes without requiring you to manually configure the infrastructure for each preview.
This is particularly useful for AI-generated applications, where each coding session can produce a working environment with its own application services and database for testing.
The right approach depends on what the PR changes, how much isolation you need, and what data you can safely use in preview environments. Shared databases work for simple changes, seeded databases provide predictable test data, and isolated forks provide stronger production parity. Copy-on-write branching can offer a lower-cost alternative when your database supports it. For teams that need isolated databases alongside application services, CI/CD, and infrastructure, Northflank provides the tooling to manage the entire preview environment together.
Database forking creates a new database instance from an existing database snapshot. The fork starts with the same data and schema as the source but remains isolated, so changes do not affect the original database. In preview environments, this gives each PR its own database for testing migrations and data changes.
Forking creates a separate database instance from a backup or snapshot. Database branching uses copy-on-write storage to create an isolated database without duplicating the underlying data. Branching can be faster and more storage-efficient, while forking can work across a wider range of database types.
Yes. An isolated database lets each PR run migrations without affecting other previews or staging. Forking from staging also lets you test migrations against realistic data rather than an empty database.
It depends on the strategy. Shared databases have no additional per-PR database cost, while isolated databases add cost for each active preview. Scheduling previews to shut down when they are not needed can help reduce those costs. Northflank pricing calculator can help estimate the cost based on your database type and size.
Isolated databases are generally the safest option. Each PR gets its own data, so changes and test data from one preview cannot interfere with another tenant or environment.
Do not use production data directly. Sanitise sensitive data first, then use the sanitised dataset as the source for preview databases. This preserves realistic data shapes while reducing the risk of exposing customer information in development and preview environments.


