The manual.
Everything you need to read pev correctly: how the metrics are computed, what they mean for your contract, what the data covers, and where the limits are. No marketing prose; just the manual.
What pev is
pev (Parallel Execution Visualizer) is a free developer tool for Monad mainnet. It traces every block as it lands and reconstructs what would have happened if the txs had run in true parallel: which transactions touch the same storage slots, which ones blocked which, and how many sequential rounds were forced by contention.
Built by Silk Nodes. The data is theoretical parallelism: we compute what the conflict graph allows, not what Monad's actual scheduler picked. That's intentional. The scheduler decisions are internal and not exposed via RPC; the conflict structure is observable and reproducible, and it's what you can actually fix in your contract.
How parallel execution works on Monad
Monad doesn't process transactions one at a time. It runs them in parallel, many at once, across separate execution lanes. The catch: when two transactions touch the same storage slot in the same block, the chain has to run one first and re-execute the other once it finishes.
That re-execution is the cost of contention. A block with 30 txs that all touch distinct state can finish in one round. A block with 30 txs all writing to the same global counter has to run sequentially, 30 rounds deep, because each tx invalidates the next. Real workloads sit between those extremes.
The shape of your contract decides where on that spectrum you land. Contracts with isolated state (per-user balances, sharded counters) parallelize cleanly. Contracts with hot shared state (a single global counter, a shared queue, a contended AMM pool) become the chokepoint everyone else waits on.
pev's job is to make that shape visible. Every block page, every contract page, every analytics view is downstream of one question: which transactions blocked which, and on what slot.
Metrics glossary
Parallelism Score
A 0-100 measure of how parallel-friendly a block is. 100 means every transaction could have run in parallel; no contention. 0 would be every transaction blocking the next one, fully serial. Real Monad blocks typically land between 60 and 95. Computed as the ratio of tx count to required execution waves: a 30-tx block that fits in 2 waves scores around 93; the same block forced into 10 waves scores around 70.
Execution Waves
The minimum number of sequential rounds the block needs because of conflicts. Wave 1 runs everything that has no upstream dependency. Wave 2 runs everything blocked only by Wave 1 results. And so on. A block with depth 1 is fully parallel. A block with depth 5 had a chain of 5 transactions where each one couldn't start until the previous finished. Useful for spotting stack-of-dependent-writes patterns vs. broad parallel work.
Hot Storage Slot
A storage slot (a specific 32-byte location at a specific contract) touched by 2 or more transactions in the same block. Hot slots are the literal bottleneck: every tx that wants to read or write a hot slot has to wait for the txs that already wrote it in this block to commit. pev ranks hot slots by conflicts caused (how many tx-pair conflict edges in this block share this slot), then by touches (how many txs touched it at all). The top slot on a contract page is usually the line of Solidity worth re-architecting.
Write-Write Conflict
Two transactions in the same block both wrote the same storage slot. One has to win the race, the other is re-executed. About 94% of all conflicts we observe on Monad mainnet are write-write, dominated by hot counters and shared pool state.
Read-Write Conflict
One transaction read a slot that another transaction in the same block wrote. The reader has to retry after the writer commits. About 1% of observed conflicts. Rare because most reads are of slots that don't get written in the same block.
Mixed Conflict
A pair of transactions that conflict on multiple slots, with at least one write-write and at least one read-write among them. About 5% of conflicts. Common in transactions that touch several pieces of shared state at once (router contracts, complex AMM paths).
Conflicts Caused
On the contract page, the count of conflict edges where this contract owned the hot slot. A contract with high "conflicts caused" is putting load on the execution lane, regardless of how many of its own txs were the ones blocked.
How to use pev
I have a contract on Monad and want to know if it's a bottleneck
- 01Open /contract/<your-address>. Default view is the last 7 days.
- 02Read the verdict line at the top: Healthy, Bottlenecked, or Throughput-killer. That's pev's one-line take.
- 03Scroll to Hot Storage Slots. The top entry is the most contested location in your contract. If you can refactor that one slot, you'll move the score.
- 04Scroll to Methods Causing Conflicts. Groups conflicts by 4-byte selector so you can see which function (mint, swap, claim, etc.) is responsible for what share.
- 05If you've made a change and want to compare, use the window selector at the top: 1h, 24h, 7d, 30d, all-time. Each window queries fresh.
I want to know what the busiest contracts on Monad look like
- 01Open /analytics. The page is refreshed every 5 minutes from a pre-aggregated cache, so it loads in <1s.
- 02The Top conflict-causing contracts list ranks contracts by total conflicts in the window. Click any one to see the per-contract breakdown.
- 03Top hot slots ranks specific (contract, slot) pairs, useful for finding the single 32-byte location creating the most contention chain-wide.
- 04Methods, Conflict kinds, and Wave depth distribution let you see the chain's overall shape.
I have a transaction hash from my dapp and want to debug it
- 01Open /tx/<hash>. We show you the block it landed in, the wave it executed in, what other txs it conflicted with, and which storage slots it touched.
- 02Click any conflict edge to jump to the other transaction. The conflict graph lets you trace the chain of dependencies.
I want to share a finding with my team
- 01Every page generates a dynamic OG card. Paste the URL into Twitter, Discord, Slack, Telegram and the preview shows the real numbers.
- 02Per-block, per-contract, per-tx, and the landing page all have their own card variants.
Data coverage and caveats
Honest disclosures about what pev does and doesn't see. None of these are bugs; they're the cost of operating on live mainnet data with public RPCs.
History depth: ~12 days, growing
Our indexer started on Monad mainnet on April 25, 2026 and has been live-tailing the chain head since. Older blocks are not currently indexed. We may run a backfill if there's demand, otherwise the window grows naturally as the indexer runs.
DELEGATECALL targets may be missing
When a tx calls a proxy that DELEGATECALL's to an implementation, storage changes happen at the proxy's address, not the impl's. prestateTracer (the RPC tracer we use) doesn't surface the impl address in that case. So proxy implementations may show as "not seen" in pev even when they execute constantly. Custom JS tracers would fix this; the RPC we currently use doesn't support them. We're tracking this as a known limitation, not a bug.
Sourcify name coverage is thin
We resolve contract names via Sourcify. Coverage on Monad mainnet is still early, so most contracts show as short hex (0xab12…cd34) rather than human names. If you want yours labeled, verify it at sourcify.dev and pev will pick the name up automatically.
Aggregates lag real-time by a few minutes
The /analytics page reads from a cache refreshed every 5 minutes. Per-contract aggregate lookups read from a cache refreshed every 15 minutes. Live per-block and per-tx pages compute on demand from the same data the indexer just wrote, so those are real-time. The lag is a fast-page-load trade.
Parallelism scores are theoretical, not actual
Every metric on this site is computed from the conflict graph prestateTracer produces. It tells you the maximum speedup the block's conflict structure permits. It doesn't tell you what Monad's actual scheduler picked, which is an internal decision not exposed via RPC. Score 80 means "this block could have run 80% as parallel as it had transactions to support." The actual execution may have been better or worse depending on scheduler choices.
Re-execution cost is reported, not modeled
pev counts conflict edges and execution waves. It doesn't model the exact gas cost of re-execution under Monad's specific re-execution rules. Treat wave count as a relative signal across contracts and blocks, not as an absolute throughput dollar figure.
API reference
pev exposes a handful of read-only JSON endpoints under /api/v1/. All endpoints are public, no auth required, no rate limit configured today. Stable surface; we'll version-bump if we have to break anything.
/api/v1/leaderboard/:kind?window=&limit=parallel, blocked, busy, or top hot slots ( hotspots) over a time window. window ∈ 1h | 24h | 7d | all. Default 24h, limit 20./api/v1/stats/api/v1/block/:number/api/v1/tx/:hash/api/v1/debug/contract/:address/api/og/landing | /api/og/block/:n | /api/og/contract/:addr | /api/og/analyticsIf you're building on this surface and want stability guarantees, open a feedback note: info@silknodes.io. If you start to see rate limits, we'll publish them here.
About + contact
pev is built and operated by Silk Nodes, a professional blockchain infrastructure provider running validators, dedicated RPC nodes, and white-label services on a self-owned, globally distributed network with a zero-slashing track record. pev runs on the same redundant infrastructure that backs our validator and RPC operations, built as a developer tool to make Monad mainnet observable for the teams shipping on it.
Bug reports, feature requests, weird data, "why doesn't my contract show up?", all welcome at info@silknodes.io. We read everything.