Most of the transactions in a block do not touch each other. Alice paying Bob and Carol paying Dave read and write disjoint state; executing them one after the other wastes every core but one. EmpoorioChain's runtime includes a parallel execution engine that exploits this, and this post explains how it works and — importantly — which of its numbers are measured and which are projections.
The model
The design follows the Block-STM family (optimistic parallel execution with deterministic conflict resolution), adapted to Substrate's storage model:
Block of transactions
↓
signed_tx_accesses() analyse each transaction's reads and writes
↓
DeterministicFrameScheduler group transactions into independent batches
↓
rayon::par_iter per batch execute each batch across cores
↓
Merge of state diffs detect real conflicts at commit
↓
Sequential re-execution only for the transactions that actually conflicted
The scheduler is deterministic: given the same block, every node partitions it identically. That is the property that makes parallel execution safe in consensus — the resulting state root must be the same on every validator, and it must equal what strictly sequential execution would produce. A test named assert_parallel_equivalent_to_sequential enforces exactly that, and a correctness invariant checks that the plan covers every transaction exactly once, that independent transactions land in at least one shared batch, and that conflicting ones are separated in a deterministic order.
The whole engine sits behind a feature flag (parallel-execution), so it can be enabled or disabled per build without a breaking change.
Targets
The stated engineering target is ≥ 3,000 TPS for blocks with ≤ 20 % state conflicts. The expected shape of the curve:
| Conflicts in block | Expected | Notes |
|---|---|---|
| 0 % | ≥ 5,000 TPS | Independent transfers, maximum parallelism |
| 20 % | ≥ 3,200 TPS | Mixed block — the minimum target |
| 50 % | ~1,800 TPS | Typical DeFi workload; outside target |
| 100 % | ~500 TPS | Everything conflicts; equivalent to sequential |
Scheduler planning latency scales roughly linearly with block size — around 1.5 ms to plan a 1,000-transaction block with no conflicts on an 8-core laptop, around 16 ms for 5,000 transactions with total conflicts.
What is measured and what is not
Be precise here, because the original documents are. The planning latencies and TPS figures above are projections from the scheduler benchmark (cargo bench --bench parallel_execution), run on a development machine. They are not measurements of the public testnet under real load. The multi-node parallel-execution run (four validators under Zombienet) is prepared — configuration and binary exist — and had not been executed at the time of the last report because Zombienet was not installed in that environment.
Separately, the May 2026 mixed-load testnet benchmark measured 700/700 transactions finalized with a 0 % failure rate, but its sustained throughput did not approach the parallel targets. Those are two different experiments answering two different questions, and conflating them would be exactly the kind of number inflation this ecosystem has decided to stop doing.
Next steps
- Parallel EVM. Apply the same scheduler to Frontier transactions using
revmwith independent state overlays. - Telemetry in EmpooScan. Show, per block, how many transactions executed in parallel versus sequentially.
- Thread-pool tuning based on the validator's core count.
When the four-node run happens, its results will be committed under artifacts/performance/testnet/<date>/ and this post will be updated with measured numbers in place of projected ones.
Based on PARALLEL_EXECUTION_REPORT.md and PERFORMANCE_REPORT.md. Projections are labelled as such in the source and here.


