Why You Shouldn't Copy Production Data Into Test Environments (and What to Use Instead)
The risks of using real customer data in development and testing, the main alternatives (masking, subsetting, synthetic data), and reserved domains, phone numbers and IP ranges that are safe to put in test data.
Copying the production database into a dev or staging environment is fast and gives realistic data. It is also one of the most common ways personal data leaks. This guide covers why it's risky, what the alternatives are, and a few reserved values that make test data safe by design.
Why production copies are risky
Test environments are less protected. They often have weaker access controls, shared passwords, debug logging, and more people with access, including contractors and tools.
Copies spread. A database dump ends up on laptops, in CI caches, in bug reports and in screenshots. Each copy is another place the data can leak from.
Privacy rules apply to copies too. Many privacy laws, such as the EU's GDPR, expect personal data to be used only for the purposes it was collected for and kept to a minimum. Using customers' real records for testing can be hard to justify.
Real data can trigger real actions. A test job that sends emails, texts or webhooks to real addresses can reach real customers.
The alternatives
Approach
What it is
Good for
Watch out for
Masking / anonymizing
Replace names, emails etc. in a copy of production
Keeping real-world distributions
Re-identification from what's left (rare values, free-text fields, combinations of fields)
Subsetting
Take a small, masked slice of production
Smaller, faster test databases
Broken foreign keys if the slice isn't consistent
Synthetic data
Generate data that never belonged to anyone
Demos, CI, tutorials, sharing with vendors
Must be consistent and realistic enough to catch real bugs
For most development, demos and automated tests, synthetic data is the simplest choice because there is no personal data to protect in the first place.
What makes synthetic data useful
Random strings in every column aren't enough. Useful test data:
Has consistent relationships: every order points to a real customer, and every line belongs to an order.
Adds up: totals equal the sum of their lines, and payments match invoices.
Respects time: nothing ships before it is ordered, and nobody is paid before their hire date.
Includes edge cases: refunds, cancellations, failed payments, empty optional fields, long names and non-ASCII characters.
Comes in two sizes: a small set for unit tests and screenshots, and a larger one for performance and pagination.
Reserved values that are safe to use
These are set aside by standards bodies precisely so they can't reach a real person or system:
Email domains: example.com, example.net and example.org are reserved for documentation and examples (RFC 2606). The .test and .example top-level domains are reserved too.
Phone numbers (North America): 555-0100 through 555-0199 are set aside for fictional use.
IP addresses: 192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24 are reserved for documentation (RFC 5737); 2001:db8::/32 for IPv6 (RFC 3849).
Payment cards: use the test card numbers published by your payment provider for its test mode. Never put real card numbers in test data.
A quick checklist
No real names, emails, phone numbers, addresses, government IDs or card numbers in non-production environments.
Outgoing email, SMS and webhooks disabled or pointed at a sandbox in test environments.
Seed data versioned in the repo and generated from a fixed seed, so every run is reproducible.
Consistency checks (sums, foreign keys, date order) run against the seed data in CI.
If you must use masked production data, document who approved it, where it lives and when it gets deleted.
Customers, products, orders, payments, shipments and returns that add up: a realistic, fully synthetic e-commerce database for dev, demos and SQL practice.
Employees, managers, salary history, benefits, pay periods, payslips, time off and reviews that add up: a fully synthetic HR database for dev, demos and SQL practice.
Shipments, packages, carriers, service levels and tracking events that add up: a fully synthetic shipping database for dev, demos, dashboards and SQL practice.