Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real sensitive values?
Made-up emails, card numbers, bank accounts and phone numbers that look like the real thing.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| IP address | Hidden: shown as <SECRET_1> | Left as is | Hidden: shown as [IPV4_7853] |
| Hidden: shown as <SECRET_1> | Hidden: shown as ***@*** | Hidden: shown as [EMAIL_9874] | |
| Card number | Hidden: shown as <SECRET_1> | Hidden: shown as **** **** **** | Hidden: shown as [CREDIT_CARD_3168] |
| Bank account | Hidden: shown as <SECRET_1> | Hidden: shown as [REDACTED IBAN] | Hidden: shown as [IBAN_5258] |
| US Social Security no. | Switch off | Left as is | Left as is |
| US phone number | Hidden: shown as <SECRET_1> | Left as is | Hidden: shown as [PHONE_UK_4232] |
| Email, Korean label | Hidden: shown as <SECRET_1> | Hidden: shown as ***@*** | Hidden: shown as [EMAIL_9340] |
| Phone, Korean label | Hidden: shown as <SECRET_1> | Left as is | Hidden: shown as [PHONE_UK_4232] |
| Hidden | 88%7 of 8 | 50%4 of 8 | 88%7 of 8 |
| Usual timems | 17.1 | 9.4 | 673 |
| SpeedMB per second | 7.3 | 13.6 | 0.2 |
real-looking-values · 128.0 KiB · each line repeated 512 times
2 / 3
Does it redact fake values?
Values made for examples and testing, like example.com emails and test card numbers, plus look-alikes that fail a basic check.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Example IP address | Left as is | Left as is | Hidden: shown as [IPV4_3267] |
| example.com email | Left as is | Hidden: shown as ***@*** | Left as is |
| Test card number | Left as is | Hidden: shown as **** **** **** | Hidden: shown as [CREDIT_CARD_3326] |
| Textbook bank account | Hidden: shown as <SECRET_1> | Hidden: shown as [REDACTED IBAN] | Hidden: shown as [IBAN_0830] |
| Social Security no. | Switch off | Left as is | Left as is |
| 555 phone number | Left as is | Left as is | Hidden: shown as [PHONE_UK_7432] |
| Card no., wrong check digit | Left as is | Left as is | Left as is |
| SSN starting 000 | Switch off | Left as is | Left as is |
| Hidden | 13%1 of 8 | 38%3 of 8 | 50%4 of 8 |
| Usual timems | 6.4 | 3.5 | 472 |
| SpeedMB per second | 14.4 | 27.1 | 0.2 |
validator-heavy · 92.5 KiB · each line repeated 512 times
3 / 3
Does it understand context?
The same kind of fake values, now next to English and Korean labels, and next to words like “example” that say it is not real.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Email, English label | Left as is | Hidden: shown as ***@*** | Left as is |
| Email, Korean label | Left as is | Hidden: shown as ***@*** | Left as is |
| Email, Korean label, decomposed form | Left as is | Hidden: shown as ***@*** | Left as is |
| Phone, English label | Left as is | Left as is | Hidden: shown as [PHONE_UK_7432] |
| Phone, Korean label | Left as is | Left as is | Hidden: shown as [PHONE_UK_7432] |
| Email and phone, one line | Left as is | Partly hidden: shown as ***@*** | Partly hidden: shown as [PHONE_UK_7432] |
| SSN after “example” | Switch off | Left as is | Left as is |
| IP after “documentation” | Left as is | Left as is | Hidden: shown as [IPV4_3267] |
| Hidden | 0%0 of 9 | 44%4 of 9 | 44%4 of 9 |
| Usual timems | 8.6 | 6.7 | 614 |
| SpeedMB per second | 17.4 | 22.4 | 0.2 |
multilingual-context · 147.0 KiB · each line repeated 512 times
About the libraries
| Fact | redact-secret | flare-redact | OpenRedaction |
|---|---|---|---|
| Version | 0.1.0-beta.14 npm | 1.6.1 npm | 1.1.5 npm |
| Package | @redact-secret/core | flare-redact | @openredaction/core |
| Call timed | scanAndRedact()synchronous | redact()synchronous | detect()asynchronous: returns a Promise |
| Runs in | Node.js 20, 22, 24; browsers and Cloudflare Workers through WebAssemblyfrom package metadata and documentation | Node.js 20 or later; browsers and edge runtimesfrom package metadata and documentation | Node.js 20 or later; browser support not documentedfrom package metadata and documentation |
| Install size | 1,885.9 KiB packed5,128.3 KiB unpacked: core, WebAssembly and one platform add-on (linux x64 glibc) | 231.0 KiB packed926.8 KiB unpacked: one package | 756.4 KiB packed3,711.5 KiB unpacked: one package |
| Dependencies | 1 dependency (@redact-secret/wasm); 8 optional platform add-ons | None | None required; 3 optional peers (mammoth, pdf-parse, tesseract.js) |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the PII setting (pii:global). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real sensitive values?
Made-up emails, card numbers, bank accounts and phone numbers that look like the real thing.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Usual timems | 17.1 | 9.4 | 673 |
| SpeedMB per second | 7.3 | 13.6 | 0.2 |
real-looking-values · 128.0 KiB · each line repeated 512 times
2 / 3
Does it redact fake values?
Values made for examples and testing, like example.com emails and test card numbers, plus look-alikes that fail a basic check.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Usual timems | 6.4 | 3.5 | 472 |
| SpeedMB per second | 14.4 | 27.1 | 0.2 |
validator-heavy · 92.5 KiB · each line repeated 512 times
3 / 3
Does it understand context?
The same kind of fake values, now next to English and Korean labels, and next to words like “example” that say it is not real.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Usual timems | 8.6 | 6.7 | 614 |
| SpeedMB per second | 17.4 | 22.4 | 0.2 |
multilingual-context · 147.0 KiB · each line repeated 512 times
About the libraries
| Fact | redact-secret | flare-redact | OpenRedaction |
|---|---|---|---|
| Version | 0.1.0-beta.14 npm | 1.6.1 npm | 1.1.5 npm |
| Package | @redact-secret/core | flare-redact | @openredaction/core |
| Call timed | scanAndRedact()synchronous | redact()synchronous | detect()asynchronous: returns a Promise |
| Runs in | Node.js 20, 22, 24; browsers and Cloudflare Workers through WebAssemblyfrom package metadata and documentation | Node.js 20 or later; browsers and edge runtimesfrom package metadata and documentation | Node.js 20 or later; browser support not documentedfrom package metadata and documentation |
| Install size | 1,885.9 KiB packed5,128.3 KiB unpacked: core, WebAssembly and one platform add-on (linux x64 glibc) | 231.0 KiB packed926.8 KiB unpacked: one package | 756.4 KiB packed3,711.5 KiB unpacked: one package |
| Dependencies | 1 dependency (@redact-secret/wasm); 8 optional platform add-ons | None | None required; 3 optional peers (mammoth, pdf-parse, tesseract.js) |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the PII setting (pii:global). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real sensitive values?
Made-up emails, card numbers, bank accounts and phone numbers that look like the real thing.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| IP address | Hidden: shown as <SECRET_1> | Left as is | Hidden: shown as [IPV4_7853] |
| Hidden: shown as <SECRET_1> | Hidden: shown as ***@*** | Hidden: shown as [EMAIL_9874] | |
| Card number | Hidden: shown as <SECRET_1> | Hidden: shown as **** **** **** | Hidden: shown as [CREDIT_CARD_3168] |
| Bank account | Hidden: shown as <SECRET_1> | Hidden: shown as [REDACTED IBAN] | Hidden: shown as [IBAN_5258] |
| US Social Security no. | Switch off | Left as is | Left as is |
| US phone number | Hidden: shown as <SECRET_1> | Left as is | Hidden: shown as [PHONE_UK_4232] |
| Email, Korean label | Hidden: shown as <SECRET_1> | Hidden: shown as ***@*** | Hidden: shown as [EMAIL_9340] |
| Phone, Korean label | Hidden: shown as <SECRET_1> | Left as is | Hidden: shown as [PHONE_UK_4232] |
| Hidden | 88%7 of 8 | 50%4 of 8 | 88%7 of 8 |
real-looking-values · 128.0 KiB · each line repeated 512 times
2 / 3
Does it redact fake values?
Values made for examples and testing, like example.com emails and test card numbers, plus look-alikes that fail a basic check.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Example IP address | Left as is | Left as is | Hidden: shown as [IPV4_3267] |
| example.com email | Left as is | Hidden: shown as ***@*** | Left as is |
| Test card number | Left as is | Hidden: shown as **** **** **** | Hidden: shown as [CREDIT_CARD_3326] |
| Textbook bank account | Hidden: shown as <SECRET_1> | Hidden: shown as [REDACTED IBAN] | Hidden: shown as [IBAN_0830] |
| Social Security no. | Switch off | Left as is | Left as is |
| 555 phone number | Left as is | Left as is | Hidden: shown as [PHONE_UK_7432] |
| Card no., wrong check digit | Left as is | Left as is | Left as is |
| SSN starting 000 | Switch off | Left as is | Left as is |
| Hidden | 13%1 of 8 | 38%3 of 8 | 50%4 of 8 |
validator-heavy · 92.5 KiB · each line repeated 512 times
3 / 3
Does it understand context?
The same kind of fake values, now next to English and Korean labels, and next to words like “example” that say it is not real.
| redact-secretpii:global | flare-redact | OpenRedaction | |
|---|---|---|---|
| Email, English label | Left as is | Hidden: shown as ***@*** | Left as is |
| Email, Korean label | Left as is | Hidden: shown as ***@*** | Left as is |
| Email, Korean label, decomposed form | Left as is | Hidden: shown as ***@*** | Left as is |
| Phone, English label | Left as is | Left as is | Hidden: shown as [PHONE_UK_7432] |
| Phone, Korean label | Left as is | Left as is | Hidden: shown as [PHONE_UK_7432] |
| Email and phone, one line | Left as is | Partly hidden: shown as ***@*** | Partly hidden: shown as [PHONE_UK_7432] |
| SSN after “example” | Switch off | Left as is | Left as is |
| IP after “documentation” | Left as is | Left as is | Hidden: shown as [IPV4_3267] |
| Hidden | 0%0 of 9 | 44%4 of 9 | 44%4 of 9 |
multilingual-context · 147.0 KiB · each line repeated 512 times
About the libraries
| Fact | redact-secret | flare-redact | OpenRedaction |
|---|---|---|---|
| Version | 0.1.0-beta.14 npm | 1.6.1 npm | 1.1.5 npm |
| Package | @redact-secret/core | flare-redact | @openredaction/core |
| Call timed | scanAndRedact()synchronous | redact()synchronous | detect()asynchronous: returns a Promise |
| Runs in | Node.js 20, 22, 24; browsers and Cloudflare Workers through WebAssemblyfrom package metadata and documentation | Node.js 20 or later; browsers and edge runtimesfrom package metadata and documentation | Node.js 20 or later; browser support not documentedfrom package metadata and documentation |
| Install size | 1,885.9 KiB packed5,128.3 KiB unpacked: core, WebAssembly and one platform add-on (linux x64 glibc) | 231.0 KiB packed926.8 KiB unpacked: one package | 756.4 KiB packed3,711.5 KiB unpacked: one package |
| Dependencies | 1 dependency (@redact-secret/wasm); 8 optional platform add-ons | None | None required; 3 optional peers (mammoth, pdf-parse, tesseract.js) |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the PII setting (pii:global). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real sensitive values?
Made-up emails, card numbers, bank accounts and phone numbers that look like the real thing.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| IP address | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | |
| Card number | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Bank account | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| US Social Security no. | Switch off | Switch off | Hidden: shown as <SECRET_1> |
| US phone number | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Email, Korean label | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Phone, Korean label | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Hidden | 0%0 of 8 | 88%7 of 8 | 100%8 of 8 |
| Usual timems | 1.9 | 17.1 | 17.8 |
| SpeedMB per second | 67.9 | 7.3 | 7.2 |
real-looking-values · 128.0 KiB · each line repeated 512 times
2 / 3
Does it redact fake values?
Values made for examples and testing, like example.com emails and test card numbers, plus look-alikes that fail a basic check.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Example IP address | Switch off | Left as is | Left as is |
| example.com email | Switch off | Left as is | Left as is |
| Test card number | Switch off | Left as is | Left as is |
| Textbook bank account | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Social Security no. | Switch off | Switch off | Hidden: shown as <SECRET_1> |
| 555 phone number | Switch off | Left as is | Left as is |
| Card no., wrong check digit | Switch off | Left as is | Left as is |
| SSN starting 000 | Switch off | Switch off | Left as is |
| Hidden | 0%0 of 8 | 13%1 of 8 | 25%2 of 8 |
| Usual timems | 1.2 | 6.4 | 7.8 |
| SpeedMB per second | 78.0 | 14.4 | 12.1 |
validator-heavy · 92.5 KiB · each line repeated 512 times
3 / 3
Does it understand context?
The same kind of fake values, now next to English and Korean labels, and next to words like “example” that say it is not real.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Email, English label | Switch off | Left as is | Left as is |
| Email, Korean label | Switch off | Left as is | Left as is |
| Email, Korean label, decomposed form | Switch off | Left as is | Left as is |
| Phone, English label | Switch off | Left as is | Left as is |
| Phone, Korean label | Switch off | Left as is | Left as is |
| Email and phone, one line | Switch off | Left as is | Left as is |
| SSN after “example” | Switch off | Switch off | Left as is |
| IP after “documentation” | Switch off | Left as is | Left as is |
| Hidden | 0%0 of 9 | 0%0 of 9 | 0%0 of 9 |
| Usual timems | 2.4 | 8.6 | 11.8 |
| SpeedMB per second | 61.3 | 17.4 | 11.8 |
multilingual-context · 147.0 KiB · each line repeated 512 times
About the settings
| Fact | Default | PII | PII + US |
|---|---|---|---|
| Selectors | none | pii:global | pii:global, pii:us |
| Turns on | no PII family | email, iban, network address, payment card, phone | email, iban, network address, payment card, phone, ssn |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real sensitive values?
Made-up emails, card numbers, bank accounts and phone numbers that look like the real thing.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Usual timems | 1.9 | 17.1 | 17.8 |
| SpeedMB per second | 67.9 | 7.3 | 7.2 |
real-looking-values · 128.0 KiB · each line repeated 512 times
2 / 3
Does it redact fake values?
Values made for examples and testing, like example.com emails and test card numbers, plus look-alikes that fail a basic check.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Usual timems | 1.2 | 6.4 | 7.8 |
| SpeedMB per second | 78.0 | 14.4 | 12.1 |
validator-heavy · 92.5 KiB · each line repeated 512 times
3 / 3
Does it understand context?
The same kind of fake values, now next to English and Korean labels, and next to words like “example” that say it is not real.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Usual timems | 2.4 | 8.6 | 11.8 |
| SpeedMB per second | 61.3 | 17.4 | 11.8 |
multilingual-context · 147.0 KiB · each line repeated 512 times
About the settings
| Fact | Default | PII | PII + US |
|---|---|---|---|
| Selectors | none | pii:global | pii:global, pii:us |
| Turns on | no PII family | email, iban, network address, payment card, phone | email, iban, network address, payment card, phone, ssn |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real sensitive values?
Made-up emails, card numbers, bank accounts and phone numbers that look like the real thing.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| IP address | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | |
| Card number | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Bank account | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| US Social Security no. | Switch off | Switch off | Hidden: shown as <SECRET_1> |
| US phone number | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Email, Korean label | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Phone, Korean label | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Hidden | 0%0 of 8 | 88%7 of 8 | 100%8 of 8 |
real-looking-values · 128.0 KiB · each line repeated 512 times
2 / 3
Does it redact fake values?
Values made for examples and testing, like example.com emails and test card numbers, plus look-alikes that fail a basic check.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Example IP address | Switch off | Left as is | Left as is |
| example.com email | Switch off | Left as is | Left as is |
| Test card number | Switch off | Left as is | Left as is |
| Textbook bank account | Switch off | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Social Security no. | Switch off | Switch off | Hidden: shown as <SECRET_1> |
| 555 phone number | Switch off | Left as is | Left as is |
| Card no., wrong check digit | Switch off | Left as is | Left as is |
| SSN starting 000 | Switch off | Switch off | Left as is |
| Hidden | 0%0 of 8 | 13%1 of 8 | 25%2 of 8 |
validator-heavy · 92.5 KiB · each line repeated 512 times
3 / 3
Does it understand context?
The same kind of fake values, now next to English and Korean labels, and next to words like “example” that say it is not real.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Email, English label | Switch off | Left as is | Left as is |
| Email, Korean label | Switch off | Left as is | Left as is |
| Email, Korean label, decomposed form | Switch off | Left as is | Left as is |
| Phone, English label | Switch off | Left as is | Left as is |
| Phone, Korean label | Switch off | Left as is | Left as is |
| Email and phone, one line | Switch off | Left as is | Left as is |
| SSN after “example” | Switch off | Switch off | Left as is |
| IP after “documentation” | Switch off | Left as is | Left as is |
| Hidden | 0%0 of 9 | 0%0 of 9 | 0%0 of 9 |
multilingual-context · 147.0 KiB · each line repeated 512 times
About the settings
| Fact | Default | PII | PII + US |
|---|---|---|---|
| Selectors | none | pii:global | pii:global, pii:us |
| Turns on | no PII family | email, iban, network address, payment card, phone | email, iban, network address, payment card, phone, ssn |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real secrets?
Made-up API keys and tokens in the places people paste them: a .env file, a command line, an HTTP header.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| .env, AWS access key | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| .env, GitHub token | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Command line, Slack token | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| HTTP header, bearer JWT | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| HTTP header, API key | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| .env, Stripe secret key | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Connection string | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Command line, npm token | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Hidden | 100%8 of 8 | 100%8 of 8 | 100%8 of 8 |
| Usual timems | 20.0 | 22.5 | 21.9 |
| SpeedMB per second | 13.7 | 13.1 | 13.2 |
credentials-real · 287.5 KiB · each line repeated 512 times
2 / 3
Does it redact fake secrets?
Placeholders like YOUR_TOKEN_HERE, keys that are public by design, and look-alikes that are too short or use the wrong letters.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Placeholder | Left as is | Left as is | Left as is |
| Angle-bracket placeholder | Left as is | Left as is | Left as is |
| AWS documentation key | Left as is | Left as is | Left as is |
| Public by design, Stripe publishable key | Left as is | Left as is | Left as is |
| Too short GitHub token | Left as is | Left as is | Left as is |
| Wrong letters, AWS-style key | Left as is | Left as is | Left as is |
| Repeated character | Left as is | Left as is | Left as is |
| Hash, not a secret | Left as is | Left as is | Left as is |
| Hidden | 0%0 of 8 | 0%0 of 8 | 0%0 of 8 |
| Usual timems | 6.2 | 7.0 | 6.8 |
| SpeedMB per second | 26.8 | 23.9 | 23.0 |
credentials-fake · 164.0 KiB · each line repeated 512 times
3 / 3
Does it understand context?
Real secrets inside sentences, logs and code, next to look-alikes whose surroundings say they are not secrets.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Sentence | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Log line | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Code | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| JSON body | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Example in a comment | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Test fixture comment | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Commit hash | Left as is | Left as is | Left as is |
| Request id | Left as is | Left as is | Left as is |
| Hidden | 75%6 of 8 | 75%6 of 8 | 75%6 of 8 |
| Usual timems | 18.9 | 21.2 | 18.3 |
| SpeedMB per second | 15.0 | 13.0 | 15.9 |
credentials-context · 285.0 KiB · each line repeated 512 times
About the settings
| Fact | Default | PII | PII + US |
|---|---|---|---|
| Selectors | none | pii:global | pii:global, pii:us |
| Turns on | no PII family | email, iban, network address, payment card, phone | email, iban, network address, payment card, phone, ssn |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Every line of these credential texts carries a secret, so each call finds and replaces thousands of them. The times are for text that dense, so they are not comparable with the speeds on the Performance page, which times a different text.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real secrets?
Made-up API keys and tokens in the places people paste them: a .env file, a command line, an HTTP header.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Usual timems | 20.0 | 22.5 | 21.9 |
| SpeedMB per second | 13.7 | 13.1 | 13.2 |
credentials-real · 287.5 KiB · each line repeated 512 times
2 / 3
Does it redact fake secrets?
Placeholders like YOUR_TOKEN_HERE, keys that are public by design, and look-alikes that are too short or use the wrong letters.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Usual timems | 6.2 | 7.0 | 6.8 |
| SpeedMB per second | 26.8 | 23.9 | 23.0 |
credentials-fake · 164.0 KiB · each line repeated 512 times
3 / 3
Does it understand context?
Real secrets inside sentences, logs and code, next to look-alikes whose surroundings say they are not secrets.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Usual timems | 18.9 | 21.2 | 18.3 |
| SpeedMB per second | 15.0 | 13.0 | 15.9 |
credentials-context · 285.0 KiB · each line repeated 512 times
About the settings
| Fact | Default | PII | PII + US |
|---|---|---|---|
| Selectors | none | pii:global | pii:global, pii:us |
| Turns on | no PII family | email, iban, network address, payment card, phone | email, iban, network address, payment card, phone, ssn |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Every line of these credential texts carries a secret, so each call finds and replaces thousands of them. The times are for text that dense, so they are not comparable with the speeds on the Performance page, which times a different text.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real secrets?
Made-up API keys and tokens in the places people paste them: a .env file, a command line, an HTTP header.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| .env, AWS access key | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| .env, GitHub token | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Command line, Slack token | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| HTTP header, bearer JWT | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| HTTP header, API key | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| .env, Stripe secret key | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Connection string | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Command line, npm token | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Hidden | 100%8 of 8 | 100%8 of 8 | 100%8 of 8 |
credentials-real · 287.5 KiB · each line repeated 512 times
2 / 3
Does it redact fake secrets?
Placeholders like YOUR_TOKEN_HERE, keys that are public by design, and look-alikes that are too short or use the wrong letters.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Placeholder | Left as is | Left as is | Left as is |
| Angle-bracket placeholder | Left as is | Left as is | Left as is |
| AWS documentation key | Left as is | Left as is | Left as is |
| Public by design, Stripe publishable key | Left as is | Left as is | Left as is |
| Too short GitHub token | Left as is | Left as is | Left as is |
| Wrong letters, AWS-style key | Left as is | Left as is | Left as is |
| Repeated character | Left as is | Left as is | Left as is |
| Hash, not a secret | Left as is | Left as is | Left as is |
| Hidden | 0%0 of 8 | 0%0 of 8 | 0%0 of 8 |
credentials-fake · 164.0 KiB · each line repeated 512 times
3 / 3
Does it understand context?
Real secrets inside sentences, logs and code, next to look-alikes whose surroundings say they are not secrets.
| Defaultno PII | PIIpii:global | PII + USadds pii:us | |
|---|---|---|---|
| Sentence | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Log line | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Code | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| JSON body | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Example in a comment | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Test fixture comment | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> | Hidden: shown as <SECRET_1> |
| Commit hash | Left as is | Left as is | Left as is |
| Request id | Left as is | Left as is | Left as is |
| Hidden | 75%6 of 8 | 75%6 of 8 | 75%6 of 8 |
credentials-context · 285.0 KiB · each line repeated 512 times
About the settings
| Fact | Default | PII | PII + US |
|---|---|---|---|
| Selectors | none | pii:global | pii:global, pii:us |
| Turns on | no PII family | email, iban, network address, payment card, phone | email, iban, network address, payment card, phone, ssn |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Every line of these credential texts carries a secret, so each call finds and replaces thousands of them. The times are for text that dense, so they are not comparable with the speeds on the Performance page, which times a different text.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real secrets?
Made-up API keys and tokens in the places people paste them: a .env file, a command line, an HTTP header.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| .env, AWS access key | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [AWS_KEY_5692] |
| .env, GitHub token | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [GITHUB_TOKEN_0852] |
| Command line, Slack token | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [SLACK_TOKEN_4831] |
| HTTP header, bearer JWT | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [AUTH_6553] [JWT_1006] |
| HTTP header, API key | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [API_KEY_5282] |
| .env, Stripe secret key | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [STRIPE_KEY_4672] |
| Connection string | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [DB_CONN_4622] |
| Command line, npm token | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [NPM_TOKEN_8044] |
| Hidden | 100%8 of 8 | 100%8 of 8 | 100%8 of 8 |
| Usual timems | 20.0 | 9.6 | 1,407 |
| SpeedMB per second | 13.7 | 29.7 | 0.2 |
credentials-real · 287.5 KiB · each line repeated 512 times
2 / 3
Does it redact fake secrets?
Placeholders like YOUR_TOKEN_HERE, keys that are public by design, and look-alikes that are too short or use the wrong letters.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Placeholder | Left as is | Hidden: shown as *** | Left as is |
| Angle-bracket placeholder | Left as is | Hidden: shown as *** | Left as is |
| AWS documentation key | Left as is | Hidden: shown as *** | Hidden: shown as [AWS_KEY_4884] |
| Public by design, Stripe publishable key | Left as is | Left as is | Hidden: shown as [STRIPE_KEY_3790] |
| Too short GitHub token | Left as is | Hidden: shown as *** | Left as is |
| Wrong letters, AWS-style key | Left as is | Left as is | Left as is |
| Repeated character | Left as is | Hidden: shown as *** | Left as is |
| Hash, not a secret | Left as is | Left as is | Left as is |
| Hidden | 0%0 of 8 | 63%5 of 8 | 25%2 of 8 |
| Usual timems | 6.2 | 4.1 | 234 |
| SpeedMB per second | 26.8 | 39.8 | 0.7 |
credentials-fake · 164.0 KiB · each line repeated 512 times
3 / 3
Does it understand context?
Real secrets inside sentences, logs and code, next to look-alikes whose surroundings say they are not secrets.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Sentence | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [GITHUB_TOKEN_7924] |
| Log line | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [NAME_9305]=[GITHUB_TOKEN_4441] |
| Code | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [AWS_KEY_2662] |
| JSON body | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Left as is |
| Example in a comment | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [GITHUB_TOKEN_9363] |
| Test fixture comment | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Partly hidden: shown as [LAB_5432] |
| Commit hash | Left as is | Left as is | Left as is |
| Request id | Left as is | Left as is | Left as is |
| Hidden | 75%6 of 8 | 75%6 of 8 | 50%4 of 8 |
| Usual timems | 18.9 | 7.6 | 1,009 |
| SpeedMB per second | 15.0 | 36.6 | 0.3 |
credentials-context · 285.0 KiB · each line repeated 512 times
About the libraries
| Fact | redact-secret | flare-redact | OpenRedaction |
|---|---|---|---|
| Version | 0.1.0-beta.14 npm | 1.6.1 npm | 1.1.5 npm |
| Package | @redact-secret/core | flare-redact | @openredaction/core |
| Call timed | scanAndRedact()synchronous | redact()synchronous | detect()asynchronous: returns a Promise |
| Runs in | Node.js 20, 22, 24; browsers and Cloudflare Workers through WebAssemblyfrom package metadata and documentation | Node.js 20 or later; browsers and edge runtimesfrom package metadata and documentation | Node.js 20 or later; browser support not documentedfrom package metadata and documentation |
| Install size | 1,885.9 KiB packed5,128.3 KiB unpacked: core, WebAssembly and one platform add-on (linux x64 glibc) | 231.0 KiB packed926.8 KiB unpacked: one package | 756.4 KiB packed3,711.5 KiB unpacked: one package |
| Dependencies | 1 dependency (@redact-secret/wasm); 8 optional platform add-ons | None | None required; 3 optional peers (mammoth, pdf-parse, tesseract.js) |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Every line of these credential texts carries a secret, so each call finds and replaces thousands of them. The times are for text that dense, so they are not comparable with the speeds on the Performance page, which times a different text.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real secrets?
Made-up API keys and tokens in the places people paste them: a .env file, a command line, an HTTP header.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Usual timems | 20.0 | 9.6 | 1,407 |
| SpeedMB per second | 13.7 | 29.7 | 0.2 |
credentials-real · 287.5 KiB · each line repeated 512 times
2 / 3
Does it redact fake secrets?
Placeholders like YOUR_TOKEN_HERE, keys that are public by design, and look-alikes that are too short or use the wrong letters.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Usual timems | 6.2 | 4.1 | 234 |
| SpeedMB per second | 26.8 | 39.8 | 0.7 |
credentials-fake · 164.0 KiB · each line repeated 512 times
3 / 3
Does it understand context?
Real secrets inside sentences, logs and code, next to look-alikes whose surroundings say they are not secrets.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Usual timems | 18.9 | 7.6 | 1,009 |
| SpeedMB per second | 15.0 | 36.6 | 0.3 |
credentials-context · 285.0 KiB · each line repeated 512 times
About the libraries
| Fact | redact-secret | flare-redact | OpenRedaction |
|---|---|---|---|
| Version | 0.1.0-beta.14 npm | 1.6.1 npm | 1.1.5 npm |
| Package | @redact-secret/core | flare-redact | @openredaction/core |
| Call timed | scanAndRedact()synchronous | redact()synchronous | detect()asynchronous: returns a Promise |
| Runs in | Node.js 20, 22, 24; browsers and Cloudflare Workers through WebAssemblyfrom package metadata and documentation | Node.js 20 or later; browsers and edge runtimesfrom package metadata and documentation | Node.js 20 or later; browser support not documentedfrom package metadata and documentation |
| Install size | 1,885.9 KiB packed5,128.3 KiB unpacked: core, WebAssembly and one platform add-on (linux x64 glibc) | 231.0 KiB packed926.8 KiB unpacked: one package | 756.4 KiB packed3,711.5 KiB unpacked: one package |
| Dependencies | 1 dependency (@redact-secret/wasm); 8 optional platform add-ons | None | None required; 3 optional peers (mammoth, pdf-parse, tesseract.js) |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Every line of these credential texts carries a secret, so each call finds and replaces thousands of them. The times are for text that dense, so they are not comparable with the speeds on the Performance page, which times a different text.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.
Comparison
Runtime comparison
What each library did to each value in the same made-up text, and how long one redact call took. Outcomes and times are recorded, not graded. Nothing here is ranked.
Compare two across many texts →
1 / 3
Does it catch real secrets?
Made-up API keys and tokens in the places people paste them: a .env file, a command line, an HTTP header.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| .env, AWS access key | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [AWS_KEY_5692] |
| .env, GitHub token | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [GITHUB_TOKEN_0852] |
| Command line, Slack token | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [SLACK_TOKEN_4831] |
| HTTP header, bearer JWT | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [AUTH_6553] [JWT_1006] |
| HTTP header, API key | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [API_KEY_5282] |
| .env, Stripe secret key | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [STRIPE_KEY_4672] |
| Connection string | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [DB_CONN_4622] |
| Command line, npm token | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [NPM_TOKEN_8044] |
| Hidden | 100%8 of 8 | 100%8 of 8 | 100%8 of 8 |
credentials-real · 287.5 KiB · each line repeated 512 times
2 / 3
Does it redact fake secrets?
Placeholders like YOUR_TOKEN_HERE, keys that are public by design, and look-alikes that are too short or use the wrong letters.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Placeholder | Left as is | Hidden: shown as *** | Left as is |
| Angle-bracket placeholder | Left as is | Hidden: shown as *** | Left as is |
| AWS documentation key | Left as is | Hidden: shown as *** | Hidden: shown as [AWS_KEY_4884] |
| Public by design, Stripe publishable key | Left as is | Left as is | Hidden: shown as [STRIPE_KEY_3790] |
| Too short GitHub token | Left as is | Hidden: shown as *** | Left as is |
| Wrong letters, AWS-style key | Left as is | Left as is | Left as is |
| Repeated character | Left as is | Hidden: shown as *** | Left as is |
| Hash, not a secret | Left as is | Left as is | Left as is |
| Hidden | 0%0 of 8 | 63%5 of 8 | 25%2 of 8 |
credentials-fake · 164.0 KiB · each line repeated 512 times
3 / 3
Does it understand context?
Real secrets inside sentences, logs and code, next to look-alikes whose surroundings say they are not secrets.
| redact-secretno PII | flare-redact | OpenRedaction | |
|---|---|---|---|
| Sentence | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [GITHUB_TOKEN_7924] |
| Log line | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [NAME_9305]=[GITHUB_TOKEN_4441] |
| Code | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [AWS_KEY_2662] |
| JSON body | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Left as is |
| Example in a comment | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Hidden: shown as [GITHUB_TOKEN_9363] |
| Test fixture comment | Hidden: shown as <SECRET_1> | Hidden: shown as *** | Partly hidden: shown as [LAB_5432] |
| Commit hash | Left as is | Left as is | Left as is |
| Request id | Left as is | Left as is | Left as is |
| Hidden | 75%6 of 8 | 75%6 of 8 | 50%4 of 8 |
credentials-context · 285.0 KiB · each line repeated 512 times
About the libraries
| Fact | redact-secret | flare-redact | OpenRedaction |
|---|---|---|---|
| Version | 0.1.0-beta.14 npm | 1.6.1 npm | 1.1.5 npm |
| Package | @redact-secret/core | flare-redact | @openredaction/core |
| Call timed | scanAndRedact()synchronous | redact()synchronous | detect()asynchronous: returns a Promise |
| Runs in | Node.js 20, 22, 24; browsers and Cloudflare Workers through WebAssemblyfrom package metadata and documentation | Node.js 20 or later; browsers and edge runtimesfrom package metadata and documentation | Node.js 20 or later; browser support not documentedfrom package metadata and documentation |
| Install size | 1,885.9 KiB packed5,128.3 KiB unpacked: core, WebAssembly and one platform add-on (linux x64 glibc) | 231.0 KiB packed926.8 KiB unpacked: one package | 756.4 KiB packed3,711.5 KiB unpacked: one package |
| Dependencies | 1 dependency (@redact-secret/wasm); 8 optional platform add-ons | None | None required; 3 optional peers (mammoth, pdf-parse, tesseract.js) |
Informational only: no pass/fail verdict, no ranking assertion (this repository measures and records; see AGENTS.md Boundary rule).
OpenRedaction's detect() is Promise-returning (asynchronous); flare-redact's redact() and redact-secret's scanAndRedact() are synchronous. Each is timed with performance.now() around the actual call, awaited where applicable, so the OpenRedaction figures include at least one Node event-loop microtask tick that the other two tools' figures do not.
redact-secret is measured from the published @redact-secret/core npm package 0.1.0-beta.14 (the pinned release, built from product commit 0c62fd38bca75c5b28b042dc79789b708ebf1d17), not a local build; PII is selected through initialize({ pii }). This run used the Default setting (no PII selectors). flare-redact and OpenRedaction are measured from their published npm packages at their package defaults, so their columns do not change with the setting; they are timed in every setting's run as a reference for how much the machine varied between runs.
Workloads are the ones in qualification/runtime-comparison-v2.json: validator-heavy and multilingual-context are the v1 workloads rendered byte-identically, the others are new and synthetic. Credential values are generated from a seed at run time and never stored; a value that reaches a recorded outcome is replaced by its index.
One setting is measured per process because redact-secret accepts one PII selection per process. The tools run in-process, interleaved round-robin per workload, after two discarded warmup calls each, and each time is the median of the recorded samples.
Outcomes come from one untimed call per distinct line, outside the timed calls. A value counts as hidden when it no longer appears verbatim in the returned text. Outcomes are recorded, never graded.
Every line of these credential texts carries a secret, so each call finds and replaces thousands of them. The times are for text that dense, so they are not comparable with the speeds on the Performance page, which times a different text.
Between the 3 runs the same flare-redact and OpenRedaction calls on the same text moved by up to 108% (most on multilingual-context, OpenRedaction). Read a difference in time smaller than that as noise, not as a result.