Mempool Configurations & RPC
Bitcoin Node Mempool Configuration: Mastering maxmempool, Expiry, and RPC Diagnostics
Maintaining an optimized, customized mempool is essential for node operators, developers, and miners. While the P2P protocol defines consensus, mempool settings are entirely defined at the node level in the bitcoin.conf file.
This manual details the critical variables that govern mempool behavior and walks through the JSON-RPC diagnostics used to audit unconfirmed states.
⚙️ 1. Core Configuration Variables (bitcoin.conf)
By default, standard nodes restrict mempool behavior to ensure high reliability. Operators can customize their settings to fit their resources:
A. Memory Limits (maxmempool)
- Variable:
maxmempool=<n>(Default:300MB) - Behavior: Sets the maximum system memory allocated to the mempool database in megabytes. Increasing this (e.g.,
maxmempool=1000) lets your node store lower-fee transactions during fee spikes, providing highly accurate fee estimations. It will consume more RAM.
B. Pruning Window (mempoolexpiry)
- Variable:
mempoolexpiry=<n>(Default:336hours, or 14 days) - Behavior: The age limit in hours of a transaction in the mempool. Any transaction that has sat unconfirmed for longer than this limit is automatically pruned from memory.
C. Persistent Storage (persistmempool)
- Variable:
persistmempool=<0|1>(Default:1) - Behavior: When set to
1, the node saves all unconfirmed transaction data to a local disk file namedmempool.datduring shutdown. Upon booting up, the node re-loadsmempool.datback into system RAM, ensuring it doesn't have to rebuild its state from scratch via peer gossip.
📡 2. Advanced Fee Policies
minrelaytxfee=<amount>: (Default:0.00001BTC/kvB, or1sat/vB). The minimum feerate required to relay a transaction across standard peers.mempoolfullrbf=<0|1>: (Default:1in modern releases). Configures the node to accept replacements for any unconfirmed transaction, overriding opt-in BIP 125 signaling.
💻 3. JSON-RPC Diagnostic Commands
Developers audit local mempool health using the following JSON-RPC commands on their node:
A. Global State Audit: getmempoolinfo
$ bitcoin-cli getmempoolinfo
{
"loaded": true,
"size": 12843,
"bytes": 9482312,
"usage": 48210342,
"total_fee": 0.24831201,
"maxmempool": 300000000,
"mempoolminfee": 0.00001000,
"minrelaytxfee": 0.00001000,
"unbroadcastcount": 0,
"fullrbf": true
}
B. Raw Database Listing: getrawmempool
Pulls a raw list of all transaction IDs waiting in the mempool.
$ bitcoin-cli getrawmempool
[
"2a088158bc6a69a1225de7e0465c749692bcf4f990db4b4c480fe804ea17851a",
"d615139931d376c5f283db0259ca02d0ff1ee61f9b2b742fc7f82717675c9f41"
]
C. Metadata Profiling: getmempoolentry <txid>
Inspects granular details, including ancestry counts and fee calculations, for a specific transaction in RAM.
$ bitcoin-cli getmempoolentry d615139931d376c5f283db0259ca02d0ff1ee61f9b2b742fc7f82717675c9f41
{
"vsize": 141,
"weight": 561,
"time": 1707864360,
"height": 830390,
"descendantcount": 1,
"descendantsize": 141,
"ancestorcount": 2,
"ancestorsize": 391,
"fees": {
"base": 0.00001128,
"modified": 0.00001128,
"ancestor": 0.00003128,
"descendant": 0.00001128
},
"depends": [
"2a088158bc6a69a1225de7e0465c749692bcf4f990db4b4c480fe804ea17851a"
],
"spentby": [],
"bip125-replaceable": true,
"unbroadcast": false
}
🐍 4. Python JSON-RPC Mempool Auditor
The following Python script connects directly to a running local Bitcoin node, queries global mempool states, lists all transaction IDs, and parses their metadata to flag RBF-replaceable transactions.
import json
import urllib.request
class BitcoinMempoolRPC:
def __init__(self, rpc_user, rpc_password, host="127.0.0.1", port=8332):
self.rpc_url = f"http://{rpc_user}:{rpc_password}@{host}:{port}/"
self.headers = {"content-type": "application/json"}
def call(self, method, params=[]):
"""Sends a JSON-RPC request to the Bitcoin Core daemon."""
payload = {
"jsonrpc": "1.0",
"id": "mempool_auditor",
"method": method,
"params": params
}
req = urllib.request.Request(
self.rpc_url,
data=json.dumps(payload).encode("utf-8"),
headers=self.headers
)
try:
with urllib.request.urlopen(req) as response:
res = json.loads(response.read().decode("utf-8"))
return res.get("result")
except Exception as e:
print(f"[!] RPC call failed: {e}")
return None
def audit_mempool(self):
"""Queries and profiles the active local mempool database."""
info = self.call("getmempoolinfo")
if not info:
print("[!] Could not connect to Bitcoin Core RPC daemon.")
return
print("=== Bitcoin Core Mempool Audit ===")
print(f"Loaded: {info['loaded']}")
print(f"Transactions in RAM: {info['size']}")
print(f"Total Raw Bytes: {info['bytes']} bytes")
print(f"RAM Utilization: {info['usage'] / (1024*1024):.2f} MB / {info['maxmempool'] / (1024*1024):.2f} MB")
print(f"Current Dynamic Fee Floor: {info['mempoolminfee'] * 1e8:.0f} sat/vB")
txids = self.call("getrawmempool")
if not txids:
print("Mempool is currently empty.")
return
print(f"\nScanning first 5 transaction packages for RBF/CPFP data:")
for txid in txids[:5]:
entry = self.call("getmempoolentry", [txid])
if entry:
is_rbf = entry.get("bip125-replaceable", False)
vsize = entry.get("vsize")
ancestor_count = entry.get("ancestorcount")
descendant_count = entry.get("descendantcount")
base_fee = entry["fees"]["base"] * 1e8 # Convert to Sats
print(f"\n[-] TXID: {txid}")
print(f" ├── Size: {vsize} vB | Fee: {base_fee:.0f} Sats ({base_fee/vsize:.2f} sat/vB)")
print(f" ├── Ancestors: {ancestor_count} | Descendants: {descendant_count}")
print(f" └── Opt-In RBF (BIP 125): {'[✔] YES' if is_rbf else '[ ] NO'}")
if __name__ == "__main__":
# Example credentials. Replace with your actual bitcoin.conf values.
rpc = BitcoinMempoolRPC(rpc_user="your_username", rpc_password="your_password")
rpc.audit_mempool()
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: