Benchmark reportVERIS-TF-001

Veris Twin Fidelity Benchmark

431 of 436 independent verdicts agree with production; the raw count, nothing set aside, is 424. Zero fake passes. Every divergence named below.

DocumentVERIS-TF-001
Rev1.1
DateAUG 2026
Tests436
Services9
Catalogue70+ TWINS

This benchmark measures how closely Veris twins behave like the production systems they replace, scored by an independent instrument we do not control. Every test is first proven against the live vendor API, then run unmodified against the twin; every divergence is counted and named. Every number below is an exact count over a fixed population. There is no sampling and there are no confidence intervals, because none are warranted.

Veris builds twins as a catalogue. More than 70 services are twinned today, every one produced by the same factory and method; internal and proprietary systems are twinned to order from a customer’s own specs, schemas, or recorded traffic.

In the catalogue today

SalesforceTwilioZendeskIntercomAtlassianDocuSignPagerDutyOpenAIGoogle MapsMySQLApache KafkaSnowflakeBigQuerySlackShopifyPayPalNotionOktaGitHubDatadogGoogle CloudSAPMongoDBElasticsearchDatabricksClickHouseStripeHubSpotMailchimpJiraAuth0GitLabAsanaAWSPostgreSQLRedisRabbitMQDynamoDBCockroachDB+ dozens more, from banking cores to ERPs

The nine services measured in this study are the ones the independent instrument covers with live vendor accounts to prove its tests against. They are a sample, not the catalogue, selected by instrument availability rather than score. Because every twin is produced the same way, the sample is representative of the build process.

Measured through Rev 1.1

StripeAsanaAirtableQuickBooksAttioGoogle MailGoogle DriveGoogle CalendarCalendly
1

The experiment: tests we didn’t write, proven on the real system first

The obvious objection to a vendor-run fidelity study is that the vendor wrote the tests. This study removes it by borrowing its instrument from an open-source project that has nothing to do with us: NangoHQ/integration-templates, a public repository of production integration code written for Nango’s own customers to run against live vendor APIs. It runs here unmodified through Nango’s own command-line tool: 436 templates across nine services, exercising 194 distinct operations. Every test, every assertion, and every pass-or-fail decision in this study belongs to them. We supplied only the environment the tests point at.

the apparatus · the real system defines correct — the twin never doesInstrument436 tests · not oursarm a · proven first · scores 100% by constructionLive vendor APIdedicated accountsarm b · identical run · only the base url changesVeris twinsame client · same payloadsCompareverdict by verdictLedgerevery difference named
FIG 1 · The two-arm protocol. A test that fails on the real system is fixed or discarded before it ever touches the twin, so the real arm is the definition of correct and everything below 100% on the twin arm is a divergence with a name.

A test written by looking at the twin can only prove that the twin behaves the way its author expected. It cannot detect the cases where the author’s understanding of the real system was wrong, and those are exactly the cases that matter. So the real system defines what counts as a correct answer, and the twin never does. Every test is first proven against the live vendor API on a dedicated account; only then is it pointed at the twin, with only the base URL changed.

2

The count: 431 of 436 verdicts agree

Agreement is scored strictest first. The exact-status lens is the raw measurement: both worlds must return the same verdict down to the HTTP status, and the number is published before anything is set aside. The behaviour lens then removes exactly seven units that differ only in what the two worlds hold — seed data, not behaviour, each one named. The population never changes: all 436 units, nothing excluded.

EXACT-STATUS LENS · RAW · same HTTP status, nothing set aside424 AGREE · 12 DIVERGE · = 97.2%
BEHAVIOUR LENS · raw, minus the seven data-only differences431 AGREE · 5 DIVERGE · = 98.9%
agree 7 · the two worlds hold different data 5 · open divergences, each named below
FIG 2 · Every unit, counted. One cell = one of the 436 tests; no sampling, no confidence intervals, nothing excluded. The raw count is published first and never adjusted; the behaviour lens then sets aside the seven units that differ only in what the two worlds hold, and the five that remain are itemized in the ledger below. Under the loosest lens, same verdict class regardless of status, 427 of 436 agree. Cells are sorted; per-unit placement lives in the retained per-operation ledger.
Per service · both lenses, side by side
ServiceUnitsExact status · rawBehaviour parity
Stripe7171/71 · 100.0%71/71 · 100.0%
Asana5050/50 · 100.0%50/50 · 100.0%
Airtable3737/37 · 100.0%37/37 · 100.0%
QuickBooks6464/64 · 100.0%64/64 · 100.0%
Google Mail5958/59 · 98.3%58/59 · 98.3%
Attio5148/51 · 94.1%50/51 · 98.0%
Google Drive3433/34 · 97.1%33/34 · 97.1%
Google Calendar4642/46 · 91.3%44/46 · 95.7%
Calendly2421/24 · 87.5%24/24 · 100.0%
All nine436424/436 · 97.2%431/436 · 98.9%

Twins of large APIs are scoped to their working core, and every operation outside a twin’s published contract refuses cleanly by policy, so scope is a countable property of each twin, not an estimate.

3

The errors point the safe way: zero fake passes

The twin never invents a success. In every open divergence it refuses: on three units with a different status than production’s own refusal, on two by declaring an operation out of scope. A permissive twin inflates every score run against it; a strict one only produces conservative results. That is what makes twin-based testing usable in an SDLC: a green integration run is never the twin flattering the agent’s code, and a red one means the agent fixes something real or hits a documented divergence.

twin stricter · score understated · safeall 5 open divergences land here — a refusal shapeddifferently, or declared; never a pass the twin inventstwin permissive · score inflated · dangerous0fake passes against vendorpolicy, every revision2 RECORDING LEFTOVERSarchived slugs only the taped accountstill holds — data, set aside, named
FIG 3 · A permissive twin silently inflates every score run on top of it; a strict twin can only understate. This is what makes a green run against the twin trustworthy and a red one worth fixing.

Rev 1.0 carried one divergence that pointed the wrong way — cross-run memory of spent ids, flagged then as the structural exception. It is closed: the twin now takes seedable registries of ids its world does not own. What remains on the permissive side is bookkeeping, not behaviour: two Attio slugs are held by archived leftovers of the recorded account, so the recording refuses a create that a clean production workspace — and the twin — would accept. Both units are counted in the raw 424, set aside by the behaviour lens, and said plainly here rather than rounded away.

4

Every divergence has a name

The study produces a named divergence list rather than a score, and the list is now five units long — each with the mechanism behind it, read off the wire logs. Three need work: two wait on a mechanism production has and the twin lacks, one on a state the twin’s world cannot yet express. Two are published boundaries the twin declares up front rather than defects. Rev 1.0’s ledger shrank the right way: the 26-unit Asana status rule and the structural exception closed outright, and the small status-code families are down to the five units below.

The divergence ledger · every open item · 5 of 436 units
UnitProduction saysTwin saysDirectionMechanism
Gmail · get‑attachment403 PERMISSION_DENIED404 notFoundSame refusal, different statusGmail refuses a stale attachment id before resolving it; the twin resolves first and reports absence. The seedable-registry mechanism that closed four families of this shape does not cover attachments yet.
Google Drive · delete‑shared‑drive403 insufficientFilePermissions404 notFoundSame refusal, different statusProduction sees the drive but the caller is not an organizer; the twin has no per-user role on drives, so visible-but-not-organizer cannot be expressed. Needs a role model, not a registry.
Attio · deals400 standard_object_disabled404 not_foundSame refusal, different statusProduction knows the object exists but is switched off by a workspace admin; the twin has no exists-but-disabled state, so the slug is merely absent.
Google Calendar · import‑eventPass501 notImplementedDeclared boundaryContract-declared unsupported; the twin answers Calendar’s own 501 envelope rather than fabricating a success.
Google Calendar · watch‑settingsPass501 notImplementedDeclared boundaryContract-declared unsupported; push channels on calendars and events are unaffected.

The seven set-aside units, named too: four are the instrument’s own parser refusing response shapes its vendor documents, reachable only because the twin’s world has rows where the recorded account was empty; three are leftovers in the recorded account itself — a calendar that still resolves ids it was told to clear, and the two archived Attio slugs of FIG 3. Data, not behaviour: counted in the raw 424, set aside in the 431.

5

The twin is the steadier instrument: 238 = 238

A repeat over 238 units across two freshly built deployments returned every verdict identical, down to the HTTP status, with zero flips. Over the same repeats, four verdicts on the real arm moved, on vendor-side memory of spent ids. For agents, a red test against the twin is not flake: no cycles burned retrying nondeterministic failures, and two agents testing the same change get the same answer. The oracle is held to the same standard: the recorded real-arm corpus is verified byte-stable before every scoring, and has not moved since it was taped.

FIG 4 · The repeat study. Amber marks on the live arm are schematic positions; the four flips trace to vendor-side memory of spent ids. Production is not a stable measurement; the twin is the more controlled instrument.
6

3.6× faster at the median; the cost is the missing tail

FIG 5· Median latency per service, twin ● vs live ○, log scale. The gap between the dots is the speedup, and the tail is on the record instead of clipped: live worst cases run to 22 s and 32 s of rate-limit backoff. * Open defect on an unclaimed refusal path, not a simulated delay; the twin’s slowest genuine response was 3.1 s. Percentiles in the table below.

A typical request is the same order of magnitude in both worlds; the twin runs about 3.6x faster at the median and its p90 stays near 130 ms on every service. The tail is where the two worlds separate: real vendors regularly take half a second and occasionally tens of seconds (Attio’s worst request sat through 32 s of rate-limit backoff), while the twin has no throttling and no multi-second stalls on someone else’s infrastructure. For agent loops this is the difference between running an integration suite once and running it hundreds of times per session. The cost is that same missing tail: timeout, retry, and backoff behavior under real-world latency is not exercised by default. Latency and fault injection exist in the product; twin behavior under injected conditions is not covered by this study.

Real vs twin latency · typical = median, slow = p90, worst = single slowest
ServiceReal typicalReal slowReal worstTwin typicalTwin slowTwin worst
Asana242 ms570 ms22 s67 ms121 ms3.1 s
Stripe207 ms969 ms6.0 s86 ms136 ms209 ms
Airtable147 ms722 ms1.6 s60 ms103 ms805 ms
Google Calendar370 ms772 ms22 s91 ms168 ms21 s *
Google Drive279 ms566 ms1.3 s89 ms118 ms3.1 s
Google Mail331 ms717 ms1.9 s77 ms118 ms255 ms
Calendly238 ms355 ms1.4 s54 ms74 ms84 ms
Attio490 ms901 ms32 s64 ms107 ms236 ms
All eight283 ms748 ms32 s78 ms134 ms21 s *
7

What this study cannot tell you

  • The instrument probes a focused slice intensely rather than sweeping the twin’s whole declared surface; what it measures, it measures independently, but it does not measure everything.
  • Twin behavior under injected latency and faults is not covered by this study.
  • This revision freshly measured the five services that carried open divergences, 214 units; the four services already exact-perfect were re-scored against their recorded results, not re-run, so a change in them under the newest build would not have been seen.
  • All measurements ran through an off-the-shelf integration gateway; behavior behind a gateway with mutual TLS or DLP inspection is not evidenced here.
  • Results are stamped per build; numbers from unstamped or mixed builds are not comparable.
8

Reproduce this

Every number on this page is reproducible from retained artifacts: a frozen claim manifest, a per-operation ledger, captured request and response corpora from both arms, per-operation diffs, per-test logs, latency tapes, the analyzers, and an identity trail binding each result to the software build that produced it. Each figure carries the command that produced it alongside the raw output. This is the artifact set to demand from any benchmarking vendor, including us.

Pinned build
The environment is rebuilt from a pinned software build immediately before each measurement, and every result is stamped with that build. Comparisons are only ever made between stamped worlds.
Fixed oracle
The instrument and its real-arm recording are pinned; between revisions only the twin build moves, so every delta on this page belongs to the twin and nothing else.
Sealed credentials
Credentials on the twin arm are minted by the environment’s own identity twin, so no real traffic can leak into a simulated measurement.
Fresh world
Each measurement starts from a clean world with no memory, which is why determinism holds.
List of effective revisions
RevDateChange
1.0August 2026First public version: 372 templates, 8 services, two-arm protocol
1.1August 2026Re-scored on a new twin build against the same recording: QuickBooks added (64 units), 436 templates across 9 services. The Asana status rule and the structural exception both closed; five open units remain, each named. Raw 97.2%, behaviour 98.9%.

The benchmark re-runs on the same protocol as twins and instrument grow; new versions append here, and the tables above always show the current revision’s results. Questions, or a system you want to see measured: hello@veris.ai