Skip to content

tool: frigate-bench for measuring backend RPC cost#2

Merged
josibake merged 1 commit into
mainfrom
tool/frigate-bench
May 19, 2026
Merged

tool: frigate-bench for measuring backend RPC cost#2
josibake merged 1 commit into
mainfrom
tool/frigate-bench

Conversation

@josibake
Copy link
Copy Markdown
Member

@josibake josibake commented May 19, 2026

Summary

Adds tools/frigate-bench/ — a small benchmark that runs the same call patterns Frigate uses against bitcoind, on a single persistent HTTP keep-alive connection (matching Frigate's Java HTTP client, not a naive curl-per-call). Useful for A/B-comparing a loopback deployment against a remote-backend deployment.

  • tools/frigate-bench/bench.py — the script

  • tools/frigate-bench/README.md — usage docs

  • flake.nix — exposes as packages.<system>.frigate-bench (via `writePython3Bin`) + apps.<system>.frigate-bench so it's runnable as:

    ```
    sudo cat /run/agenix/bitcoind-rpc-creds \
    | nix run github:2140-dev/roost#frigate-bench -- http://10.42.0.1:8332/
    ```

Measured

Four phases:

  • pure latency: getbestblockhash, getblockcount (small in/out, warm connection)
  • chain meta: getblockhash, getblockheader (reorg-detection-style calls)
  • big payload: getblock(tip, 0) raw block hex (~1-2 MB on mainnet)
  • mempool init hot loop: getrawmempool once + getrawtransaction × 1000 sample, with extrapolation to the full current mempool size

Real numbers (loopback kingfisher vs WG-edge albatross, mainnet)

Test Loopback WG Ratio
getbestblockhash 0.084 ms 28.0 ms 333x
getblock(tip, 0) raw 12.67 ms 94.83 ms 7.5x
getrawtransaction (×1000) 0.122 ms 29.04 ms 238x
mempool init total 12 s 47 min ~240x

Confirms what's been observed informally on the multi-box deployment: per-call latency dominates for small RPCs (basically the link RTT), bandwidth dominates for big payloads, and mempool init is the architectural cost that frigate pays on every restart.

Test plan

  • CI: `nix flake check` green
  • CI: `nix fmt --ci` green
  • Local: tested on kingfisher (loopback) and albatross (over WG); numbers above

Not measured

  • Fulcrum/Electrum proxying — possible future extension; low-volume in normal operation
  • ZMQ steady-state delivery latency — not amenable to synthetic benchmarking; measure from frigate's own logs

🤖 Generated with Claude Code

A small benchmark that runs the same call patterns frigate uses against
bitcoind, on a single persistent HTTP connection (matching frigate's
Java HTTP client behavior rather than a naive curl-per-call). Useful
for A/B-ing a loopback deployment vs a remote-backend deployment to
quantify how much network latency the consumer actually pays.

Covers four phases:
  - pure latency:  getbestblockhash, getblockcount (small in/out)
  - chain meta:    getblockhash, getblockheader (small)
  - big payload:   getblock(tip, 0) raw block hex
  - mempool init:  getrawmempool + getrawtransaction × 1000 sample,
                   with an extrapolation to the full current mempool

Reads `user:password` from stdin (so the password doesn't leak into
process listings) and takes the RPC URL as argv[1]. Exposed via the
flake's `packages.<system>.frigate-bench` (a writePython3Bin with
no system Python dependency) and `apps.<system>.frigate-bench` so:

  sudo cat /run/agenix/bitcoind-rpc-creds \\
    | nix run github:2140-dev/roost#frigate-bench -- http://10.42.0.1:8332/

works on any frigate consumer without installing python or the script.

Does not measure fulcrum/electrum proxying or ZMQ steady-state
delivery latency — both are noted as future extensions in the README.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@josibake josibake merged commit 5aecb6b into main May 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant