FP&A-grade analytics dashboard for Bitcoin on-chain fee markets, block space economics, and mining revenue.
Free, open-source alternative to Glassnode/CryptoQuant — runs against your own Bitcoin node with full data sovereignty.
- Fee Market Analysis — mempool as order book, fee rate time-series, congestion monitoring
- Block Explorer — recent blocks with pool attribution, weight utilization, fee statistics
- Adoption Curves — SegWit and Taproot adoption tracking over time
- Mining Economics — subsidy vs fee revenue breakdown, pool profitability analysis
- Node Status — health monitoring and database statistics
Bitcoin Node (RPC, localhost only)
│
├──► collector (daemon, 60s poll → SQLite)
│ ↓
│ ~/.bitcoin-fee-observatory/observatory.db
│ ↓
└──► Streamlit dashboard (reads SQLite + live RPC)
- Python 3.10+
- Bitcoin Core or Bitcoin Knots node with RPC enabled
- bitcoinlib-rpc
# Clone and install
git clone https://github.com/Bortlesboat/bitcoin-fee-observatory.git
cd bitcoin-fee-observatory
pip install -e .
# Start the data collector (keep this running in a terminal)
python -m fee_observatory.collector
# In another terminal, launch the dashboard
python -m streamlit run src/fee_observatory/app.pyThe dashboard opens at http://localhost:8505. The collector auto-detects your Bitcoin node using cookie auth.
All settings work via CLI flags (collector) or environment variables (both):
| Variable | Default | Description |
|---|---|---|
BITCOIN_RPC_HOST |
127.0.0.1 |
Bitcoin node RPC host |
BITCOIN_RPC_PORT |
8332 |
Bitcoin node RPC port |
BITCOIN_COOKIE_PATH |
auto-detect | Path to .cookie file |
OBSERVATORY_DB |
~/.bitcoin-fee-observatory/observatory.db |
SQLite database path |
OBSERVATORY_INTERVAL |
60 |
Collector poll interval (seconds) |
python -m fee_observatory.collector --help
# Custom node and interval:
python -m fee_observatory.collector --host 192.168.1.50 --port 8332 --interval 30
# Custom database location:
python -m fee_observatory.collector --db /path/to/my/observatory.dbThe flagship page. Treats the mempool as a supply/demand order book:
- Stacked area chart of fee bucket sizes over time
- Fee estimate trends (1-block through 1-day targets)
- Next block minimum fee with congestion coloring
- "Best time to send" recommendation
Recent blocks table with analytics overlay:
- Pool attribution, weight utilization, adoption percentages
- Revenue breakdown: subsidy vs fees per block
- Pool distribution pie chart
Script type transition tracking:
- Legacy → SegWit → Taproot stacked area
- Taproot adoption trend with moving average
Revenue analysis with FP&A framing:
- Subsidy vs fee revenue over time
- Fee revenue as % of total (the long-term sustainability metric)
- Pool profitability comparison
- Block profitability scatter (fees vs weight utilization)
Health dashboard:
- Chain, height, sync progress, peers
- Database statistics (rows, time range, disk usage)
pip install -e ".[dev]"
pytest tests/ -v
ruff check src/ tests/- RPC is localhost-only — the dashboard never exposes RPC credentials
- Dashboard binds to localhost — not accessible from the network by default
- All SQL queries are parameterized — no injection surface
- No secrets in the repo —
.cookieauth is auto-detected at runtime - Read-only analytics — the dashboard and collector only read from the Bitcoin node, never write
Warning: Do not expose the dashboard to the internet without authentication. It is designed for local use.
All data is stored locally in ~/.bitcoin-fee-observatory/observatory.db (SQLite with WAL mode). The database has three tables:
mempool_snapshots— mempool state every 60 secondsblocks— analyzed block data (detected on arrival)fee_estimates— fee rate estimates every 60 seconds
The database accumulates value over time — the longer you run the collector, the richer your time-series data.
MIT