Results

The numbers a CTO asks for. All of them.

Will it drown us in alerts? Will it catch what hurts? Will it run on our machines? Can we trust the numbers? Here is every answer we have measured.

Datainspec 0.4.1October 2026one laptop · no rules written
0findings in 432 scans of unchanged files, across 108 datasets
93.15%of 628 faults planted in real public datasets caught, with no rules written
106Mrows compared on one laptop, in 5 GB of memory
229Mreal text cells, 0 false alerts for hidden database commands

01Will it drown us in alerts?

Quiet when nothing is wrong.

Alert fatigue kills data tools. So we measure the alarms on data that didn't change, as hard as the catches.

0warnings

on a real month of France's company register

30 million companies, September against October 2025. No column check raised anything. What changed fits in three lines:

What changed · SIRENE · Oct 2025clean
  • VolumeRows: +128,055 (+0.43%), 30,020,346 to 30,148,401, within the usual range
  • Names, codes11 name or code columns: new and gone values, each under the alarm floors
  • Patterns5 columns: the share of values off their usual pattern moved 0.16 to 0.25 points, under the alarm
How we measured this

INSEE's StockUniteLegale, September and October 2025: 30,020,346 and 30,148,401 rows, 35 columns, 4.3 GB of CSV, on the low-memory route, in 1,240 seconds and 10.1 GB at its peak, on the laptop below. Two warnings came from the row-level model (rows that look unusual together), counted apart; none from the column checks.

0

findings in 432 scans of unchanged files

Each of 108 datasets scanned against itself, under four settings. Nothing changed, and nothing was reported.

How we measured this

The same-file gate: 108 datasets, each scanned against itself on the low-memory route at three memory budgets and on the in-memory route once: 432 scans, no false finding. Four more scans were refused for memory before any work (README, Limits; R8 section 2.4). Both sweeps were re-run for 0.4.1: identical.

229M

real text cells, 0 false alerts

The check for database commands hidden in text raised nothing on 229,214,793 real cells, and caught 450 of 450 hidden payloads in the test set.

How we measured this

The row-level clean gate: every text cell of 11 real datasets at full size, 229,214,793 cells, 0 false positives; recall 450 of 450 on the stealth payload set (docs/COVERAGE.md). Time-delay, URL-encoded and unquoted numeric injection styles are outside this check.

Quiet is not blind

A slow drift still shows.

A column that moves 1% a month stays under the alarm every time. History follows each column across every scan and every version you approved, ranks the ones that moved most, and charts them: twelve small steps read as one trend.

How we measured this

The History tab in the app, since 0.4.0. For each column: the share of missing values, the number of distinct values, the mean and the findings, across every scan of the dataset and every approved version, each approval marked on the chart. It ranks the 20 columns that changed most since the oldest scan, once 4 scans are recorded. It shows the trend; it doesn't raise an alarm on it.

scan 1scan 13+12%
Illustration: about 1% a scan. Each step stays inside its alarm band (shaded); the trend doesn't.

02Will it catch what hurts?

Catches what hurts. No rules written.

Every result here uses the default settings. Nobody wrote a rule, set a threshold or told it what to look for.

585of 628

planted faults caught, 93.15%

Dropped columns, changed types, missing-value spikes, outliers, new categories and format drift, planted into real public datasets. Default settings; nobody wrote a rule.

How we measured this

628 faults planted one at a time into a corpus of 107 real public datasets of up to 5,000 rows each, each scanned against its clean original with the default settings; caught means a warning or a critical finding. Measured 18 September 2026.

Calibration

Precise where it matters.

Those are the defaults: automatic profiling and calibration set every threshold so that normal months stay quiet. For the columns that matter most, an engineer sets a precise threshold in the Calibration tab, with a reason. It is on the record, and it can be undone.

How we measured this

In the app's Calibration tab, per column and per check (the missing-value rate, the outlier cutoff and the others the column has), a new value and a reason. Each change is kept with who made it, and can be reverted.

NOAA · public weather records

1,420 fake readings, flagged with their rows.

Placeholder codes posing as measurements: dew points of 9999.9, wind speeds of 999.9. Flagged before that version could become the reference.

columnvaluerows
DEWP9999.9347
WDSP999.9535
MXSPD999.9538
How we measured this

NOAA GSOD 2023, 49 stations in Norway and Svalbard, 10,977 rows: the health check that runs before a version is approved, each flag with sample rows. It flags these three columns; other columns also hold NOAA's codes and are not flagged.

Citi Bike · New York trips

A test station, in a city's public data.

Between December and January it flagged 52 station IDs it had never seen before, with the rows. 51 were new stations. One was a lab test station, in 3 rows, that had slipped into the public export.

unseen end_station_idwhat it was
JC008new station, Newport Pkwy
HB305new station, 9 St HBLR
JC117new station, Dr. Lena Edwards Park
Lab - NYC - Monolitha lab test station, 3 rows
+ 48 morenew stations
How we measured this

Citi Bike NYC trips, December 2025 against January 2026: 2,091,620 and 1,816,391 rows. 'Ids never seen before' on the end and start stations (52 ids in 15,085 rows, 20 ids in 11,178), both critical. A person read the list and marked the finding an expected change, and the test station a real problem. Measured in August 2026 on an earlier engine.

03Will it run on our machines?

Runs where your data is. On a laptop.

Neither file is loaded whole: it streams through a folder on disk, so memory stays flat as the data grows. Before a big scan it works out the memory it needs, and refuses rather than crash.

Time, rows a side

1M rows
35 s
5.3M rows
4.6 min
30M rows
21 min
53M rows
33 min

One laptop. Each run compares two files of that size.

Peak memory: 10× the rows, the same memory

5.3M rows
5.1 GB
53M rows
5.0 GB
The laptop
32 GB

53 million rows a side, 106 million in all, in 5 GB: about a sixth of the laptop.

Read-only on your sourcesNo data, profile or finding sent outCommand line on Windows and Linux, or DockerExit codes 0–3 and JUnit for CI
How we measured this

Windows 11, Intel i9-13950HX, 32 GB. 1M rows: a synthetic population register, the whole command timed, start-up included (32.6 and 34.5 s). 5.3M and 53M rows: New York for-hire trips, Parquet, 25 columns, two row ranges of the same three months, the low-memory route; peak memory is the process's peak commit (53M rows: 3.2 GB resident). 30M: France's company register, CSV, 10.1 GB at its peak. The memory it states as a minimum is an estimate and was exceeded by up to 5%; at 355 columns the row model did not finish on this laptop.

04Can we trust these numbers?

Measured before every release.

Every version runs the same measurement against the last one. A result that changed is fixed or declared with its reason, or the release doesn't ship.

  1. Everyplanted fault re-checked against the last version
  2. 4clean-data gates, each run before and after
  3. 2sweeps scanning every dataset against itself
  4. 1outcome review of what changed
  5. Shiponly when every change is explained
How we measured this

Before a version ships: the planted faults are re-run against the last version, four clean-data gates run before and after (range checks, ratio checks, the row-level layer, placeholder spikes), and every dataset is scanned against itself twice. Any result that changed is classified.

05Why it matters

What one bad file costs.

Two ordinary mistakes, on synthetic data built for our videos. The findings are the engine's own; the figures are our reading of the files.

A synthetic retailer

One store started sending prices in cents.

1,703 rows, all from one store. If October's file reached the monthly report, sales would read €13.2M instead of €1.6M.

Watch the 90-second demo

A synthetic population register

One office opened its file in Excel and saved it.

84,134 person IDs rewritten; a payment run matching on them would miss 17,282 people, €9.0M in a month.

Watch the 70-second story

Prove it on your data.

A pilot on one recurring dataset, on your machines, with success criteria agreed in writing before it starts.