Performance
How long zn-gate takes: the agent hooks and the local scanner, with the version, date, machine and method of each measurement.
zn-gate runs on your machine, so its cost is time on every tool call, not a network round trip. This page gives the measured figures, says which version and day each one comes from, and what they do not cover. These numbers are measurements on one machine, not a promise of the same speed on yours.
Agent hooks
Each time a coding agent calls a tool, it starts the zn-gate hook and waits for it: once before the call (for example a shell command) and once after it, with the tool's output.
Measured on 2026-10-17 on a GitHub Actions ubuntu-latest runner (4 vCPU AMD EPYC 7763) with Node.js 22.23, using the hook code of the zn-gate repository on that day (package version 1.11.0). Times are in milliseconds. A bare node -e "" takes 25 ms (p50) on the same machine.
| Agent | Event | p50 (ms) | p95 (ms) |
|---|---|---|---|
| Claude Code | PreToolUse, shell command | 51 | 54.7 |
| Codex CLI | PreToolUse, shell command | 52 | 53.8 |
| Cursor | beforeShellExecution | 51.7 | 58.6 |
| Claude Code | PostToolUse, 1 KB | 63 | 65 |
| Codex CLI | PostToolUse, 1 KB | 62.2 | 65.3 |
| Cursor | postToolUse (MCP), 1 KB | 62.2 | 64 |
| Claude Code | PostToolUse, 100 KB | 67.5 | 70.4 |
| Codex CLI | PostToolUse, 100 KB | 67 | 68.8 |
| Cursor | postToolUse (MCP), 100 KB | 66.9 | 68.9 |
| Claude Code | PostToolUse, 100 KB with 2 secrets | 73.8 | 76.3 |
| Codex CLI | PostToolUse, 100 KB with 2 secrets | 74.7 | 77.5 |
| Cursor | postToolUse (MCP), 100 KB with 2 secrets | 75.9 | 77.9 |
| Claude Code | PostToolUse, 1000 KB | 85.8 | 89.4 |
| Codex CLI | PostToolUse, 1000 KB | 86.4 | 88.5 |
| Cursor | postToolUse (MCP), 1000 KB | 88.9 | 92.3 |
Most of this time is Node.js starting up. Reading the table: a shell command costs about 50 ms before it runs, and a tool result of up to 1000 KB about 90 ms at most (p95). Cursor only lets zn-gate rewrite MCP output, which is why its post-call rows are for MCP tools. OpenCode is not in the table: its zn-gate plugin runs inside the OpenCode process, so no hook process is started.
How the hooks were measured
- The benchmark starts
node lib/hooks/runner.js <agent>with the agent's event on stdin, exactly as the agent does, and times it until the process exits. - Outputs are 1 KB, 100 KB (also with two secrets in it) and 1000 KB of source-like text.
- The vault is locked, so detected values are redacted for good and no background process is involved.
- Each case runs 40 times after one warm-up run. p95 is the 38th of the 40 times (nearest rank).
- Fake values are generated for each run. A case fails if one of them comes back from the hook, if the hook could not check the output, or if a case with secrets has no zn-gate marker in place of them.
A CI check runs this benchmark on every change to the hook code. It compares each case's p95 divided by Node's start-up time in the same run, so a faster or slower machine does not change the result much, and fails when that ratio is more than 20 % above the stored baseline.
Local scanner
The scanner is the part of zn-gate that checks text with its rules and redacts secrets. It runs inside the process, with no network. There are two measurements, taken at different times on an AWS machine with an Intel Xeon Platinum 8259CL. Both used benign inputs that the scanner had not seen before (no cache).
Checking a tool result (rules and secret redaction)
Measured on 2026-10-11 with zn-gate 1.4.1, on a 2-vCPU AWS machine with Node.js 24. This is the whole check_tool_result call, in process. p50 is the median of 3 runs and p99 is the worst of the 3.
| Input size | p50 (ms) | p99 (ms) |
|---|---|---|
| 200 B | 0.045 | 0.19 |
| 4 KB | 0.30 | 0.81 |
| 64 KB | 3.8 | 6.7 |
Rules alone
Measured on 2026-10-10 with zn-gate 1.4.0 (rules version 2026-09-29.1), on a 2.5 GHz machine with Node.js 24.21, 20,000 samples per size. This is the rules check without secret redaction.
| Input size | p50 (ms) | p95 (ms) |
|---|---|---|
| 200 characters | 0.013 | 0.028 |
| 1,000 characters | 0.047 | 0.077 |
| 4,000 characters | 0.173 | 0.372 |
| 16,000 characters | 0.681 | 1.179 |
The rules take under 0.1 ms (p50) for inputs up to about 1,000 characters. Time grows in proportion to the length of the input, so do not read that figure for much longer text.
Limits
- The hook figures come from one CI runner. On your computer the times will differ; most of the difference follows Node.js start-up, not zn-gate.
- The scanner figures were measured on zn-gate 1.4.0 and 1.4.1. They have not been measured again on later versions, and this page does not present them as such.
- The scanner figures are for text that the scanner has not seen before; they are in process and do not include starting Node.js or the agent.
- This page does not cover the optional cloud check, which adds a network call and is not part of the local figures. No end-to-end latency for it is published here.
- The numbers are medians and high percentiles of a few runs on one machine each, not guarantees.
The benchmark scripts and the measurement files are in the bench folder of the zn-gate repository. Related pages: Secret redaction and Configuration.