Query performance measurements of libbitcoin-server across machines and configurations, some with Bitcoin Core, Fulcrum, or Frigate comparisons.
Index efficiency is Libbitcoin's query rate relative to the other server, divided by the size of its index relative to the other's, both at block 950,000 (index sizes are on the node performance page). Each value is a multiple: 2.5× means Libbitcoin delivers 2.5 times the query rate per byte of index, and below 1× it delivers less. Address history rates are entries per second, silent payments rates are blocks scanned per second, and other rates are calls per second.
The other charts measure one connection at a time. Throughput is what a server delivers under many: each connection count requests its own set of blocks or transactions back to back for 20 seconds, repeating the set if it runs out, from 16 client processes, after a server restart and cache purge, with both servers configured to accept the full connection count. The dashed lines mark the block rate that 1, 10, 100 and 1,000 peer connections at 1 Gbps can carry, so a block curve above a line means the network, not the server, would be the limit. Bitcoin Core serves only unconfirmed transactions over P2P, so P2P transactions are shown for Libbitcoin alone. Bitcoin Core serves P2P blocks from a single thread and levels off at about 860 blocks per second from two connections, with latency growing in proportion to the load; Libbitcoin serves them concurrently and reaches about 5,600 per second by 64 connections. Over encrypted (BIP324) P2P, Libbitcoin reaches about 4,100 blocks per second and Bitcoin Core about 520, while Libbitcoin transactions are faster than unencrypted, since BIP324 drops the per-message double SHA-256 checksum and Libbitcoin's ChaCha20 is hardware accelerated.
Libbitcoin only, in binary data format over HTTP. Addresses are grouped by history size as in the Electrum interface, and an address response is its outputs, so the rate is outputs returned per second of call time.
Addresses are grouped by history size, and the largest class adds 27 addresses of 100k to 2.2M entries. The 0 entries class uses 300 script hashes that own no output, the query a wallet makes most often when it scans past its last used address, and is plotted in calls per second. Address history rates are entries returned per second of call time.
A silent payments scan subscribes one scan key to a range of blocks ending at 950,000, and is timed from the subscription to the notification of completion. Each of three repetitions purges the standby list, scans cold with a new key, then scans warm with the same key. Rates are blocks of the range per second, and each range is labeled with its approximate span of time. GPU scans use each server's default GPU backend. CPU scans use Frigate's CPU backend, UltrafastSecp256k1 field arithmetic on BMI2/ADX, which has no SIMD path, and Libbitcoin's AVX-512 IFMA scan. A scan the server ended without completing, other than by timeout, is marked as a server failure. Libbitcoin's other CPU paths are shown warm, in order of rate above the Libbitcoin AVX-512 IFMA warm bar. AVX-512F builds the IFMA 52 bit multiply-add from 32 bit multiplies, and AVX-IFMA is measured as AVX-512 IFMA restricted to its 256 bit registers.
Each server is a peer to a single client connection over loopback. A block is a witness block by getdata, headers and cfheaders are 2,000 per request, and cfilter is one block per request.
Each server is at block 950,000 with an empty pool. The 28,142 transactions of blocks 950,001 to 950,009 are offered in block order by one P2P peer (inventory, then the transaction when requested), and each is timed from its send to the arrival of its rawtx notification on a ZMQ subscription. Latency is over the 24,517 transactions both servers accepted. Libbitcoin accepted 1,421 more transactions, as Bitcoin Core's clustered mempool imposes a hardwired capacity limit for performance reasons. Both rejected 2,204 transactions that were not yet valid at block 950,000: 1,522 are time-locked to a later block, 55 have unsatisfied relative lock times (BIP68), and 627 spend outputs of those.
Measurements pending.
Measurements pending.
All servers run on one machine, shelly (Threadripper PRO 9985WX, 512 GB, Windows 11), one stack at a time, each with a store at block 950,000 on its own volume. The client is on the same machine, over loopback, making sequential calls on one connection. Libbitcoin 4.0 serves from its own store (address index load factor 5). Bitcoin Core 32.0 has txindex, txospenderindex and the basic block filter index, with networking disabled. Fulcrum 2.1.3 indexes from that Bitcoin Core, at default settings. Frigate 1.6.1 indexes silent payments from that Bitcoin Core. The Electrum interface is compared with Fulcrum, the Sparrow interface with Frigate, and the bitcoind JSON-RPC and REST interfaces with Bitcoin Core.
Each method is called with 300 unique requests, drawn from random blocks over the whole chain: a block, a transaction and an output script from each.
Each of three repetitions, on its own requests, stops the servers, empties working sets, flushes modified pages and purges the standby list, restarts the servers and waits until idle, sends 5 s of untimed pings, then makes a cold pass in shuffled order and a warm pass on the same requests in another order. Every cold pass therefore starts with nothing resident, including each server's own caches.
A call is timed from request to the last response byte, received into a preallocated buffer, with parsing after timing. Rates are calls per second (1000 / mean ms). Bitcoin Core and Fulcrum hold all headers in memory, so they have no cold header query, and their warm header bars are hatched.
Copyright © 2011-2026 libbitcoin developers