Latency

Latency, measured and estimated

If you’ve seen 42 µs or 62 µs next to our name: neither was ever measured inside an enclave. Here is every number we have, what each one measures, and our best estimate for the full trip through one.

The short answer

  • Signing takes about 40 µs. The median was 39.1 µs on an Apple M2 laptop and 41.2 µs on a shared Linux runner. Measured
  • The band is narrow. On the laptop, the middle half of 200,000 signatures fell within 0.13 µs of each other, and 97.7% within 5 µs of the median. Measured
  • Through a Nitro Enclave, expect about 120 µs, most of it the trip in and out. We haven’t measured that yet. Estimate
  • So, 42 or 62? Neither is an enclave number. 62 was the 99th percentile of one benchmark of signing alone, on a shared CI machine in May; that run’s median was 41.2. We have no recorded run behind 42.

Two questions in one

“Is it 42 or 62?” mixes two questions. Where does a typical signature land? And how far do the slow ones stray from it? The first depends on the machine and on everything around the signature, and for the enclave we can only estimate it today. The second is about the work itself, and that we can measure now. The answer is that the band is narrow, because every signature does the same fixed amount of work.

What we measured

Each run times one call to SigningKey::sign in RustCrypto k256 0.13.4: it hashes a 256-byte message with SHA-256, then signs it with ECDSA on the secp256k1 curve, using deterministic nonces (RFC 6979). Nothing else is inside the timer: no enclave, no vsock, no network, no policy check. We ran it 200,000 times on an Apple M2 laptop that was doing its usual work, and kept every sample.

Figure 1. 200,000 signatures, one narrow spike

Share of signatures in each half-microsecond bin. Apple M2 laptop, 8 November 2026. Signing alone.

How long 200,000 signatures took on an Apple M2Histogram in half-microsecond bins from 38 to 64 microseconds. 83.5% of signatures fall in the 39.0 to 39.5 bin. Median 39.1; 99 in 100 below 47.4; 999 in 1,000 below 54.0.020%40%60%80%38.5 to 39.0 µs: 7,615 signatures (3.81%)39.0 to 39.5 µs: 167,010 signatures (83.51%)39.5 to 40.0 µs: 1,766 signatures (0.88%)40.0 to 40.5 µs: 11,655 signatures (5.83%)40.5 to 41.0 µs: 523 signatures (0.26%)41.0 to 41.5 µs: 463 signatures (0.23%)41.5 to 42.0 µs: 2,160 signatures (1.08%)42.0 to 42.5 µs: 1,906 signatures (0.95%)42.5 to 43.0 µs: 1,192 signatures (0.60%)43.0 to 43.5 µs: 617 signatures (0.31%)43.5 to 44.0 µs: 473 signatures (0.24%)44.0 to 44.5 µs: 575 signatures (0.29%)44.5 to 45.0 µs: 615 signatures (0.31%)45.0 to 45.5 µs: 321 signatures (0.16%)45.5 to 46.0 µs: 305 signatures (0.15%)46.0 to 46.5 µs: 318 signatures (0.16%)46.5 to 47.0 µs: 283 signatures (0.14%)47.0 to 47.5 µs: 257 signatures (0.13%)47.5 to 48.0 µs: 206 signatures (0.10%)48.0 to 48.5 µs: 172 signatures (0.09%)48.5 to 49.0 µs: 180 signatures (0.09%)49.0 to 49.5 µs: 155 signatures (0.08%)49.5 to 50.0 µs: 129 signatures (0.06%)50.0 to 50.5 µs: 140 signatures (0.07%)50.5 to 51.0 µs: 162 signatures (0.08%)51.0 to 51.5 µs: 173 signatures (0.09%)51.5 to 52.0 µs: 177 signatures (0.09%)52.0 to 52.5 µs: 71 signatures (0.04%)52.5 to 53.0 µs: 58 signatures (0.03%)53.0 to 53.5 µs: 53 signatures (0.03%)53.5 to 54.0 µs: 67 signatures (0.03%)54.0 to 54.5 µs: 58 signatures (0.03%)54.5 to 55.0 µs: 41 signatures (0.02%)55.0 to 55.5 µs: 12 signatures (0.01%)55.5 to 56.0 µs: 10 signatures (0.01%)56.0 to 56.5 µs: 3 signatures (0.00%)56.5 to 57.0 µs: 5 signatures (0.00%)57.0 to 57.5 µs: 3 signatures (0.00%)57.5 to 58.0 µs: 3 signatures (0.00%)58.0 to 58.5 µs: 4 signatures (0.00%)58.5 to 59.0 µs: 3 signatures (0.00%)59.0 to 59.5 µs: 2 signatures (0.00%)59.5 to 60.0 µs: 1 signatures (0.00%)60.0 to 60.5 µs: 1 signatures (0.00%)60.5 to 61.0 µs: 3 signatures (0.00%)61.5 to 62.0 µs: 3 signatures (0.00%)62.0 to 62.5 µs: 2 signatures (0.00%)62.5 to 63.0 µs: 1 signatures (0.00%)63.0 to 63.5 µs: 2 signatures (0.00%)63.5 to 64.0 µs: 1 signatures (0.00%)3840424446485052545658606264microseconds per signatureMedian 39.1 µsMiddle half: 39.08 to 39.21 µs99 in 100below 47.4 µs999 in 1,000below 54.0 µsHow long 200,000 signatures took on an Apple M2Histogram in half-microsecond bins from 38 to 64 microseconds. 83.5% of signatures fall in the 39.0 to 39.5 bin. Median 39.1; 99 in 100 below 47.4; 999 in 1,000 below 54.0.020%40%60%80%38.5 to 39.0 µs: 7,615 signatures (3.81%)39.0 to 39.5 µs: 167,010 signatures (83.51%)39.5 to 40.0 µs: 1,766 signatures (0.88%)40.0 to 40.5 µs: 11,655 signatures (5.83%)40.5 to 41.0 µs: 523 signatures (0.26%)41.0 to 41.5 µs: 463 signatures (0.23%)41.5 to 42.0 µs: 2,160 signatures (1.08%)42.0 to 42.5 µs: 1,906 signatures (0.95%)42.5 to 43.0 µs: 1,192 signatures (0.60%)43.0 to 43.5 µs: 617 signatures (0.31%)43.5 to 44.0 µs: 473 signatures (0.24%)44.0 to 44.5 µs: 575 signatures (0.29%)44.5 to 45.0 µs: 615 signatures (0.31%)45.0 to 45.5 µs: 321 signatures (0.16%)45.5 to 46.0 µs: 305 signatures (0.15%)46.0 to 46.5 µs: 318 signatures (0.16%)46.5 to 47.0 µs: 283 signatures (0.14%)47.0 to 47.5 µs: 257 signatures (0.13%)47.5 to 48.0 µs: 206 signatures (0.10%)48.0 to 48.5 µs: 172 signatures (0.09%)48.5 to 49.0 µs: 180 signatures (0.09%)49.0 to 49.5 µs: 155 signatures (0.08%)49.5 to 50.0 µs: 129 signatures (0.06%)50.0 to 50.5 µs: 140 signatures (0.07%)50.5 to 51.0 µs: 162 signatures (0.08%)51.0 to 51.5 µs: 173 signatures (0.09%)51.5 to 52.0 µs: 177 signatures (0.09%)52.0 to 52.5 µs: 71 signatures (0.04%)52.5 to 53.0 µs: 58 signatures (0.03%)53.0 to 53.5 µs: 53 signatures (0.03%)53.5 to 54.0 µs: 67 signatures (0.03%)54.0 to 54.5 µs: 58 signatures (0.03%)54.5 to 55.0 µs: 41 signatures (0.02%)55.0 to 55.5 µs: 12 signatures (0.01%)55.5 to 56.0 µs: 10 signatures (0.01%)56.0 to 56.5 µs: 3 signatures (0.00%)56.5 to 57.0 µs: 5 signatures (0.00%)57.0 to 57.5 µs: 3 signatures (0.00%)57.5 to 58.0 µs: 3 signatures (0.00%)58.0 to 58.5 µs: 4 signatures (0.00%)58.5 to 59.0 µs: 3 signatures (0.00%)59.0 to 59.5 µs: 2 signatures (0.00%)59.5 to 60.0 µs: 1 signatures (0.00%)60.0 to 60.5 µs: 1 signatures (0.00%)60.5 to 61.0 µs: 3 signatures (0.00%)61.5 to 62.0 µs: 3 signatures (0.00%)62.0 to 62.5 µs: 2 signatures (0.00%)62.5 to 63.0 µs: 1 signatures (0.00%)63.0 to 63.5 µs: 2 signatures (0.00%)63.5 to 64.0 µs: 1 signatures (0.00%)38424650545862microseconds per signatureMedian 39.1 µsMiddle half: 39.08 to 39.21 µs99 in 100below 47.4 µs999 in 1,000below 54.0 µs
83.5% of all signatures landed in the same half-microsecond. The middle half sits between 39.08 and 39.21 µs, three ticks of this machine’s clock. The rare slow ones come from the laptop, not the code: 45 samples (0.02%) took longer than 64 µs, the slowest 275.7 µs, and they’re off the right edge.
Show the numbers
Signatures per bin, Apple M2, 200,000 samples
MicrosecondsSignaturesShare
38.5 to 39.07,6153.807%
39.0 to 39.5167,01083.505%
39.5 to 40.01,7660.883%
40.0 to 40.511,6555.828%
40.5 to 41.05230.262%
41.0 to 41.54630.231%
41.5 to 42.02,1601.080%
42.0 to 42.51,9060.953%
42.5 to 43.01,1920.596%
43.0 to 43.56170.309%
43.5 to 44.04730.237%
44.0 to 44.55750.288%
44.5 to 45.06150.308%
45.0 to 45.53210.161%
45.5 to 46.03050.153%
46.0 to 46.53180.159%
46.5 to 47.02830.142%
47.0 to 47.52570.129%
47.5 to 48.02060.103%
48.0 to 48.51720.086%
48.5 to 49.01800.090%
49.0 to 49.51550.078%
49.5 to 50.01290.065%
50.0 to 50.51400.070%
50.5 to 51.01620.081%
51.0 to 51.51730.087%
51.5 to 52.01770.089%
52.0 to 52.5710.036%
52.5 to 53.0580.029%
53.0 to 53.5530.027%
53.5 to 54.0670.034%
54.0 to 54.5580.029%
54.5 to 55.0410.021%
55.0 to 55.5120.006%
55.5 to 56.0100.005%
56.0 to 56.530.002%
56.5 to 57.050.003%
57.0 to 57.530.002%
57.5 to 58.030.002%
58.0 to 58.540.002%
58.5 to 59.030.002%
59.0 to 59.520.001%
59.5 to 60.010.001%
60.0 to 60.510.001%
60.5 to 61.030.002%
61.5 to 62.030.002%
62.0 to 62.520.001%
62.5 to 63.010.001%
63.0 to 63.520.001%
63.5 to 64.010.001%
64.0 or more450.023%

That spike is the point. Nearly all the signatures took the same time, to within a few ticks of the laptop’s clock. The smaller bumps to the right are the same work, interrupted.

Why the band is narrow

Three things keep it tight.

  • The work never changes. One hash of a fixed-size message and one signature. There’s no branch that does more work for some orders than for others.
  • The library takes the same time whatever the key. k256 is designed so that operations on secret values run in constant time, to resist timing attacks; NCC Group reviewed it in 2023 (their report). A side effect we like: the time doesn’t wander with the input either.
  • There’s nothing to wait for. No network, no disk, no lock, no queue.

What does wander is the machine around the code: an interrupt, another process, the scheduler moving the thread, the CPU changing speed. That is the tail in Figure 2, and it’s why the shared cloud runner, where other jobs compete for the CPU, has a longer tail than the laptop. On a dedicated core with nothing else on it, the tail should shrink. We’ll show that when we’ve measured it, not before.

Figure 2. Same median, different tails

Signing time, in microseconds, that a given share of signatures stayed within. Higher on the right means a longer tail.

Signing time at each percentile, on two machinesApple M2: half under 39.1, 9 in 10 under 40.1, 99 in 100 under 47.4, 999 in 1,000 under 54.0, 9,999 in 10,000 under 100.4 microseconds. Shared Linux runner: half under 41.2, 99 in 100 under 61.7, 999 in 1,000 under 81.6.020406080100Half of them9 in 1099 in 100999 in1,0009,999 in10,000share of signatures at or below the timeµsApple M2 laptop, Half of them: 39.1 µsApple M2 laptop, 9 in 10: 40.1 µsApple M2 laptop, 99 in 100: 47.4 µsApple M2 laptop, 999 in 1,000: 54.0 µsApple M2 laptop, 9,999 in 10,000: 100.4 µsShared Linux runner (x86_64), Half of them: 41.2 µsShared Linux runner (x86_64), 99 in 100: 61.7 µsShared Linux runner (x86_64), 999 in 1,000: 81.6 µs39.141.2100.4 µsApple M281.6 µsLinux runnerSigning time at each percentile, on two machinesApple M2: half under 39.1, 9 in 10 under 40.1, 99 in 100 under 47.4, 999 in 1,000 under 54.0, 9,999 in 10,000 under 100.4 microseconds. Shared Linux runner: half under 41.2, 99 in 100 under 61.7, 999 in 1,000 under 81.6.02040608010050%90%99%99.9%99.99%signatures at or below the timeµsApple M2 laptop, 50%: 39.1 µsApple M2 laptop, 90%: 40.1 µsApple M2 laptop, 99%: 47.4 µsApple M2 laptop, 99.9%: 54.0 µsApple M2 laptop, 99.99%: 100.4 µsShared Linux runner (x86_64), 50%: 41.2 µsShared Linux runner (x86_64), 99%: 61.7 µsShared Linux runner (x86_64), 99.9%: 81.6 µs39.141.2100.481.6
The code does the same work on both machines, so the medians agree within 2 µs. What differs is the machine around it. The shared cloud runner, where other jobs compete for the CPU, stretches the slowest 1 in 100 to 61.7 µs; the laptop keeps it under 47.4. The Linux run reported three percentiles, so its line has three points.
Show the numbers
Microseconds, by the share of signatures at or below
Share of signaturesApple M2 laptopShared Linux runner (x86_64)
Half of them39.141.2
9 in 1040.1not reported
99 in 10047.461.7
999 in 1,00054.081.6
9,999 in 10,000100.4not reported

Through an enclave: our estimate

A Nitro Enclave has no network. Requests reach it over vsock, a socket between the instance and its enclave, and that hop costs more than the signature does. Lutsch, Franck, El-Hindi, István and Binnig measured it for their DaMoN 2025 paper, “An Analysis of AWS Nitro Enclaves for Database Workloads”: on a c6in.8xlarge, a small request and reply took 77.4 µs at the median and 85.5 µs for 99 in 100, with a long tail at 1 in 1,000 (665.4 µs). Their raw data is in their repository. Published

Figure 3. Where the time would go inside an enclave

One signature, from the trading process on the host into the enclave and back. Typical case.

Estimated time for one signature through a Nitro Enclavevsock round trip: 77 microseconds (published); Signing: 40 microseconds (measured); Session crypto, message check, policy: 3 microseconds (estimate). Total about 120 microseconds, estimated.vsock round trip: 77 µs (published)77 µsSigning: 40 µs (measured)40 µsSession crypto, message check, policy: 3 µs (estimate)≈ 120 µsestimatedEstimated time for one signature through a Nitro Enclavevsock round trip: 77 microseconds (published); Signing: 40 microseconds (measured); Session crypto, message check, policy: 3 microseconds (estimate). Total about 120 microseconds, estimated.vsock round trip: 77 µs (published)77 µsSigning: 40 µs (measured)40 µsSession crypto, message check, policy: 3 µs (estimate)≈ 120 µs in total, estimated
vsock round trip: 77 µs, publishedSigning: 40 µs, measuredSession crypto, message check, policy: 3 µs, estimate
The enclave’s cost is the trip in and out, not the signature. The vsock figure is the median that Lutsch and colleagues measured between an instance and its enclave (DaMoN 2025); signing is our median from the runs above; the last few microseconds are our guess for the session’s encryption, reading the request and the policy check. Adding each part’s 99th percentile gives about 150 µs, an upper bound for the slowest 1 in 100.

So our estimate is about 120 µs for a typical signature through the enclave, and under about 150 µs for 99 in 100. Two caveats, both honest. Their benchmark wasn’t tuned for latency the way a signing path will be, with pinned cores and polling instead of sleeping, so the hop may come in lower. And their 1-in-1,000 tail means the far tail through an enclave is an open question. It’s the first thing we’ll measure.

Figure 4. Where these numbers sit

Round trips on AWS from Lutsch, Franck, El-Hindi, István and Binnig (DaMoN 2025, c6in.8xlarge, small messages, medians), next to ours.

Where these numbers sit, on a logarithmic scaleTCP, loopback on one instance: 19.6 microseconds (published); Signing alone: 39.1 microseconds (measured); TCP between two instances, one zone: 49.0 microseconds (published); vsock, instance to its enclave: 77.4 microseconds (published); Through the enclave, our estimate: 120.0 microseconds (estimate); From another instance, through socat: 1,125.6 microseconds (published)10301003001,000microseconds, round trip, on a logarithmic scaleTCP, loopback on one instanceTCP, loopback on one instance: 19.6 µs, published19.6 µsSigning aloneSigning alone: 39.1 µs, measured39.1 µsTCP between two instances, one zoneTCP between two instances, one zone: 49.0 µs, published49.0 µsvsock, instance to its enclavevsock, instance to its enclave: 77.4 µs, published77.4 µsThrough the enclave, our estimateThrough the enclave, our estimate: about 120 µs, estimated≈ 120 µsFrom another instance, through socatFrom another instance, through socat: 1,126 µs, published1,126 µsWhere these numbers sit, on a logarithmic scaleTCP, loopback on one instance: 19.6 microseconds (published); Signing alone: 39.1 microseconds (measured); TCP between two instances, one zone: 49.0 microseconds (published); vsock, instance to its enclave: 77.4 microseconds (published); Through the enclave, our estimate: 120.0 microseconds (estimate); From another instance, through socat: 1,125.6 microseconds (published)10301003001,000microseconds, logarithmic scaleTCP, loopback on one instanceTCP, loopback on one instance: 19.6 µs, published19.6 µsSigning aloneSigning alone: 39.1 µs, measured39.1 µsTCP between two instances, one zoneTCP between two instances, one zone: 49.0 µs, published49.0 µsvsock, instance to its enclavevsock, instance to its enclave: 77.4 µs, published77.4 µsThrough the enclave, our estimateThrough the enclave, our estimate: about 120 µs, estimated≈ 120 µsFrom another instance, through socatFrom another instance, through socat: 1,126 µs, published1,126 µs
Ours, measuredOurs, estimatedPublished by others
An enclave isn’t free. The hop into it costs more than a network round trip between two machines in the same zone. What it buys is isolation: nothing on the host can read the key. The same study found that putting a common TCP-to-vsock proxy (socat) in front of the enclave adds about a millisecond; Sentinel’s host speaks vsock directly.
Show the numbers
Round trips, microseconds
PathMicrosecondsSource
TCP, loopback on one instance19.6DaMoN 2025
Signing alone39.1Measured
TCP between two instances, one zone49.0DaMoN 2025
vsock, instance to its enclave77.4DaMoN 2025
Through the enclave, our estimate120.0Estimate
From another instance, through socat1,125.6DaMoN 2025

Every run

When and whereSignaturesMedian99 in 100999 in 1,000Raw data
15 May 2026, GitHub-hosted ubuntu-latest runner, x86_64. Signing alone; commit 512cd6fc.50,00041.261.781.6latest.json
8 November 2026, Apple M2 laptop, the same benchmark five times. Signing alone; commit c707f9c0.5 × 50,00039.147.5 to 50.253.7 to 79.4m2-2026-11-08.json
8 November 2026, the same laptop, every sample kept. Signing alone.200,00039.147.454.0samples, harness
DaMoN 2025, c6in.8xlarge, published. vsock round trip, instance to enclave, small messages.n/a77.485.5665.4their repository

All figures in microseconds. A 99th percentile from a single run of 50,000 rests on its slowest 500 samples, which is why the laptop’s five runs spread from 47.5 to 50.2 µs while the median never moved.

How it was measured

The timed loop is short enough to read in full:

let signing_key = SigningKey::from_bytes(&[42u8; 32].into())?;
let message = [0xABu8; 256];
for _ in 0..1_000 { let _: Signature = signing_key.sign(&message); }  // warm up

for _ in 0..n {
    let t0 = Instant::now();
    let sig: Signature = signing_key.sign(&message);  // SHA-256, then ECDSA (RFC 6979)
    samples.push(t0.elapsed().as_nanos() as u64);
    black_box(sig);
}
  • The clock is Rust’s monotonic Instant; on this Mac it ticks every 41.7 ns.
  • Percentiles are nearest-rank: the 99th is the sample that 99% of samples are at or below.
  • The build matches the workspace’s release profile: fat LTO, one codegen unit, overflow checks on. This harness’s median matches the repo’s own benchmark to within a tenth of a microsecond.
  • To repeat it, take the harness (its Cargo.toml is in the comment at the top), run cargo build --release, then sign-dist 200000 > samples.txt.

What we measure next

The full round trip from the host process into the enclave and back, on a Nitro-capable instance with pinned cores, a million samples, raw data published. We call it EXP-01. When it’s done, its numbers replace the estimate on this page, whatever they turn out to be.

If you’d like it run on your instances and your workload, that’s what a pilot is for.

A correction

What this page replaces

Until 8 November 2026 this site said “62 µs P99 signing inside AWS Nitro Enclaves”, and drew charts modeled from that one figure. The 62 µs was the 99th percentile of the signing step alone, on a shared CI runner. It was never measured inside an enclave, and the full trip through one will be slower, as the estimate above shows. Earlier versions quoted 42 µs, a figure with no recorded run behind it.