Monad, measured
Segundo on Monad, measured
We settled the pay of 96 freelancers every second for five seconds, from 16 sender keys at once. Monad put 96 of those payouts in a single block.
Per-second pay only works if many tabs can pay out at the same moment without queueing behind each other. So on October 13, 2026 we opened 96 real tabs on Monad testnet, clocked every freelancer in, and settled all of them every second. Then we sent the same kind of payout from a single key, the way Segundo's relayer worked before this test. Below are the numbers from that run, what they don't prove, and the transactions so you can check them.
Why this is the test that matters
Paying by the second turns one invoice a month into a steady stream of small payouts. Three things decide whether that stream keeps up.
Many tabs pay out together
A studio with a dozen freelancers, or a platform with thousands, settles everyone on the same beat. If payouts queue, the freelancer at the back of the queue watches a number that isn't really theirs yet.
One address sends one thing at a time
Every transaction from an address carries the next number in its sequence (its nonce), and the chain takes them strictly in order. A relayer that pays the gas for everyone from one address is a single queue unless it is built not to be.
Blocks set the pace
A payout is final when it is in a block. Monad made a block every 0.305 s on average over the last 10,000, so a once-a-second payout has about three blocks to land in.
The burst, block by block
Every second for five seconds, each of the 16 sender keys sent one settle for each of its own 6 tabs: 96 payouts a second, 480 in all. Each key kept its own nonce sequence, so no key waited on another.
Show every block as a table
| Block | Ours | Reverted | Others | Block gas used | Seen after first send |
|---|---|---|---|---|---|
| 70,681,931 | 36 | 0 | 1 | 3.0% | 0.81 s |
| 70,681,932 | 0 | 0 | 4 | 1.1% | 0.95 s |
| 70,681,933 | 0 | 0 | 6 | 1.0% | 1.34 s |
| 70,681,934 | 48 | 2 | 6 | 5.4% | 1.56 s |
| 70,681,935 | 60 | 0 | 5 | 7.8% | 1.88 s |
| 70,681,936 | 48 | 2 | 2 | 5.2% | 2.18 s |
| 70,681,937 | 36 | 2 | 8 | 3.9% | 2.48 s |
| 70,681,938 | 60 | 3 | 2 | 4.7% | 2.86 s |
| 70,681,939 | 0 | 0 | 6 | 2.1% | 3.26 s |
| 70,681,940 | 0 | 0 | 3 | 1.5% | 3.40 s |
| 70,681,941 | 96 | 5 | 5 | 6.2% | 3.80 s |
| 70,681,942 | 0 | 0 | 3 | 3.1% | 4.07 s |
| 70,681,943 | 0 | 0 | 2 | 0.3% | 4.40 s |
| 70,681,944 | 96 | 5 | 4 | 8.1% | 4.67 s |
- Second 196 settles landed in 4 blocks, 70,681,931, 70,681,934, 70,681,935, 70,681,936. Median 1.88 s from send to block.
- Second 296 settles landed in 3 blocks, 70,681,934, 70,681,935, 70,681,936. Median 0.99 s from send to block.
- Second 396 settles landed in 2 blocks, 70,681,937, 70,681,938. Median 0.97 s from send to block.
- Second 496 settles landed in one block, 70,681,941. Median 0.92 s from send to block.
- Second 596 settles landed in one block, 70,681,944. Median 0.77 s from send to block.
The first second was the slowest, and not because of Monad: the three public RPC endpoints took 1.85 s just to accept that first batch while connections opened, against about 0.96 s afterwards. By the last two seconds, every tab's payout for that second landed together in one block.
One key or many
The criticism we set out to test: every transaction comes from one relayer address, in nonce order. So we ran the same payouts three ways.
Monad was not the bottleneck; our relayer was. 48 payouts from one fresh key with consecutive nonces all landed in a single block. Segundo's relayer used to send a transaction, wait for its receipt, then send the next, so it topped out near 1.1 payouts a second however fast the chain is. That was fine for a demo and wrong for payroll, so we changed it: the relayer is now a pool of keys that keep many transactions in flight each.
Production needs what this benchmark used: a pool of relayer keys, each sending its own nonces without waiting. With a pool, one stuck transaction holds up only its own key, server instances never race for the same nonce, and no key comes near Monad's limit on fees in flight per account, the lesser of 10 MON and its balance over about three blocks1. At 0.0093 MON a payout, that limit is roughly a thousand payouts in flight per key.
Since this run, Segundo's relayer uses a pool of 7 keys. Each person's actions go to one key chosen from their address (a tab's payouts, from its number), so they stay in order, and each key sends its next transaction without waiting for the last one's receipt.
Why a running tab costs nothing
The other half of per-second pay at scale is not writing to the chain every second. Segundo's contract (deployed under its working name, Till) is built so it doesn't have to.
When a freelancer clocks in, the contract stores one timestamp. From then on nothing is written: what they have earned is worked out from the block's clock whenever anyone asks. Ninety-six tabs running cost the same as none.
Money moves only when a tab is settled, and anyone may settle any tab, because the money can only ever go to that tab's freelancer. That is what let 16 unrelated keys pay 96 people in this test without any of them being trusted.
Who pays out when nobody is watching
Pay is earned every second. While a tab is open on someone's screen, the app asks for a payout every few seconds; when nobody has it open, a keeper settles every running tab that owes at least a cent, every few minutes. Segundo runs one keeper itself, and a second runs as a Chainlink CRE workflow: several nodes each read the running tabs from Monad and fetch exchange rates from three public sources, agree on one report, and SegundoKeeper settles those tabs with settleMany and stores the rates.
Because anyone may settle any tab, neither keeper is trusted with anything: the worst either can do is stop, and then the other, the app or the freelancer settles instead.
What this run does not show
A benchmark is only worth its caveats. These are ours.
Parallel execution
Every settle changes the contract's AUSD balance, one storage slot. Monad runs transactions in parallel optimistically and re-runs any that read something an earlier one changed, with the same result as running them in order2. So these settles conflict with each other, and this run says nothing about how many ran side by side. What it measures is how many landed, how fast, and how full the blocks got.
23 reverts across the three runs
19 in the burst, 3 from the single key sent all at once and 1 sent one at a time. All out of gas, all on the same 5 tabs. Monad charges the whole gas limit, not the gas used3, so to keep the bill down we gave every tab one tight limit taken from the others; those 5 need 92,488 gas, not 84,456. Segundo's relayer estimates each call and adds 15%, and refuses a signed request asking for more than 1.5 times its own estimate. Reverted transactions still landed and count in the throughput.
59 settles with nothing to pay
Block timestamps count whole seconds. When a tab's second settle landed in the same second as its first, there was nothing new earned, so it succeeded and paid nothing. 402 settles moved money.
Public endpoints, one machine
We sent through public RPC endpoints, and the Monad Foundation one allows 50 calls a second per client, so senders were spread over three. Times are from one machine's clock: send to the moment it received the block's header over WebSocket.
Five seconds, testnet, test money
Each payout cost about 0.0093 test MON at testnet gas prices, and the whole exercise, from opening the tabs to closing them and sweeping funds back, cost 11.68 test MON, so we kept the burst short. The tabs paid 0.36 test AUSD an hour and were all closed afterwards.
The pace and the price
Average block time, last 10,000 blocks
0.305 s
Blocks 70,709,207 to 70,719,207, read from Monad testnet when this page was last refreshed (every 10 minutes). During the run it was 0.305 s.
| First payout to a new freelancer | 118,591 |
|---|---|
| Every payout after that | 84,456 |
| Nothing new earned | 31,564 |
| Price paid per unit of gas | 102 gwei |
Check it yourself
Every payout in the run is a public transaction. A few to start with:
- First settle of the burst0x17b4822e…7984a2
- One of 96 settles in block 70,681,9410x71ac4e4b…6836cb
- One of 96 settles in block 70,681,9440x30d38025…6a509e
- One of 48 settles from a single key in block 70,681,9990xcfa891a7…ddfdb6
- A settle sent one at a time, the way the relayer worked before this test0x244500b3…e9c1b6
- One of the reverts (out of gas)0x56e0d8d1…e96f8d
The scripts that ran this are in the repository, with the method and how to run it again: scripts/bench. This page is built from the run's summary, bench.json; the record of every transaction (send time, block, status, amount paid) sits next to the scripts in scripts/bench/out.