To scale test data volume synthetically, you de-identify a production baseline and then generate additional records modeled on it until you reach the volume you need — multiplying row counts while preserving referential integrity and keeping sensitive data out of lower environments. Masking and subsetting produce a safe baseline; synthetic generation adds realistic new rows on top of it. This is how teams reach the high volumes that load, performance, and parallel-environment testing require but production alone can't safely provide.
Why production data runs out for load and performance testing
Production databases hold a fixed number of rows — however many real customers, orders, or events a business has actually accumulated — and that ceiling is often far below what a serious test needs. Functional tests are usually fine with a copy of production, but load testing and performance testing are a different problem: they exist to push a system past its normal operating point, which means they need many multiples of the data production currently holds. A checkout flow that behaves against ten thousand orders can still fall over at ten million, and you can't find the breaking point with a dataset that never reaches it.
The obvious move — copy production and run against that — fails on two counts. It carries real customer data into lower environments, which is a privacy and compliance exposure most teams can't accept, and even after you strip the sensitive fields it's still capped at production volume. Copying gives you a safe-ish replica of what you already have; it doesn't give you more.
The next instinct is to manufacture the extra rows by hand, and this is where most homegrown approaches break. Hand-written insert scripts and naive row duplication ignore the relationships between tables: duplicate an orders row with no matching customer and the foreign key dangles, or clone the same customer ten thousand times and you flatten the distributions a query planner and a cache actually respond to. The result looks like volume but behaves nothing like production under pressure. Getting past that ceiling safely is a core problem of test data management, and synthetic scaling is the approach built to solve it.
Production alone falls short for high-volume testing in a few specific ways:
- Fixed ceiling — you can't load test against volumes your business hasn't reached yet.
- Unsafe to copy — production carries PII and PHI that shouldn't move into test environments.
- Still capped — a masked production copy is safe, but no larger than production.
- Naive duplication breaks — hand-built inserts and row cloning distort distributions and dangle foreign keys.
The two-step pattern: de-identify a baseline, then synthetically scale it
The reliable way to scale test data volume synthetically is a two-step pattern, and the order is the whole point. You first turn a slice of production into a safe, realistic baseline, then generate new records modeled on that baseline until you reach the volume you need. Keeping the steps in that order is what lets you multiply rows without ever letting sensitive data into the environment where the scaling happens.
- De-identify and shape the baseline with Tonic Structural. Structural connects to a production database, applies masking and de-identification to the sensitive fields, and can subset the result down to a representative slice. What comes out is a dataset that keeps production's structure and relationships but contains no real personal data — the safe foundation everything else is built on.
- Generate additional records with Tonic Fabricate. Point Fabricate at the de-identified baseline and it models the schema, the value patterns, and the cross-table distributions, then produces new synthetic records in the same shape. You decide how many, so a baseline of a few hundred thousand rows becomes the tens of millions a load test demands.
The sequence matters because it is the guarantee about sensitive data. Structural does its de-identification first, so Fabricate only ever sees data that is already safe — there is no path by which real PII gets reintroduced during the scale-up. It also reflects a real division of labor between the two products. Fabricate generates data; it has no subsetting or production-masking step of its own, so it does not stand in for Structural in test data management. Structural produces the trustworthy baseline, and Fabricate multiplies it. Used together this way, they turn a fixed production dataset into synthetic test data at whatever volume the work requires.
Keeping referential integrity intact as you scale
The hard part of multiplying rows isn't producing them — it's keeping them coherent. Referential integrity is the property that the relationships between tables stay valid: every foreign key points at a row that actually exists, and the connected records tell a consistent story. An order belongs to a real customer, that customer has a real address, and the line items reference products that are really in the catalog. Break that, and your test data fails in ways that have nothing to do with the code you are trying to test.
Naive duplication breaks referential integrity almost immediately. Copy a row without its parents and you get orphaned records; copy a key that is supposed to be unique and you get collisions; clone the same subtree repeatedly and the join cardinalities stop resembling production. Modeling on a de-identified baseline avoids all of this, because the generator learns the relationships rather than blindly copying rows. If the baseline shows customers with anywhere from one to fifty orders each, the generated data reproduces that spread instead of stamping out identical clones, so the ratios your queries and indexes depend on survive the scale-up. Tonic Fabricate maintains referential integrity as it generates, and it holds that integrity across multiple databases and file formats at once, so the same entities and IDs line up wherever they appear — not just within a single table. Tonic Structural preserves those same relationships through its masking and subsetting, which is why the baseline it hands off is already coherent before a single new row is generated.
The Tonic Advantage: the baseline carries the integrity forward. Because Structural produces a de-identified baseline with its foreign keys and cross-table relationships intact, Fabricate has a coherent model to generate from. Every synthetic row it adds inherits that structure, so a dataset scaled from a few hundred thousand rows to tens of millions stays as referentially sound at the top end as the baseline was at the start. The integrity is not re-derived at scale — it is preserved from the baseline and extended.
Synthetic scaling vs. subsetting, cloning, and masked copies
Synthetic scale-up is one of several ways to produce test data, and some of the alternatives solve the opposite problem. Tonic Structural provides two of these approaches directly — the de-identified baseline and subsetting.
Subsetting scales data down, not up. Its job is to take a large production database and produce a smaller, referentially intact slice — the opposite of what you need for load testing, but exactly right when you want a lightweight isolated environment or you're cutting storage and cost. Structural's patented subsetter shrinks petabytes down to gigabytes without breaking foreign keys, which is what keeps the smaller copy usable rather than a pile of orphaned rows. Subsetting and synthetic scaling are complementary: you subset to get small and isolated, you generate to get large.
A full masked production copy is safe to use but stays capped at production volume, and moving a complete database into every lower environment is heavy and slow — the storage footprint and refresh windows that are merely inconvenient for one environment multiply with every team that needs its own copy. Naive duplication — cloning rows to inflate counts — gets you a bigger number but destroys the distributions and relationships that make a load test meaningful. Choosing synthetic data for testing over masked production copies is the approach that clears the volume ceiling while keeping the data coherent, and pairing it with subsetting lets you move volume in either direction from the same safe baseline.
| Approach | Volume direction | Referential integrity | Safe for lower environments |
|---|---|---|---|
| Synthetic scale-up (Structural baseline + Fabricate) | Up — beyond production | Preserved — modeled from the baseline | Yes — no real PII in the generated data |
| Subsetting (Structural) | Down — a representative slice | Preserved — foreign keys followed out | Yes — de-identified in the same pass |
| Masked production copy | Flat — capped at production | Preserved | Yes, but heavy to move |
| Naive duplication / insert scripts | Up | Broken — orphans and collisions | Depends on source; distorts distributions |
Provisioning scaled data across parallel environments and pipelines
Generating volume on demand changes how teams provision test environments, not just how much data they hold. Once high-volume datasets can be produced from a safe baseline whenever they are needed, you stop rationing a single shared environment and start giving each team, branch, or pipeline its own. Tonic Fabricate operationalizes the generation step through automated workflows and mock APIs, so producing a fresh, correctly sized dataset becomes something a CI/CD pipeline does on its own rather than a ticket someone files. A workflow defined once can be re-run at any volume, which is what makes parallel isolated environments practical: no two teams collide over the same fixtures, and each environment is refreshed on its own schedule.
That model scales to real organizations. Flexport generates targeted test datasets multiple times daily for more than 30 teams while meeting its global privacy obligations and SOC 2 requirements — a working example of on-demand provisioning across many teams without loosening the controls on sensitive data. Safe self-service provisioning at that cadence becomes achievable when data generation is automated rather than manual.
The operational payoff lands hardest exactly where the volume problem started. Load and performance testing need large, disposable datasets on a schedule, and integration and parallel-feature work need many coherent copies at once. When generation is wired into the pipeline, all of it becomes data that the testing and QA workflow requests and gets, sized to the job, with sensitive data kept out of every environment it touches.