Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Comparison: dvb-WarpPool vs. ckpool vs. public-pool vs. mkpool

Choosing a self-hosted solo pool comes down to a handful of open-source candidates. This page compares them feature by feature so you can pick the right tool for your setup.

How this table was made — and how to read it fairly:

  • Every claim was verified against the source code of the compared projects, not against their marketing. Full re-verification on 2026-07-21 against ckpool master 308410d (2026-07-20), public-pool master 96a9202 (2026-06-05, one commit past 95565ee, which the Umbrel app pins), and mkpool master d2e4819 (2026-07-19). dvb-WarpPool claims reflect v1.24.0.
  • All four are actively maintained open-source projects making different trade-offs. ckpool has been the workhorse of solo mining for a decade (the hosted solo.ckpool.org has found hundreds of mainnet blocks); mkpool is a modern multi-coin C++ engine; public-pool is the familiar TypeScript pool with a web UI. Nothing here means “those are bad.”
  • The table tracks what ships in the open-source code. Hosted instances (solo.ckpool.org, public-pool.io, mkpool.com) run additional private code you don’t get when self-hosting — mkpool’s README states its database/analytics service, REST API and website are not in the open release, so those rows reflect the engine only. Where a project’s README claims a feature its open code doesn’t implement, we go by the code — and equally, where the code has moved ahead of what this page used to say, the code wins (mkpool’s multi-node failover was listed here as unimplemented and is now wired up end to end).
  • Competitor repos move. If a cell is outdated, open an issue — this page is only useful while it’s accurate. All rows — ours and the competitors’ — were last verified 2026-07-21 against the commits named above. The 2026-07-21 pass changed several rows in the competitors’ favour: ckpool has gained a Bitcoin Core IPC template path and BIP54 coinbase handling, and mkpool has gained working multi-node failover, tagged releases and CI. Those corrections are reflected below. The address-ownership owner-panel row was re-verified 2026-07-24 against fresh heads (ckpool 308410d, public-pool 96a9202, mkpool 4785cd5): none of the three has any signed-message ownership mechanism.
dvb-WarpPoolckpool (solo)public-poolmkpool
CoinsBitcoinBitcoinBitcoin9 chains (BTC, BCH, BitcoinII, DigiByte, eCash, ZEC, LTC, DOGE, BCH II; DOGE also merge-mined under LTC)
Starting difficultyhardware-aware, 7 device classes from user agent (unrecognised falls back to the profile default)42 by default, operator-configurable (startdiff), same value for every miner100,000, same value for every minerfixed per port tier (default 65,536; SV2 extended channels: seeded from the miner’s nominal hashrate)
Sub-1 difficultyfrom the first share (NerdMiner class)no (mindiff 1)yes — reachable both by the starvation descent (÷6 below 5 recent shares) and by ordinary VarDiff; floor 0.00001no (floor 1; configured floors 1024)
Difficulty persistencesurvives reconnects and pool restartsnonono
suggest_difficulty / d=both, clamped to the device class; a repeat or below-current suggest is deduped and treated as a seed, not continuous controlsuggest only (no d= password syntax); clamped up to mindiff, and a repeat or already-current suggest is dedupedsuggest unclamped, one-shot (latched); d= integer, upward onlyboth; suggest_difficulty clamped to the tier’s vardiff min/max, d=/diff= clamped per coin — both re-emit set_difficulty (+ a job re-push) on every repeat, and are ignored on fixed-diff tiers
VarDiff styleEMA + Poisson significance gate (retarget only when the share-rate clears a 1/√N confidence band) + guarded idle decay, per-class floorsdual EMA (60 s / 300 s window) + fixed 0.15–0.4 share-rate hysteresis band, retarget gated on ≥72 shares or 240 s60 s timer + ±2× hysteresis, power-of-2 snaps (downward starvation step ÷6)dual EMA + fixed hysteresis — a faithful ckpool port, same 0.15/0.40 and 72-share/240 s constants
Fixed-difficulty portsno — VarDiff adapts per devicevia separate instancesnoyes (one fixed-diff TCP port per tier)
Stratum V22024 spec, live-verified (Bitaxe / NerdQAxe)nonot in master (side branch)yes — Noise NX handshake, EllSwift/BIP324 key exchange, encrypted transport (the source names no spec version)
TLS for minersout of the box + Let’s Encrypt guidenonoyes (in-binary)
Block/coinbase standardsBIP34 height, SegWit commitment, BIP310 version-rolling (overt ASICBoost), BIP54-forward-compatible coinbase locktimeBIP34, SegWit, version-rolling, and BIP54 (nSequence fffffffe + nLockTime = height−1)BIP34, SegWit, version-rollingBIP34, SegWit, version-rolling (mask 1fffe000, off for BCH)
Payout modeltwo modes: a single operator-configured address (default), or opt-in per-worker coinbase — each miner mines to the address in its own stratum login, full reward, one output, and the config rejects a pool fee in that modesolo mode (btcsolo) pays each miner’s own address from the stratum username; auth is refused if the username is not a valid address. Optional operator donation output, default 0 (shipped example config sets 2%)pays the address in the stratum username. Optional dev-fee output (1.5%) when DEV_FEE_ADDRESS is set, automatically waived below 50 TH/spays the address in the stratum username (V1 and both SV2 channel types), validated twice — locally, then via validateaddress. Optional operator donation output, default 1% but with no default address, so it is inert until configured. Merge-mined DOGE falls back to an operator address if the miner supplies none
Coinbase outputs (solo/per-miner path)1 (+ SegWit commitment)1 (+ commitment), 2 with a donation1 (+ commitment), 2 with the dev fee1 (+ commitment), 2 with a donation; more on eCash (consensus-mandated outputs)
Multi-node failoveryes — sub-second switch, submitblock to all nodes in parallelyes (btcd failover list)no (single RPC endpoint)yes — RPC fallback nodes with automatic switch-back, plus redundant submitblock fan-out and upstream-link failover for the new proxy role
Block-change latencyZMQ from every configured node, first winsCore IPC notifications when configured, otherwise ZMQ, plus a polling backstopZMQ (optional; falls back to a 500 ms poll), which triggers a getmininginfo pollZMQ + polling fallback + watchdog
Template sourcegetblocktemplate (RPC) by default + optional Bitcoin Core IPC (Cap’n Proto, experimental, requires Core ≥ 31) — templates straight from kernel notifications, measured ~5–12 ms vs ~89–101 ms for GBT+ZMQalso bothgetblocktemplate by default, with an opt-in Core IPC template path (ipcmining / ipctemplate) that falls back to RPCgetblocktemplate (RPC)getblocktemplate (RPC)
Rate-limit / auto-banper-IP on connect/auth/API + escalating ban + manual block listper-user exponential auth backoff (capped 600 s); no IP or share-rate bansconnection cap, socket timeout, user-agent filter; no per-IP limit or ban listtoken-bucket + invalid-share ban, plus a DB-backed address/worker blacklist
Web UI / APIPWA, 8 languages, authenticated, live SSEnone (logs + unix socket)yes — UI in a separate repo; read APIs unauthenticated and CORS fully open (one share-submission endpoint takes an API key)none in the open release (engine + Postgres writer, plus a local control socket)
Prometheus /metricsyes (pool + per-miner + network)nonoyes (opt-in build flag)
Notifications5 sinks + Web Push; friends can subscribenoneTelegram/Discord (block found, plus a Discord restart notice)none in the open release
Address-ownership owner panelyes — a miner proves control of the payout address by signing a challenge (BIP-137 for legacy/SegWit, BIP-322 for Taproot), which unlocks a per-address privacy toggle and notification target; no account, no funds movedno (no per-address owner controls)no — per-address pages are public, the “settings” route is a no-op stub, and the Telegram/Discord subscribe is unauthenticated (anyone can subscribe to any address)no (no per-address owner surface in the open release)
Device telemetryBitaxe / Antminer / Avalon / Whatsminer probes + mDNSnonono
Energy & solar trackingyesnonono
Tests1201, gating every release in CIone SHA-256 self-test; no pool-level tests63, not run in CI (workflows build/scan the image only)Catch2 (12 files) + ASan/TSan/UBSan + fuzz harnesses, in CI on a monthly cron and manual dispatch rather than per-push
Releasessigned checksums; .deb / .rpm / AppImage / multi-arch Docker from CI, plus a manually built .dmg; reproducible + SBOM (no macOS or Windows CI runner since the forge move: the .dmg is built by hand per release, the Windows .msi is paused with the WiX packaging still maintained)build from source (autotools); no tags, no in-repo packagingbuild from source / Docker image from CI; no tags or releasesbuild from source; tags v0.2.0 and v.0.3.0 present, plus a release workflow
Mainnet track recordnot yet — the project is youngmany (hosted, since 2014)yes (hosted)hosted instance live on mainnet
LicenseAGPLv3 + commercialGPLv3GPLv3 (UI repo: no license file)GPLv3

Note on the IPC template source — no firstness claim

This row previously said that none of the compared pools carried a Bitcoin Core IPC path. That is no longer true: as of the 2026-07-21 re-check, ckpool ships an in-tree Cap’n Proto mining IPC implementation (ipc/mining/mining.capnp, ipc/mining/mining_ipc.cpp) used for both block notification and template generation, opt-in via the ipcmining and ipctemplate config keys and falling back to getblocktemplate. That is architecturally the same choice dvb-WarpPool made. public-pool and mkpool still go through getblocktemplate only.

It is explicitly not a claim to be “first” or “fastest” with IPC. Stratum Reference Implementation (SRI) was the first consumer of Core’s IPC mining interface, and other projects outside this three-way comparison may well use it too. Core’s IPC interface is itself experimental and has broken its mining.capnp schema across releases, which is why dvb-WarpPool keeps GBT+ZMQ as the default and ships IPC strictly opt-in. The latency figures are our own measurements on our own hardware, not a cross-pool benchmark.

When the others are the better pick

Honesty cuts both ways:

  • ckpool — a minimal, battle-hardened C daemon with a decade of track record, if you’re comfortable with logfiles and a unix socket as your interface. It needs the least trust in young code.
  • public-pool — the exact software behind public-pool.io, a familiar UI, and a large user base running the same commit.
  • mkpool — if you want multi-coin solo mining (BTC, BCH, LTC, merge-mined DOGE, ZEC and more from one binary), fixed-difficulty ports, RPC-node failover, or a lean modern C++ engine, and you don’t need a built-in operator UI, device telemetry, or packaged/signed releases. It also now ships proxy, passthrough and redirector roles for scaling out across machines, and it’s already live on mainnet.
  • dvb-WarpPool — if you run mixed home hardware (NerdMiner next to a Bitaxe next to an Avalon), want TLS / SV2 / notifications / energy tracking and a full operator UI without bolting on extra services, and value tested, signed, reproducible releases. Bitcoin-only by design.

See also