# Fast and Secure P2Pv2 Through Resource Budgets

Engineering article by Evan Forbes explaining resource management in Zakura's
P2Pv2 stack. It describes implementation on main, not a new stable release or a
claim of comprehensive denial-of-service resistance.

High throughput and DoS resistance both require resource management. A low
blanket throughput cap would also restrict useful traffic. The stack instead
checks validity and usefulness, authorizes requested responses, and reserves
resources before accepting work. Reservations last until work ends. Capacity
exhaustion delays processing and propagates backpressure to the sender.

## Resource ownership

Frame checks precede payload allocation. Decoders separately bound allocations
that a small payload can request. Verification precedes protected state changes.
A requester records permitted responses and reserves capacity before requesting
data. Responses consume their authorization even if local scheduling changes.
Handlers decide whether further processing remains useful. Repeated records can
renew validity, and empty service lists can clear state.

GetBlocks v3 separately bounds accepted requests, storage execution, retained
results, and output. Serving acquires output capacity and execution slots before
reading storage. Per-peer and node-wide budgets contain commitments. A blocking
read retains its execution slot after a disconnect until the read finishes.
Output stays accounted for while retained or queued.

## Backpressure and progress

The QUIC driver reads on application demand with bounded read-ahead. If the
application stops consuming, the receive buffer fills and QUIC stops granting
credit. The sender can exhaust existing credit before it must wait. Application
queues need their own bounds after data leaves QUIC.

Waiting requests must not trap responses or control messages. Empty responses
still require bounded execution and yielding. Local capacity exhaustion causes
waiting. Only unambiguous protocol violations justify peer penalties.

## Performance and scope

GetBlocks serves finalized blocks as stored bytes without decoding and
re-encoding. Reported Mainnet storage probes on one 16-vCPU host increased
single-block throughput from 23,500 to 53,000 reads/s at the same 24-job limit.
This is a component result, not a synchronization benchmark. Ready responses
can bypass slower reads. Each range retains block order.

The raw response queue retains about 20 MB per session at its bound, excluding
QUIC and downstream allocations. Synthetic small-block probes lost about 5–16%
throughput. Production probes showed no loss or remained inconclusive. These changes are merged but not yet in
a stable release. Transport, application, and connection-count budgets still
jointly determine total memory use.

Sources:
- https://github.com/zakura-core/zakura/pull/1402
- https://github.com/zakura-core/zakura/pull/1403
- https://github.com/zakura-core/zakura/pull/1410#pullrequestreview-5526353537
- https://github.com/zakura-core/zakura/blob/08938dd4156ffa5798136615998131749b918cfc/docs/specs/peer-message-regulation.md

---

Canonical HTML version: https://zakura.com/engineering/p2pv2-resource-budgets/
