GenerateRealData makes test data for whole databases, not single tables. You give it your schema, and it gives back related tables where every foreign key points at a real row, totals add up across tables, dates come in order and your business rules hold on every row. Up to 500,000 rows in one run, as SQL, CSV, Excel or JSON.

I built it because every other way I tried broke the moment the data spanned more than a couple of tables. Here's what it does, how it works, and where it still falls short.

What it does, on a real schema

Take an ordinary shop:

CREATE TABLE customers (id INT PRIMARY KEY, name TEXT, country TEXT); CREATE TABLE orders (id INT PRIMARY KEY, customer_id INT REFERENCES customers(id), status TEXT, ordered_at TIMESTAMP, total NUMERIC(10,2)); CREATE TABLE order_items (id INT PRIMARY KEY, order_id INT REFERENCES orders(id), quantity INT, unit_price NUMERIC(10,2), line_total NUMERIC(10,2)); CREATE TABLE shipments (id INT PRIMARY KEY, order_id INT REFERENCES orders(id), shipped_at TIMESTAMP, delivered_at TIMESTAMP); 

Real data from this shop always follows rules the database doesn't enforce:

  1. line_total = quantity * unit_price
  2. An order's total is the sum of its line totals.
  3. ordered_at <= shipped_at <= delivered_at
  4. A cancelled order has no shipment.

You upload the file, add those rules in plain English (it also infers common ones from the column names), and generate. Then you can prove the rules hold with one SQL query per rule, each counting the rows that break it:

-- Rule 2: order totals match their items SELECT COUNT(*) FROM orders o WHERE o.total <> (SELECT SUM(line_total) FROM order_items i WHERE i.order_id = o.id); -- Rule 4: cancelled orders never ship SELECT COUNT(*) FROM orders o JOIN shipments s ON s.order_id = o.id WHERE o.status = 'cancelled'; 

Checks like these are how I hold the engine to it. Across the 15 databases I've published, there are 401 of them, and every one returns 0.

How it works

The job is split in two.

1. Plan once with AI. You upload CREATE TABLE statements (PostgreSQL, MySQL, SQL Server or SQLite) or describe the database in plain English. An AI model reads it once and writes a plan: which column references which table, which values are copied from a parent row, which columns are calculated, and which rules must hold. The plan is saved, so you can run it again whenever you like.

Uploading a CREATE TABLE file: only the structure is read, and INSERT rows are stripped before processing

2. Generate with an engine. A statistical engine produces the rows from that plan, with no AI calls in the loop (unless you turn on AI-written text fields). Because it's ordinary code following a plan:

  • Parent tables are generated first, so every foreign key resolves. If two tables reference each other, like departments and employees, the engine breaks the cycle by filling one key after both tables exist.
  • Rules hold on every row, however many rows you ask for.
  • The same seed gives the same dataset, so a failing test can be reproduced.
  • The SQL file loads in one go. It creates the tables, inserts the data and adds the foreign keys at the end, so even tables that reference each other load cleanly.

What else is in it

  • 232 data types and 222 built-in generators, one of the largest libraries of any test data generator: real airport and ICD-10 codes, IBANs and card numbers with valid check digits, cities that match their country and postcode. Amounts follow realistic distributions instead of flat random ranges.
  • Time series with one series per entity, each with a trend, seasonality, noise and occasional shocks.
  • Bad data on purpose, if you want it. An optional anomaly rate plants defects for testing validation and cleaning code.
  • AI-written text that matches each row, such as a review that fits its rating and product. Every plan, including the trial, comes with an allowance of AI-written fields.
  • A REST API on the paid plans, so test pipelines can generate data themselves.

Why not the usual ways?

Keys: every foreign key resolves. Totals: sums agree across tables. Needs prod: you need production data to start.

Keys Totals Rules Scale Needs prod Repeatable
Faker script Hand-code Hand-code Hand-code Yes No Seed
LLM INSERTs Often no Often no Mostly No No No
Prod copy Yes Yes Yes Yes Yes Snapshot
GenerateRealData Yes Yes Yes 500k/run No Seed
  • Faker-style scripts generate each column on its own. Making totals add up and dates line up means writing that logic yourself, table by table, and changing it whenever the schema changes.
  • LLM-written INSERTs look great for a few dozen rows. At thousands they hit output limits, keys start pointing at rows that don't exist, sums drift, and you get different data every time.
  • Masked production copies are the most realistic, when you have production data and time for a privacy review. For a new feature or a new schema, there's nothing to copy.

Where it falls short

  • 500,000 rows per run. Bigger datasets have to be generated in parts.
  • Designing big schemas takes time. A schema with hundreds of columns can take around four minutes to plan. Generating rows afterwards is much faster.
  • Undeclared keys get inferred. If your CREATE TABLE file declares no foreign keys, the AI works out the links from names and types. Check them before you rely on them.
  • It's paid. The 7-day trial needs no card. After that, a 30-day pass is $12 for 100,000 records or $39 for 500,000, with no auto-renewal.

See the output without signing up

I'd like to hear which rules your test data keeps getting wrong, and where your current approach breaks. Those are the cases I want the engine to handle next.