How do you manage databases in development, test, and production?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Databases should be managed differently in development, test, and production because each environment has a different goal. Development optimizes for speed, test optimizes for repeatability, and production optimizes for safety and uptime. Strong teams keep one migration workflow across all environments while changing data, access, and operational controls by stage.
Keep the Environment Roles Separate
A simple model helps avoid dangerous shortcuts:
- development for fast local iteration
- test for deterministic validation
- production for integrity, availability, and recovery
What should not happen is equally important. Production credentials should not be reused in lower environments, and raw sensitive production data should not casually appear in dev or test.
That boundary discipline prevents many avoidable incidents before they start.
Use Migration-First Schema Management
Manual schema edits drift quickly. A safer pattern is to treat migrations as the single source of truth for schema changes in every environment.
Example SQL migration:
The same ordered migration sequence should run in development, test, and production. If a migration is unsafe for production, redesign it before merge instead of treating production as a special manual exception.
Optimize Development for Fast Resets
Developers need quick setup and fast reset loops. A common local workflow is:
- start a disposable database container
- apply migrations automatically
- load deterministic seed data
- reset quickly when schema changes
Example local Compose service:
Seed scripts should be idempotent so developers can rerun them without having to guess which state the database is already in.
Make Test Environments Repeatable
Test databases should look as much like production as possible in schema, constraints, and migration order. Otherwise a green test suite can still hide deploy-time failures.
A practical CI sequence is:
Good test database practices include:
- ephemeral databases per CI run when possible
- migrations applied from scratch
- small deterministic fixtures
- anonymized realistic datasets for integration tests
The goal is confidence, not convenience.
Treat Production as an Operations System
Production database management needs controls that lower environments do not require at the same level.
Important production practices include:
- least-privilege roles for apps and operators
- automated backups
- tested restore procedures
- monitoring for performance and capacity
- change windows for risky operations
Backups are only half the story. If restore has never been tested, the backup strategy is incomplete.
Use Backward-Compatible Deployment Patterns
Application deployments and schema changes should not assume the old and new versions switch simultaneously. Safer database rollout patterns are usually:
- expand schema first
- deploy app code that handles old and new schema shapes
- backfill data if needed
- switch reads or writes fully
- remove the old schema path later
That reduces the chance that a rolling deploy breaks because part of the fleet expects a schema shape that is not there yet.
Protect Data Privacy Across Environments
Lower environments should not become a dumping ground for raw production data. Use one of these instead:
- synthetic data
- masked snapshots
- carefully scoped anonymized extracts
Even in non-production, access rules still matter. Relaxing everything in dev and test often creates security drift that later leaks into production practices.
Assign Ownership and Observability
Every important database should have clear ownership. Teams should know who approves migrations, who responds to incidents, and which signals matter operationally.
Key signals include:
- connection saturation
- slow query rates
- replication lag
- deadlocks
- backup status
- restore drill success
Without those, problems are often discovered only after user-facing impact.
Common Pitfalls
The biggest pitfall is treating production schema changes as manual one-offs while development and test use migrations. That creates drift immediately.
Another common issue is letting test environments diverge so far from production that passing tests no longer predict deploy safety.
Teams also copy production data downward without proper anonymization, which turns convenience into a privacy and compliance risk.
Summary
- Use one migration-first schema workflow across development, test, and production.
- Optimize development for speed, test for repeatability, and production for safety.
- Keep strict credential and data boundaries between environments.
- Use backward-compatible rollout patterns for schema and application changes.
- Pair backups with restore drills and real monitoring so production operations are trustworthy.
Related reading
- How do you perform Django database migrations when using Docker-Compose?
- How do you query for a non-existent null attribute in DynamoDB
- How do you remove an RDS data layer from an Elastic Beanstalk environment
- How do you run a single query through mysql from the command line?
- How do you pass custom environment variable on Amazon Elastic Beanstalk AWS EBS?
- How do you put your source code into Kubernetes?
- How do you test that a Python function throws an exception?
- How do you test that a Python function throws an exception?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.