Priority-fill relay
Discussion draft · not for deployment

What if Zcash nodes sent new blocks to their best relayers first?

The same 1,000-node network, twice. With Zebra today, every node splits its upload evenly across every peer that asks for a new block. With priority fill, each node serves the peers most likely to pass the block on first, at full speed, and fills spare upload with the next. Same bytes, same protocol, different order.

Speed
Block — · mined by a random pool node Since mined 0.00 s

Zebra todaycurrent

Uploads shared evenly across all requesters
Nodes reached0
Median node—
Miners reached—
Median miner—
Est. stale rate—

Priority fillproposal

Best relayers first, spare upload to the next
Nodes reached0
Median node—
Miners reached—
Median miner—
Est. stale rate—

Share of the network holding the latest block

Zebra todayPriority fillLast node: — vs —

Reading the picture

Each pillar is a node; its height is upload bandwidth (datacenter, home fiber, cable, rural)
A block upload in flight; the bright head shows progress
The pool that mined the latest block
Nodes light up yellow once they have the full newest block; dim yellow means a block behind
Blocks mined
0
Orphaned · today / fill
0 / 0
Avg est. stale · today / fill
— / —

· 25 s blocks on average, as from NU7 (ZIP 218) · timings are simulated seconds

The proposal

Upload order is a lever nobody is pulling

On 5 November 2026 the NU7 upgrade moves Zcash to 25-second blocks under ZIP 218, down from 75 seconds, with 2 MB blocks unchanged. The same propagation delay will take up three times as large a share of each interval, so relay speed will directly drive orphan rates and how much proof of work actually secures the chain. Most relay work shrinks what is sent, as compact blocks do. This proposal changes something else: the order in which a node uploads a fresh block to the peers asking for it.

Today a Zebra node answers every request at once. Each copy gets an equal slice of upload, so every copy finishes at about the same late moment and no peer can start relaying until then. Priority fill is five rules, applied locally by each node:

  1. Rank requesters by the throughput this node has measured from them in the past.
  2. Serve the best first, at the receiver's full speed.
  3. Fill spare upload: admit the next transfer only when upload sits below 85% for 100 ms, never slowing a running one.
  4. Bound the wait: anything waiting over 5 s is served next regardless of rank.
  5. Demote stalled readers: an upload still running when even a slow honest reader would have finished gives up its slot, and that peer drops down the ranking.

No new messages, no consensus change, no extra bytes. It is the classic Fastest Node First broadcast rule, which scheduling theory shows beats even sharing whenever some receivers matter more than others: sharing delays the important peer without delivering anyone else earlier.

How upload is shared: Zebra today vs priority fill

One node uploading a new block to four peers that asked for it. Band height is the share of the node's upload each peer gets; the total upload is the same in every schedule.

Time, in units of one block sent at the node's full upload speed

With fair sharing, no peer that will relay the block has it until time 4.0, so nobody can pass it on before then. Sending strictly one at a time gets relayer A going at 1.7 but leaves upload idle whenever a peer downloads slower than the node can send. Priority fill gets A, B and C relaying at 1.7, 2.2 and 3.0 without wasting upload; the slow peer D, which relays to no one, waits until last.

Why it matters

Orphan rates are a decentralisation problem

A stale (orphaned) block is honest work thrown away. A pool never orphans its own blocks, so the network's stale rate is paid mostly by everyone else. A pool's edge over a small miner is roughly the difference in their hashrate shares times the stale rate. With the largest Zcash pool near 46% of hashrate, every point of stale rate becomes a revenue advantage that pulls miners toward the biggest pool.

16.2% → 6.0%Blocks orphaned at 25 s with Poisson block arrivals, 1,000-node model
10.0% → 3.6%Estimated stale rate at 25 s, 100-node testbed on Zebra's networking code
7.3% → 2.7%Revenue edge of a 46% pool over a 1% pool in the model (0.2% today at 75 s)
ScenarioStale rateHashrate to out-mine network46% pool edge over 1% pool
Mainnet today, 75 s blocks0.4%49.9%0.2%
25 s blocks, Zebra today, 100-node testbed10.0%47.4%4.5%
25 s blocks, priority fill, 100-node testbed3.6%49.1%1.6%
25 s blocks, Zebra today, 1,000-node model, Poisson arrivals (orphans counted)16.2%45.6%7.3%
25 s blocks, priority fill, 1,000-node model, Poisson arrivals (orphans counted)6.0%48.5%2.7%

Stale blocks also lower the bar for attacks. An attacker mining privately wastes nothing, so with a stale fraction s they need (1 − s) / (2 − s) of total hashrate rather than half. And faster delivery of honest blocks narrows the race window that selfish mining relies on.

Close blocks carry the risk. Block arrivals follow a Poisson process, so about a quarter of blocks come within 7 s of the previous one. In the model, today's relay orphaned 64% of those; priority fill, 26%. With a fixed 25 s schedule the same model orphans almost nothing, which is why Poisson arrivals matter. Priority fill at 25 s orphans about as many blocks (6.0%) as today's relay does at today's 75 s (5.2%).

A separate, simpler fix. zebrad waits 7 s between block announcements, a spacing its code says was sized for 75 s blocks. With Poisson arrivals at a 25 s mean it holds back about a quarter of blocks. Removing it in the model cut orphans to 13.4% under today's relay and 3.9% with priority fill.

These figures assume equal-hashrate miners and full 2 MB blocks; the model orphans 5.2% of blocks at 75 s where mainnet sees 0.4%. Real hashrate is concentrated and compact blocks would shrink most transfers, both of which lower real stale rates. Read the numbers as direction and rough size, not mainnet predictions.

The honest part

What it costs, and why it is not ready

  1. It needs learned rankings. Freshly started nodes recovered only about a quarter of the gain in the testbed.
  2. The slowest nodes do not gain. Home nodes rank low and wait in upload queues; in the testbed the slowest 10% received blocks no sooner.
  3. Rankings can be gamed. Ten slow-reading attackers that looked fast, then stalled, delayed the network's slowest nodes by 0.8 s, although miners still got blocks twice as fast. Demotion, now built and tested, halved that to 0.4 s: blunted, not removed.
  4. It adds complexity to a security-critical path. The first fairness bounds tried silently cost two thirds of the gain.

The paper sets out further mitigations (per-prefix caps, a random reserve slot as in BitTorrent) and seven open questions. Poisson block arrivals have not yet been tested on Zebra's own code: the single-machine testbed ran out of memory when blocks overlapped. It is a starting point for discussion with the Zebra team and the community, not a proposal to ship.

About this simulation

How the model works

1,000 nodes are spread across five regions, with link latency growing with distance (8–160 ms one way). Each node is a datacenter (30%, 500/500 Mb/s), home fiber (25%, 100/500), home cable (35%, 15/150) or rural (10%, 3/25) connection, varied ±35%, and opens Zebra's default 25 outbound connections to nodes that accept inbound ones. Relay follows Zebra's pull model: a node announces a validated block to a random third of its peers, each peer fetches from the first announcer it hears, a request that takes over 20 s is retried elsewhere, relays wait 7 s between announcements as zebrad does, and validation takes 50 ms. Blocks arrive as a Poisson process; several can be in flight at once, competing for bandwidth, and miners build on the first block they see, so orphans are counted directly. Uploads share a node's bandwidth evenly (left) or follow priority fill, with demotion, using each node's ±50%-noisy view of its peers (right). The estimated stale rate is the chance another miner finds a competing block before this one reaches it, averaged over 40 pool nodes.

Run at 100 nodes with a fixed schedule, this model gives estimated stale rates of 9.1% and 2.7%, close to the testbed's 10.0% and 3.6%. At 1,000 nodes there are more hops and more chances to wait on a slow uploader, so today's relay degrades further while priority fill holds up.

Join the discussion

Challenge the assumptions

Everything is public: the paper, the Zebra patches, the 100-node testbed, every node log, and this page's model. Criticism of the assumptions is the most useful contribution.

Code, data and paper →github.com/onemanbillion/zcash-priority-fill-relay Discuss on the forum →Zcash Community Forum thread

Watch the 2-minute explainer · Read the paper (PDF) · ZIP 218