Exact-copy detection
The simplest privacy check: how many synthetic rows are real rows. Why it always runs, what near-copies mean, and why zero copies isn't a pass.
Updated 17 August 2026 · Figures from metrics engine 0.5.1
Exact-copy detection is the bluntest privacy check in synthetic data validation, and for that reason the one no report should be without. It asks: how many synthetic rows are, field for field, identical to a real row? Any such row is a real person's record published under a synthetic label. There is no interpretation required and no threshold to argue about.
It is also the check most easily passed by a bad generator, and this page is as much about what it doesn't tell you as what it does.
Definition
Compare every synthetic record against every real record. Count the synthetic records that match a real record exactly on all columns. Report the count and the share of the synthetic dataset.
Two refinements make it useful in practice:
Near-copies. A generator that emits a real row with one field nudged has not really done better. Near-copy detection counts synthetic rows that match a real row on all columns but one, or on all quasi-identifying columns — the ones an attacker would use to recognise a person. The share of near-copies is usually the more informative number.
Baseline for legitimate duplicates. Real datasets contain genuinely identical rows: many customers with the same age band, region and product; many transactions with the same amount and category. A synthetic dataset that reflects reality will contain some rows identical to real ones by coincidence, especially in low-cardinality data. The baseline is the rate at which real rows duplicate other real rows. Synthetic-to-real copies at or below that rate are what a faithful generator produces; copies well above it are memorisation.
What a bad score usually means
Memorisation, plainly. The generator overfit and is emitting training data. Exact copies are the unambiguous signature; a spike of them means the model should not be shipped, whatever its other scores.
A generator that copies by design. Some "synthetic" pipelines are actually perturbation or sampling of real rows. Exact-copy detection exposes them immediately, which is why they don't like it.
Low-cardinality data with a poor baseline. In a table with a handful of categorical columns and few distinct combinations, coincidental copies are common in real data and synthetic data alike. If the real-to-real duplicate rate is 8% and the synthetic-to-real rate is 9%, that is not a leak. The baseline is what stops this check from crying wolf.
Identifiers left in. A unique-ID column makes exact copies impossible and near-copies (all columns but the ID) the number that matters. It also means the identifier column should not have been synthesised at all.
The remedy for genuine copies is generator-agnostic: regularise or stop earlier, and — because copies are cheap to detect — filter them from the synthetic output as a last-resort post-processing step, understanding that filtered exact copies leave near-copies behind.
Why zero copies is not a pass
This is the point of the page. Exact-copy detection catches the crudest leak and nothing else. A generator that memorised its training data and perturbs every row by a small amount produces zero exact copies and leaks almost as badly. A generator that preserves quasi-identifier combinations faithfully lets an attacker single out individuals with zero copies present. Membership can be inferred, attributes can be inferred, records can be linked — all with an exact-copy count of zero.
So the check is a floor, not a ceiling. Its passing tells you the generator didn't do the one thing that would be embarrassing to explain. It is DCR and NNDR that catch the near-copies exact matching misses, and the attack-based metrics — singling-out, linkability and inference, membership inference — that measure the subtler leakage. A privacy report that leads with "0 exact copies" and stops has measured the easy thing.
Reading exact-copy detection alongside the other pillars
Exact copies are also the limiting case of perfect fidelity: a copied row has flawless column shape and correlation. This is the sharpest illustration of why fidelity and privacy must be read together — the highest possible fidelity score is achieved by the worst possible privacy outcome. Any report that lets fidelity or utility carry a dataset with a meaningful copy rate is broken; a critical copy finding should cap the grade outright.
It needs no holdout and no real-data sample beyond the one being compared, so it runs in every mode that includes real data. In a synthetic-only run it cannot run — there is nothing to compare against — and should say so.
Worked example
UCI Adult census, 4,200 rows × 15 columns, SDV Gaussian Copula, metrics engine 0.6.0. Privacy pillar 98.5.
| SDV Gaussian Copula | Memorising control | Real-to-real baseline | |
|---|---|---|---|
| Exact copies | 0 rows (0.0%) | 4,200 rows (100.0%) | 0.0% duplicate rows |
| Near copies | 0 rows (0.0%) | 2,157 rows (51.4%) | 2.7% |
The baseline column is what makes the other two readable. Two independent halves of the real Adult sample land within near-copy distance of each other 2.7% of the time — that is the coincidence rate for this data, not a leak. The SDV run came in at 0.0%, below its own baseline. The memorising control reached 51.4%, which is 48.6 percentage points above baseline and not explicable by coincidence in any dataset.
Adult has no duplicate rows at all (0.0%), so exact matching is unambiguous here. On a table of five categorical columns it would not be, and that is precisely when the baseline stops being a nicety.
The memorising control's exact-copy result is a critical finding that caps its overall grade at D regardless of the rest of the report — and the rest of its report was excellent: fidelity 100.0, utility 69.3, structural integrity 97.4. Every pillar except privacy ranked it above the honest generator. Its near-copy count is the second half of the story: even if you deleted all 4,200 exact matches, thousands of rows would still be a real person with a field nudged.
How SynthProof reports it
SynthProof runs exact-copy detection first in the privacy pillar, in every mode that includes a real sample, and reports exact and near-copy counts and shares next to the real-to-real duplicate baseline so coincidental matches in low-cardinality data aren't mistaken for leaks. It is labelled explicitly as the part of the privacy pillar that needs no holdout — and as a floor, not a pass. A copy share meaningfully above baseline is a critical finding that caps the overall grade regardless of fidelity or utility. When copies are found, the findings describe the region of the data they concentrate in (never the rows themselves) and, where an identifier column is implicated, say so.
Related metrics
Distance to closest record and Nearest-neighbour distance ratio generalise this check to near-copies. Membership inference is what a zero-copy result leaves untested.
Back to the guide: Synthetic data validation: the complete guide.