Consent Docs

Consent check benchmark

What one consent check took on one test machine, how it was measured, and what the figures do not promise.

Reference3 min readFor anyone looking something up

These are the figures of one run of the consent check on one shared workstation. They describe that run only. They are not a promised response time.

What was measured#

Fact Value
Script scripts/bench-consent-check.mjs in the repository
Date 3 October 2026, 15:27 to 15:32 UTC
Code This release, built on commit 86ec182
API version Server package 1.0.0
Call POST /sdk/v1/consent/check with one identifier, purposeKey: "marketing", no partnerKey and no alsoKnownAs
Method 500 checks to warm up, then 60 seconds at each number of calls in flight
Unknown people 10% of calls used an id nobody holds

Set-up#

Fact Value
Host One developer workstation, shared. The API, PostgreSQL and the script ran on it, and the script called the API over loopback.
Other load Other work kept running, including a video-encoding job that used up to about 6 cores at times. Load average was 4.4, 7.5 and 12.1 at the start and 13.6, 10.6 and 12.1 at the end.
CPU 11th Gen Intel Core i9-11900, 8 cores, 16 threads, 1 socket
Memory 93 GiB
Node.js v20.20.2, for the API and the script
API 1 replica, one Node.js process, NODE_ENV=development, compiled JavaScript. The request log wrote one line per request to a file. Database pool of 20.
PostgreSQL 18.6 in the postgres:18-alpine container, with its default settings
Redis Off. The budgets were counted in the API process.
Budgets SDK_CHECK_MAX_PER_MINUTE=600000 and RATE_LIMIT_SDK_MAX=600000. A live secret key with consent:check, 600,000 requests a minute and 600,000 checks a minute. No budget refused a call.
Database A scratch copy of a development database: 52,520 records, 54,731 events and 6,688 linked identifiers after seeding
People 20,000 people bench-<n> under USER_ID on one form with five purposes. Every third was linked to a phone number and checked by it. Every fourth refused marketing. Every tenth was withdrawn afterwards.

The budgets were raised to 600,000 so they did not shape the figures. With the defaults, a key may check 600 identifiers a minute, and at most 6,000 unless the operator raises it. One address may make 3,000 calls to /sdk a minute.

Results#

The script's own table, unchanged:

Calls in flight Checks Per second p50 ms p95 ms p99 ms Max ms Errors
1 11971 200 4.7 7 8.4 33.4 None
8 25010 417 17.8 29.5 35 66.5 None
32 22858 381 88.5 103.2 110.8 249.7 None

The answers matched how the people were seeded: about 10% no_record, 9% withdrawn and 18% refused.

JSON
{"concurrency":1,"checks":11971,"perSecond":200,"p50":4.7,"p95":7,
 "p99":8.4,"max":33.4,"errors":{},"reasons":{"granted":7470,
 "refused":2212,"no_record":1216,"withdrawn":1073},"seconds":60}
{"concurrency":8,"checks":25010,"perSecond":417,"p50":17.8,"p95":29.5,
 "p99":35,"max":66.5,"errors":{},"reasons":{"granted":15722,
 "refused":4538,"withdrawn":2189,"no_record":2561},"seconds":60}
{"concurrency":32,"checks":22858,"perSecond":381,"p50":88.5,"p95":103.2,
 "p99":110.8,"max":249.7,"errors":{},"reasons":{"no_record":2249,
 "granted":14435,"withdrawn":2088,"refused":4086},"seconds":60.1}

Throughput stopped rising between 8 and 32 calls in flight. A short sample at 32 in flight showed the single API process at about 86% of one core. One process was the limit on this host, so more calls in flight only made each one wait longer.

What the figures do not tell you#

  • Your network. Your systems also wait for the trip to your deployment and back, which depends on where it runs.
  • A promise. There is no service-level commitment on how fast a check answers.
  • Default budgets. The run used raised budgets. With the defaults, the budgets refuse calls long before these rates.
  • Your hardware. The host was shared and busy. Run the script on your own deployment to measure it:
Shell
API_URL=https://consent.example.in \
PIEDAP_SECRET_KEY=sk_… \
FORM_KEY=in-banner PURPOSE_KEY=marketing SEED=1 \
node scripts/bench-consent-check.mjs

SEED=1 writes 20,000 people first, so run it only against a database made for the run. The key needs consent:check and raised budgets.

↑↓ to move, Enter to open