CWaptcha's nonce store is the only per-request RAM consumer. Here's exactly how much it uses at any traffic level.
Each issued CAPTCHA token creates one NonceEntry in IMemoryCache. It lives until the nonce is redeemed or the TTL expires.
| Field | Value | Size |
|---|---|---|
Nonce | 64-char hex string | ~154 bytes |
FieldSalt | 32-char hex string | ~90 bytes |
Expiry | DateTimeOffset | 16 bytes |
Used | bool | 1 byte |
| Cache key + IMemoryCache overhead | captchaId key, CacheEntry, dictionary | ~300 bytes |
| Total per entry | ~560 bytes |
At any given moment, only nonces that are still within their TTL window are held in memory. The formula for live entries at steady state:
live_entries = requests_per_second × NonceTtlSeconds
RAM = live_entries × 560 bytes
Example — 10,000 requests per day
10,000 req/day ÷ 86,400 sec/day = 0.116 req/sec
live_entries = 0.116 × 300 = ~35 entries
RAM = 35 × 560 bytes = ~20 KB
Calculated with the default NonceTtlSeconds = 300 (5 minutes) and uniform traffic distribution.
| Daily requests | Req / sec | Live entries | Nonce store RAM |
|---|---|---|---|
| 10,000 | 0.12 | ~35 | ~20 KB |
| 100,000 | 1.16 | ~350 | ~195 KB |
| 1,000,000 | 11.6 | ~3,470 | ~1.9 MB |
| 10,000,000 | 116 | ~34,700 | ~19 MB |
At 10 M requests/day the nonce store uses ~19 MB. The ASP.NET Core runtime baseline is 50–150 MB regardless.
TTL is the single biggest lever. Halving the TTL halves live entries and RAM. All figures below assume 10,000 requests per day.
| NonceTtlSeconds | Relative entries | RAM at 10k/day |
|---|---|---|
| 60 | 0.2× | ~4 KB |
| 300 default | 1× | ~20 KB |
| 600 | 2× | ~40 KB |
| 3600 | 12× | ~240 KB |
Values below 60 s risk rejecting slow connections. Values above 600 s give bots more time to replay a stolen token.
With UseDistributedNonceStore(), nonces are stored in Redis. The app server carries zero per-nonce heap allocation regardless of traffic.
// Moves nonce storage to Redis — zero per-nonce RAM on the app server
builder.Services.AddCWaptcha(builder.Configuration.GetSection("CWaptcha"))
.UseDistributedNonceStore();
See the Multi-Node Deployments section in the README for full setup instructions.
The ASP.NET Core runtime itself uses 50–150 MB at idle, dwarfing the nonce store at any realistic traffic level. CWaptcha adds no background threads, timers, or polling loops — expiry is handled by IMemoryCache's built-in TTL mechanism.