Comparison

Why not just ask an AI for test data?

It is a fair question — a model will happily produce a hundred Polish-looking PESELs in seconds. The problem is what those numbers are: plausible digits, not valid ones. This page is the honest comparison, including where asking a model is the better answer.

Side by side

Generating a thousand records of national identifiers, addresses and people — the everyday test-fixture job.

Asking an LLMReal Fake Data
Checksum validityDigits that look right; the check digit is not computed, so most fail a real validatorComputed per country — the number passes the same validator your app uses
ReproducibilityA prompt is not a seed; the same request returns different dataThe same seed returns the same record, byte for byte
Cost per 1,000 records$0.18–$0.88 depending on the modelUnder one cent
LatencyGenerates every character of every recordOne request; nothing is written token by token
Deliberately invalid dataHard to ask for precisely — "wrong but only in the check digit" is a fiddly prompt`invalid=true` breaks the checksum and leaves everything else intact
Real geography and registersPlausible city and street names, not necessarily ones that exist togetherDrawn from the national registers themselves
Unstructured or novel dataWrites convincing prose, product copy, support tickets, anything you can describeOnly what a generator exists for
SetupNone — you are already talking to itAn HTTP call, or one of the addons

The part that actually matters: checksums

A PESEL, a Danish CPR, an Italian codice fiscale, an IBAN — each carries a check digit derived arithmetically from the digits before it. That is the whole point: a typo fails the check.

A language model writes the number as text. It has seen millions of them, so the *shape* is right — eleven digits, a plausible birth date encoded in the first six. But the final digit is written the way every other digit is written, and it is only correct by luck.

This is not a claim that a model *cannot* compute a checksum. Give it the algorithm and a code interpreter and it will. The point is that the everyday ask — "give me 50 test PESELs" — does not do that, and the failure is invisible: the data looks completely convincing until your validator rejects it, or worse, until it does not and the bug ships.

the same shape, one valid
PESEL weights: 1 3 7 9 1 3 7 9 1 3

  87061766641   ← generated by Real Fake Data
                  weighted sum ends in 9 → check digit 1 ✓ valid

  87061766645   ← a plausible-looking number
                  same birth date, same shape, wrong final digit ✗ rejected

A prompt is not a seed

Fixtures need to be the same tomorrow. A test that fails today should fail identically on the next run, and a teammate checking out the branch should see the data you saw.

Real Fake Data takes a `seed`: the same integer always yields the same record, and the response reports which seed produced it, so you can pin what you got. A whole nested dataset from one compose call replays byte for byte.

A model has no equivalent. Sampling settings narrow the variation but do not promise identical text, and on the current generation of Claude models the sampling parameters are not accepted at all. The reliable way to reproduce model output is to save the output — at which point you have a fixture file, not a generator.

same seed, same record
GET /v1/pl/person?seed=42   →  { "pesel": "87061766641", … }
GET /v1/pl/person?seed=42   →  { "pesel": "87061766641", … }   identical

# and the whole nested dataset replays too
POST /v1/compose  { "seed": 42, "shape": { … } }

The arithmetic on a thousand records

A model has to write every character of every record. A compact person — name, surname, national number, birth date — is roughly 35 output tokens, so a thousand of them is about 35,000 tokens of generation.

Real Fake Data charges by record, not by character: a call costs `1 + ceil(records/10)` tokens, so a thousand records is **101 tokens** regardless of how much text each one contains.

1,000 recordsGeneratesCosts
Real Fake Data101 tokens$0.008
Claude Haiku 4.5~35,000 output tokens$0.1821×
Claude Sonnet 5~35,000 output tokens$0.5363×
Claude Opus 5~35,000 output tokens$0.88106×

LLM figures use Anthropic’s published output-token rates and assume ~35 output tokens per record; input tokens are excluded, which flatters the model. Real Fake Data figures use a $25 top-up. Both sides move with volume — the ratio is the durable part, not the absolute numbers.

When asking a model is the right answer

This page would be dishonest without it. If you need data that no generator covers — support-ticket text in a particular tone, product descriptions for an invented catalogue, a CSV whose columns you just made up — a model is the tool. It handles the unstructured and the novel, which a fixed catalogue of generators cannot.

The two also compose well. Ask a model to design the shape of your seed data, then let it call Real Fake Data for the fields that have to be valid. That is exactly what the MCP server and the Claude skills are for: the model decides what a record should contain, and the identifiers inside it still pass validation.

Try it against your own validator

Generate a PESEL, a CPR, an IBAN — then run it through whatever check your application uses. That is the comparison that settles it.