Blockfrost speedup - #2821
Conversation
Also await on the utxo to become available at the address since tx inclusion does not update address query immediately. Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
- Report PostTxError immediately instead of sleeping one block time first. - Keep serving the queue after a failed submission. Previously the client thread exited, which cancelled the race in blockfrostChain and restarted the follower from the startup point: one failed post triggered a full re-sync and re-observation of every block since node start. - Actually inspect the API-level result. tryError only caught IOExceptions, so an API rejection (the inner Either from runBlockfrost) fell into the success branch and was reported as PostedTx. Rejected transactions were invisible to the caller. - Inject the submit action (submitViaBlockfrost adapter) to make the client unit-testable, and add a regression test for immediate reporting and queue continuity after failure. Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
The follower slept one block time and then processed exactly one block per iteration, so it could never advance faster than the chain grows and any lag became permanent. At the tip it was slower still: fetching the unconfirmed tip block threw NotEnoughBlockConfirmations into the retry wrapper, doubling the effective poll period to two block times. Fetch successors with getNextBlocks' (up to 100 full block records per request) instead of chasing _blockNextBlock with one getBlock per block: - catch up any distance in bounded batches without sleeping, and sleep one block time only once caught up to the tip - skip the per-block transaction fetch when the header says tx_count is zero, which is most testnet blocks - keep the one-confirmation policy by only processing blocks that already have a successor, via the confirmations field instead of exception control flow - startup catch-up is no longer a special case and no longer re-observes the block at the persisted start point, matching the direct backend Removes the now-unthrown NotEnoughBlockConfirmations and MissingNextBlockHash error constructors. Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
The test was parked behind pendingWith and rotted: it closed with a hand-signed snapshot claiming a UTxO that was never deposited into the head, which the head validator now correctly rejects with H65 (ChangedHeadAdaOverhead). The DirectChainSpec version of the same test closes with an empty snapshot; apply the same shape here and drop the then-unused second seeding and external key. Exercising a real deposit through Blockfrost remains future coverage work. Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
Nothing handled HTTP 429 responses: runBlockfrostM collapsed every API error into a rendered string and all retry paths treated them alike. Worse, the retry policy used for startup queries had a units bug: the comment promised exponential backoff of 1s..60s, but fullJitterBackoff takes microseconds, so the base was 2ms with no cap and all retries fired within about two seconds. - Distinguish 429 as BlockfrostRateLimited and retry it inside runBlockfrostM with capped exponential backoff (1s, 2s, 4s ... max 60s, at most 6 attempts) before giving up. blockfrost-client does not expose the Retry-After header, so the delay is blind. - Fix the startup retry policy to an actual 1s-base full-jitter backoff capped at 60s, and take the policy as a parameter so tests can use a delay-free one. - Route transaction submission through runBlockfrostM so it inherits the backoff. - Share the backoff constants with hydra-chain-observer's Blockfrost client, which gained the same 429 handling, instead of keeping a drifting copy there. Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
With the Blockfrost backend now polling verifiable conditions, the remaining fixed-delay machinery had no purpose: - Remove the --blockfrost-query-timeout option, its query-timeout config key and api.yaml schema entry; it configured the deleted unconditional pre-query sleep. - Remove getQueryDelay from the ChainBackend class and the 30s settle before each Blockfrost cluster test; reactive rate-limit backoff replaced the only reason they existed. - Shrink the blanket Blockfrost test timeout multiplier from 30x to 3x, since the follower now observes about one block behind the tip. Un-park "can open, close & fanout a Head using Blockfrost": tag it @requiresBlockfrost so the nightly filter actually selects it, and size observation deadlines as 6 block times instead of a fixed 30s. During development on preview, publishing took ~32s and a seeding ~40s, versus roughly 10 and 30 minutes before. Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
e4011a0 to
1d4fe81
Compare
Transaction cost differencesNo cost or size differences found |
End-to-end benchmark differencesComparing this PR ( Sustained load (3 nodes, 3x5000 txs)
Plateau 1000 UTxO (1 node, 4000 txs)
Round-trip latency (3 nodes, closed-loop, 3x250 txs)
|
Transaction costsSizes and execution budgets for Hydra protocol transactions. Note that unlisted parameters are currently using
Script summary
|
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 5477 | 9.85 | 3.25 | 0.49 |
| 2 | 5571 | 9.62 | 3.15 | 0.50 |
| 3 | 5668 | 10.61 | 3.48 | 0.51 |
| 5 | 5861 | 11.42 | 3.73 | 0.53 |
| 10 | 6340 | 13.83 | 4.50 | 0.57 |
| 50 | 10183 | 35.60 | 11.31 | 0.97 |
| 100 | 14983 | 62.17 | 19.63 | 1.45 |
| 114 | 16331 | 69.49 | 21.89 | 1.59 |
Cost of Increment Transaction
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 2321 | 20.59 | 7.33 | 0.47 |
| 2 | 2452 | 21.75 | 8.37 | 0.49 |
| 3 | 2581 | 23.20 | 9.50 | 0.52 |
| 5 | 2846 | 24.46 | 11.23 | 0.55 |
| 10 | 3503 | 29.84 | 16.27 | 0.66 |
| 50 | 8742 | 71.36 | 55.93 | 1.51 |
| 75 | 12018 | 97.94 | 80.93 | 2.05 |
Cost of Decrement Transaction
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 641 | 18.46 | 6.68 | 0.38 |
| 2 | 773 | 19.40 | 7.64 | 0.40 |
| 3 | 903 | 20.35 | 8.61 | 0.42 |
| 5 | 1167 | 22.35 | 10.58 | 0.46 |
| 10 | 1825 | 27.17 | 15.44 | 0.56 |
| 50 | 7067 | 67.53 | 54.73 | 1.40 |
| 75 | 10338 | 93.89 | 79.60 | 1.94 |
Close transaction costs
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 2 | 800 | 18.76 | 12.65 | 0.43 |
| 3 | 931 | 19.72 | 13.62 | 0.45 |
| 50 | 7090 | 68.07 | 60.18 | 1.45 |
| 74 | 10238 | 92.64 | 83.90 | 1.95 |
Contest transaction costs
| Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|
| 1 | 704 | 21.50 | 14.91 | 0.46 |
| 2 | 828 | 22.64 | 15.93 | 0.48 |
| 3 | 964 | 23.75 | 16.95 | 0.51 |
| 5 | 1226 | 26.07 | 19.02 | 0.55 |
| 10 | 1881 | 31.72 | 24.14 | 0.66 |
| 50 | 7121 | 80.17 | 65.91 | 1.59 |
| 66 | 9217 | 98.64 | 82.36 | 1.95 |
FanOut transaction costs
Involves spending head output and burning head tokens. Uses ada-only UTXO for better comparability.
Rows first grow the UTxO set at a fixed 10 parties, then show the largest set that still fits per number of parties (burning more participation tokens leaves less room for outputs).
| Parties | UTxO | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|---|---|
| 10 | 0 | 0 | 5644 | 23.29 | 42.87 | 0.90 |
| 10 | 1 | 57 | 5679 | 25.63 | 45.39 | 0.93 |
| 10 | 5 | 285 | 5814 | 35.88 | 55.71 | 1.10 |
| 10 | 10 | 570 | 5984 | 49.89 | 68.99 | 1.31 |
| 10 | 20 | 1140 | 6324 | 82.42 | 96.97 | 1.79 |
| 1 | 20 | 1138 | 6043 | 76.20 | 95.00 | 1.72 |
| 5 | 20 | 1140 | 6169 | 78.96 | 95.88 | 1.75 |
| 10 | 20 | 1140 | 6325 | 82.42 | 96.97 | 1.79 |
| 20 | 20 | 1139 | 6633 | 89.74 | 99.26 | 1.88 |
| 50 | 15 | 855 | 7396 | 94.70 | 91.88 | 1.90 |
PartialFanOut transaction costs
Largest chunk of ada-only outputs that can be distributed in one partial fanout step, computed dynamically. The last row is the maximum total UTxO count where at least one output can still be distributed.
| Total UTxO | Distributed | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|---|---|
| 11 | 10 | 570 | 983 | 34.91 | 66.33 | 0.95 |
| 25 | 23 | 1310 | 1429 | 68.24 | 99.40 | 1.48 |
| 30 | 23 | 1308 | 1427 | 68.24 | 99.40 | 1.48 |
| 40 | 23 | 1309 | 1428 | 68.24 | 99.40 | 1.48 |
| 50 | 23 | 1309 | 1428 | 68.24 | 99.40 | 1.48 |
| 100 | 23 | 1307 | 1426 | 68.24 | 99.40 | 1.48 |
| 150 | 23 | 1309 | 1428 | 68.24 | 99.40 | 1.48 |
| 200 | 23 | 1310 | 1429 | 68.24 | 99.40 | 1.48 |
| 200 | 23 | 1310 | 1425 | 68.24 | 99.40 | 1.48 |
PartialFanOut transaction costs (with native tokens)
Largest chunk of native-token outputs that can be distributed in one partial fanout step, computed dynamically. The last row is the maximum total UTxO count where at least one output can still be distributed.
| Total UTxO | Distributed | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|---|---|
| 11 | 10 | 1000 | 1473 | 42.00 | 68.83 | 1.05 |
| 25 | 21 | 2058 | 2302 | 76.56 | 99.12 | 1.58 |
| 30 | 21 | 2142 | 2390 | 76.59 | 99.17 | 1.59 |
| 40 | 21 | 1995 | 2236 | 76.56 | 99.11 | 1.58 |
| 50 | 21 | 2079 | 2325 | 76.59 | 99.12 | 1.59 |
| 100 | 21 | 2163 | 2413 | 76.59 | 99.17 | 1.59 |
| 150 | 21 | 2478 | 2743 | 76.56 | 99.22 | 1.60 |
| 200 | 21 | 1974 | 2215 | 76.56 | 99.11 | 1.58 |
| 200 | 21 | 2373 | 2629 | 76.59 | 99.22 | 1.60 |
FinalPartialFanOut transaction costs (with native tokens)
Terminal partial fanout step (FanoutProgress → Final) with outputs carrying a native token. Burns all head tokens and proves accumulator exhaustion via BLS proof.
| Distributed | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
|---|---|---|---|---|---|
| 1 | 100 | 5519 | 22.10 | 44.30 | 0.89 |
| 5 | 490 | 5825 | 35.58 | 55.79 | 1.10 |
| 10 | 1020 | 6251 | 53.90 | 70.62 | 1.37 |
| 10 | 1010 | 6241 | 53.90 | 70.60 | 1.37 |
End-to-end benchmark results
This page is intended to collect the latest end-to-end benchmark results produced by Hydra's continuous integration (CI) system from the latest master code.
Please note that these results are approximate as they are currently produced from limited cloud VMs and not controlled hardware. Rather than focusing on the absolute results, the emphasis should be on relative results, such as how the timings for a scenario evolve as the code changes.
Generated at 2026-08-13 10:54:05.311075051 UTC
Baseline Scenario
| Number of nodes | 1 |
|---|---|
| Number of txs | 300 |
| Avg. Confirmation Time (ms) | 202.5 |
| P99 | 204.7ms |
| P95 | 204.4ms |
| P50 | 202.6ms |
| Tx validation time p50 (ms) | 124.6 |
| End-to-end TPS | 1431.84 tx/s |
| Backlog drain time (s) | 0.2 |
| Snapshots observed | 3 |
| Snapshots per second | 14.32 /s |
| Avg txs per snapshot | 100.0 |
| Peak node RSS (MB) | 144.4 |
| Number of Invalid txs | 0 |
| Fanout outputs | 2 |
Three local nodes
| Number of nodes | 3 |
|---|---|
| Number of txs | 900 |
| Avg. Confirmation Time (ms) | 1006.0 |
| P99 | 1060.1ms |
| P95 | 1058.8ms |
| P50 | 1045.3ms |
| Tx validation time p50 (ms) | 489.8 |
| End-to-end TPS | 836.15 tx/s |
| Backlog drain time (s) | 1.0 |
| Snapshots observed | 3 |
| Snapshots per second | 2.79 /s |
| Avg txs per snapshot | 300.0 |
| Peak node RSS (MB) | 146.2 |
| Number of Invalid txs | 0 |
| Fanout outputs | 4 |
Scenario benchmark results
This page collects results from the scenario matrix: every combination of cluster size, UTxO shape, and incremental-ops mode is exercised by CI from the latest master code and reported below.
Numbers are approximate. They come from cloud VMs rather than controlled hardware, so the useful signal is the relative change between cells and between commits, not the absolute throughput.
Generated at 2026-08-13 11:06:27.336454208 UTC
Summary across cells
TPS columns are rates (transactions per second); Wall clock (s) is the measured elapsed time from the first tx submission to the last confirmation. Times are rounded to one decimal.
| Scenario | Txs | Wall clock (s) | End-to-end TPS (tx/s) | Sustained TPS (tx/s) | Avg conf (ms) | P95 conf (ms) |
|---|---|---|---|---|---|---|
| Nodes=1, Constant, fire and forget | 30 | 0.0 | 1250.03 | n/a | 23.3 | 23.7 |
| Nodes=1, Constant, wait for tx valid | 30 | 0.1 | 210.34 | 206.74 | 4.7 | 6.2 |
| Nodes=1, Growing, fire and forget | 30 | 0.0 | 1036.73 | n/a | 28.2 | 28.7 |
| Nodes=1, Growing, wait for tx valid | 30 | 0.2 | 151.38 | 158.82 | 6.5 | 9.9 |
| Nodes=1, Mixed, fire and forget | 30 | 0.0 | 820.13 | n/a | 35.8 | 36.3 |
| Nodes=1, Mixed, wait for tx valid | 30 | 0.2 | 176.97 | 179.39 | 5.6 | 7.5 |
| Nodes=2, Constant, fire and forget | 60 | 0.1 | 941.88 | n/a | 61.4 | 62.5 |
| Nodes=2, Constant, wait for tx valid | 60 | 0.4 | 139.29 | 134.94 | 14.2 | 20.7 |
| Nodes=2, Growing, fire and forget | 60 | 0.1 | 804.07 | n/a | 72.3 | 73.1 |
| Nodes=2, Growing, wait for tx valid | 60 | 0.6 | 92.86 | 92.98 | 21.3 | 32.0 |
| Nodes=2, Mixed, fire and forget | 60 | 0.1 | 924.13 | n/a | 63.1 | 64.7 |
| Nodes=2, Mixed, wait for tx valid | 60 | 0.6 | 100.21 | 94.71 | 19.7 | 29.3 |
| Nodes=3, Constant, fire and forget | 90 | 0.1 | 650.22 | n/a | 135.8 | 138.1 |
| Nodes=3, Constant, wait for tx valid | 90 | 0.8 | 113.20 | 111.56 | 25.9 | 37.5 |
| Nodes=3, Growing, fire and forget | 90 | 0.2 | 563.87 | n/a | 156.4 | 159.3 |
| Nodes=3, Growing, wait for tx valid | 90 | 1.2 | 72.15 | 72.03 | 40.8 | 54.8 |
| Nodes=3, Mixed, fire and forget | 90 | 0.2 | 516.36 | n/a | 170.9 | 172.8 |
| Nodes=3, Mixed, wait for tx valid | 90 | 1.0 | 86.07 | 82.89 | 34.5 | 43.2 |
Nodes=1, Constant, fire and forget
| Number of nodes | 1 |
|---|---|
| Number of txs | 30 |
| Avg. Confirmation Time (ms) | 23.3 |
| P99 | 23.8ms |
| P95 | 23.7ms |
| P50 | 23.4ms |
| Tx validation time p50 (ms) | 17.3 |
| End-to-end TPS | 1250.03 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 2 |
| Snapshots per second | 83.34 /s |
| Avg txs per snapshot | 15.0 |
| Peak node RSS (MB) | 143.6 |
| Number of Invalid txs | 0 |
| Fanout outputs | 2 |
Nodes=1, Constant, wait for tx valid
| Number of nodes | 1 |
|---|---|
| Number of txs | 30 |
| Avg. Confirmation Time (ms) | 4.7 |
| P99 | 10.6ms |
| P95 | 6.2ms |
| P50 | 4.3ms |
| Tx validation time p50 (ms) | 1.6 |
| End-to-end TPS | 210.34 tx/s |
| Sustained TPS | 206.74 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 30 |
| Snapshots per second | 210.34 /s |
| Avg txs per snapshot | 1.0 |
| Peak node RSS (MB) | 144.4 |
| Number of Invalid txs | 0 |
| Fanout outputs | 2 |
Nodes=1, Growing, fire and forget
| Number of nodes | 1 |
|---|---|
| Number of txs | 30 |
| Avg. Confirmation Time (ms) | 28.2 |
| P99 | 28.7ms |
| P95 | 28.7ms |
| P50 | 28.4ms |
| Tx validation time p50 (ms) | 11.6 |
| End-to-end TPS | 1036.73 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 2 |
| Snapshots per second | 69.12 /s |
| Avg txs per snapshot | 15.0 |
| Peak node RSS (MB) | 144.0 |
| Number of Invalid txs | 0 |
| Fanout outputs | 31 |
Nodes=1, Growing, wait for tx valid
| Number of nodes | 1 |
|---|---|
| Number of txs | 30 |
| Avg. Confirmation Time (ms) | 6.5 |
| P99 | 12.5ms |
| P95 | 9.9ms |
| P50 | 6.2ms |
| Tx validation time p50 (ms) | 1.6 |
| End-to-end TPS | 151.38 tx/s |
| Sustained TPS | 158.82 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 30 |
| Snapshots per second | 151.38 /s |
| Avg txs per snapshot | 1.0 |
| Peak node RSS (MB) | 144.2 |
| Number of Invalid txs | 0 |
| Fanout outputs | 31 |
Nodes=1, Mixed, fire and forget
Each client first grows its UTxO set (1-in to 2-out) for half of its tx budget, then contracts it back (2-in to 1-out) for the remainder.
| Number of nodes | 1 |
|---|---|
| Number of txs | 30 |
| Avg. Confirmation Time (ms) | 35.8 |
| P99 | 36.3ms |
| P95 | 36.3ms |
| P50 | 36.0ms |
| Tx validation time p50 (ms) | 20.9 |
| End-to-end TPS | 820.13 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 2 |
| Snapshots per second | 54.68 /s |
| Avg txs per snapshot | 15.0 |
| Peak node RSS (MB) | 143.4 |
| Number of Invalid txs | 0 |
| Fanout outputs | 2 |
Nodes=1, Mixed, wait for tx valid
Each client first grows its UTxO set (1-in to 2-out) for half of its tx budget, then contracts it back (2-in to 1-out) for the remainder.
| Number of nodes | 1 |
|---|---|
| Number of txs | 30 |
| Avg. Confirmation Time (ms) | 5.6 |
| P99 | 11.1ms |
| P95 | 7.5ms |
| P50 | 5.2ms |
| Tx validation time p50 (ms) | 1.6 |
| End-to-end TPS | 176.97 tx/s |
| Sustained TPS | 179.39 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 30 |
| Snapshots per second | 176.97 /s |
| Avg txs per snapshot | 1.0 |
| Peak node RSS (MB) | 143.9 |
| Number of Invalid txs | 0 |
| Fanout outputs | 2 |
Nodes=2, Constant, fire and forget
| Number of nodes | 2 |
|---|---|
| Number of txs | 60 |
| Avg. Confirmation Time (ms) | 61.4 |
| P99 | 63.0ms |
| P95 | 62.5ms |
| P50 | 61.9ms |
| Tx validation time p50 (ms) | 24.1 |
| End-to-end TPS | 941.88 tx/s |
| Backlog drain time (s) | 0.1 |
| Snapshots observed | 2 |
| Snapshots per second | 31.40 /s |
| Avg txs per snapshot | 30.0 |
| Peak node RSS (MB) | 144.9 |
| Number of Invalid txs | 0 |
| Fanout outputs | 3 |
Nodes=2, Constant, wait for tx valid
| Number of nodes | 2 |
|---|---|
| Number of txs | 60 |
| Avg. Confirmation Time (ms) | 14.2 |
| P99 | 27.1ms |
| P95 | 20.7ms |
| P50 | 13.2ms |
| Tx validation time p50 (ms) | 3.6 |
| End-to-end TPS | 139.29 tx/s |
| Sustained TPS | 134.94 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 60 |
| Snapshots per second | 139.29 /s |
| Avg txs per snapshot | 1.0 |
| Peak node RSS (MB) | 144.8 |
| Number of Invalid txs | 0 |
| Fanout outputs | 3 |
Nodes=2, Growing, fire and forget
| Number of nodes | 2 |
|---|---|
| Number of txs | 60 |
| Avg. Confirmation Time (ms) | 72.3 |
| P99 | 73.7ms |
| P95 | 73.1ms |
| P50 | 72.8ms |
| Tx validation time p50 (ms) | 23.7 |
| End-to-end TPS | 804.07 tx/s |
| Backlog drain time (s) | 0.1 |
| Snapshots observed | 2 |
| Snapshots per second | 26.80 /s |
| Avg txs per snapshot | 30.0 |
| Peak node RSS (MB) | 144.9 |
| Number of Invalid txs | 0 |
| Fanout outputs | 62 |
Nodes=2, Growing, wait for tx valid
| Number of nodes | 2 |
|---|---|
| Number of txs | 60 |
| Avg. Confirmation Time (ms) | 21.3 |
| P99 | 32.8ms |
| P95 | 32.0ms |
| P50 | 20.6ms |
| Tx validation time p50 (ms) | 6.3 |
| End-to-end TPS | 92.86 tx/s |
| Sustained TPS | 92.98 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 60 |
| Snapshots per second | 92.86 /s |
| Avg txs per snapshot | 1.0 |
| Peak node RSS (MB) | 146.1 |
| Number of Invalid txs | 0 |
| Fanout outputs | 62 |
Nodes=2, Mixed, fire and forget
Each client first grows its UTxO set (1-in to 2-out) for half of its tx budget, then contracts it back (2-in to 1-out) for the remainder.
| Number of nodes | 2 |
|---|---|
| Number of txs | 60 |
| Avg. Confirmation Time (ms) | 63.1 |
| P99 | 64.7ms |
| P95 | 64.7ms |
| P50 | 63.0ms |
| Tx validation time p50 (ms) | 22.5 |
| End-to-end TPS | 924.13 tx/s |
| Backlog drain time (s) | 0.1 |
| Snapshots observed | 2 |
| Snapshots per second | 30.80 /s |
| Avg txs per snapshot | 30.0 |
| Peak node RSS (MB) | 144.9 |
| Number of Invalid txs | 0 |
| Fanout outputs | 3 |
Nodes=2, Mixed, wait for tx valid
Each client first grows its UTxO set (1-in to 2-out) for half of its tx budget, then contracts it back (2-in to 1-out) for the remainder.
| Number of nodes | 2 |
|---|---|
| Number of txs | 60 |
| Avg. Confirmation Time (ms) | 19.7 |
| P99 | 32.5ms |
| P95 | 29.3ms |
| P50 | 19.5ms |
| Tx validation time p50 (ms) | 6.7 |
| End-to-end TPS | 100.21 tx/s |
| Sustained TPS | 94.71 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 60 |
| Snapshots per second | 100.21 /s |
| Avg txs per snapshot | 1.0 |
| Peak node RSS (MB) | 145.3 |
| Number of Invalid txs | 0 |
| Fanout outputs | 3 |
Nodes=3, Constant, fire and forget
| Number of nodes | 3 |
|---|---|
| Number of txs | 90 |
| Avg. Confirmation Time (ms) | 135.8 |
| P99 | 138.2ms |
| P95 | 138.1ms |
| P50 | 136.3ms |
| Tx validation time p50 (ms) | 66.1 |
| End-to-end TPS | 650.22 tx/s |
| Backlog drain time (s) | 0.1 |
| Snapshots observed | 2 |
| Snapshots per second | 14.45 /s |
| Avg txs per snapshot | 45.0 |
| Peak node RSS (MB) | 145.9 |
| Number of Invalid txs | 0 |
| Fanout outputs | 4 |
Nodes=3, Constant, wait for tx valid
| Number of nodes | 3 |
|---|---|
| Number of txs | 90 |
| Avg. Confirmation Time (ms) | 25.9 |
| P99 | 40.8ms |
| P95 | 37.5ms |
| P50 | 24.5ms |
| Tx validation time p50 (ms) | 6.7 |
| End-to-end TPS | 113.20 tx/s |
| Sustained TPS | 111.56 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 61 |
| Snapshots per second | 76.72 /s |
| Avg txs per snapshot | 1.5 |
| Peak node RSS (MB) | 145.0 |
| Number of Invalid txs | 0 |
| Fanout outputs | 4 |
Nodes=3, Growing, fire and forget
| Number of nodes | 3 |
|---|---|
| Number of txs | 90 |
| Avg. Confirmation Time (ms) | 156.4 |
| P99 | 159.4ms |
| P95 | 159.3ms |
| P50 | 157.7ms |
| Tx validation time p50 (ms) | 54.3 |
| End-to-end TPS | 563.87 tx/s |
| Backlog drain time (s) | 0.2 |
| Snapshots observed | 2 |
| Snapshots per second | 12.53 /s |
| Avg txs per snapshot | 45.0 |
| Peak node RSS (MB) | 146.1 |
| Number of Invalid txs | 0 |
| Fanout outputs | 0 |
Nodes=3, Growing, wait for tx valid
| Number of nodes | 3 |
|---|---|
| Number of txs | 90 |
| Avg. Confirmation Time (ms) | 40.8 |
| P99 | 62.5ms |
| P95 | 54.8ms |
| P50 | 40.4ms |
| Tx validation time p50 (ms) | 11.8 |
| End-to-end TPS | 72.15 tx/s |
| Sustained TPS | 72.03 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 62 |
| Snapshots per second | 49.70 /s |
| Avg txs per snapshot | 1.5 |
| Peak node RSS (MB) | 146.9 |
| Number of Invalid txs | 0 |
| Fanout outputs | 0 |
Nodes=3, Mixed, fire and forget
Each client first grows its UTxO set (1-in to 2-out) for half of its tx budget, then contracts it back (2-in to 1-out) for the remainder.
| Number of nodes | 3 |
|---|---|
| Number of txs | 90 |
| Avg. Confirmation Time (ms) | 170.9 |
| P99 | 172.9ms |
| P95 | 172.8ms |
| P50 | 171.8ms |
| Tx validation time p50 (ms) | 57.6 |
| End-to-end TPS | 516.36 tx/s |
| Backlog drain time (s) | 0.2 |
| Snapshots observed | 2 |
| Snapshots per second | 11.47 /s |
| Avg txs per snapshot | 45.0 |
| Peak node RSS (MB) | 145.6 |
| Number of Invalid txs | 0 |
| Fanout outputs | 4 |
Nodes=3, Mixed, wait for tx valid
Each client first grows its UTxO set (1-in to 2-out) for half of its tx budget, then contracts it back (2-in to 1-out) for the remainder.
| Number of nodes | 3 |
|---|---|
| Number of txs | 90 |
| Avg. Confirmation Time (ms) | 34.5 |
| P99 | 46.0ms |
| P95 | 43.2ms |
| P50 | 35.8ms |
| Tx validation time p50 (ms) | 9.4 |
| End-to-end TPS | 86.07 tx/s |
| Sustained TPS | 82.89 tx/s |
| Backlog drain time (s) | 0.0 |
| Snapshots observed | 61 |
| Snapshots per second | 58.34 /s |
| Avg txs per snapshot | 1.5 |
| Peak node RSS (MB) | 146.0 |
| Number of Invalid txs | 0 |
| Fanout outputs | 4 |
noonio
left a comment
There was a problem hiding this comment.
minor feedback about using a library
this is looking really nice! so satisfying to see things deleted. really nice change :)
|
Filed a follow-up so I can just merge this now - #2824 |
fixes #2753
Improvements in this PR:
https://github.com/cardano-scaling/hydra/actions/runs/31692829527/job/94423784389