Sizing and measured performance

The first question after "is it secure" is "how many developers will it hold". This document answers it with numbers from a run anyone can repeat together with the caveats that make those numbers honest. Where the measurement does not support a claim the claim is not made.

Everything below was measured rather than modelled.

The measurement

Thirty environments on a kind cluster installed through the Helm chart exactly as a customer installs it and held under load for five minutes. The script is hack/load.sh.

It creates N environments through the API and waits for each to report Ready. It then drives the read path with concurrent clients and soaks with several writers appending to the audit chain. Finally it verifies the chain. Results land in .load-results/.

Results

Measured 2026-09-12 on an Apple M4 Pro with 14 cores and 24 GiB RAM on macOS 26.5.2. Docker Desktop had 14 CPUs. The cluster was single-node kind with one API replica and one operator replica.

Environment creation

Environments requested 30
Reached Ready 30 of 30
Time to Ready p50 6.3 s rising to p95 7.3 s with a max of 7.3 s
Wall clock for all 30 34 s with six creates in flight

Measured from the API accepting the create to the Environment reporting Ready — the reconcile and the pod scheduling and the routing update. That is what a developer actually waits for.

These were shared-mode environments that deploy a prebuilt image. Building from source adds the build. That depends on your repository and registry and is not included here.

API read load

Load 20 concurrent clients for 60 s on GET /environments
Throughput 290 requests/second
Errors 0 non-2xx out of 17411
Latency p50 13 ms rising to p95 24 ms and p99 78 ms with a max of 128 ms

This is the endpoint a dashboard polls with 30 environments in the workspace.

Soak with sustained audit appends

Duration 5 minutes with 4 concurrent writers
Writes 12640 with 0 errors
Latency p50 8 ms rising to p95 15 ms and p99 17 ms with a max of 28 ms
Audit chain after verifies intact

Every write appends to the hash chain and that cannot be parallelised inside the database — each entry hashes onto the previous one. Four concurrent writers is the shape that would expose that as a bottleneck and at this rate it is not one: write latency is lower than read latency because a read serialises 30 environments and a write appends one row.

What this supports

Tested to 30 concurrent environments on a 14-core laptop with the API answering 290 reads/second at a p99 of 78 ms and sustaining 42 audited writes/second with the chain intact.

For a rough sense of scale: a team of 200 developers where each creates a couple of environments a day and has a browser polling the dashboard is nowhere near any of these figures. The single-replica decision assumed "a few hundred developers doing occasional writes". Nothing measured here contradicts that.

What this does not support

Read this part before quoting the numbers above.

Rules of thumb

Until you have measured your own cluster:

Repeating this

Run hack/load.sh to repeat it on kind. ENVS=60 SOAK=30m hack/load.sh changes the size and the length. On your own cluster any load tool works: create environments through the API or the CLI in parallel and hold them for the soak period. Read the API latency from nezal_api_request_duration_seconds at /metrics and the time to Ready from each Environment's conditions.

The script fails if the audit chain does not verify at the end. That is not decoration: this measurement is how a canonicalisation bug in the audit chain was found. The chain reported tampering on a log nobody had touched.