How Bitcoin Core Estimates Fees
Few things in Bitcoin are more aggravating than broadcasting a transaction, checking a block explorer forty minutes later, and seeing:
"0 Confirmations — Estimated wait: 14 hours."
Equally painful is the opposite blunder: panicking during a sudden fee surge, attaching 75 sat/vB to an ordinary payment, and watching the mempool empty out ten minutes later—realizing you just overpaid by tenfold.
Unlike traditional payment networks where fees are fixed by a corporate tollkeeper, or newer blockchains like Ethereum with an in-protocol base fee mechanism (EIP-1559), Bitcoin operates on a pure, decentralized first-price auction. Every 10 minutes or so, miners have a finite cargo container of roughly 1 to 1.5 megabytes of real estate to sell. If hundreds of people are clamoring for that space, miners don't care who you are, what your payment is for, or how long you've been waiting. They care about one thing only: feerate—the fee paid per unit of digital real estate consumed, measured in satoshis per virtual byte (sat/vB).
This forces every wallet and user into a guessing game: What feerate should I attach right now?
In Bitcoin, this question is framed around a confirmation target:
"What feerate gives my transaction an acceptably high probability of confirming within $N$ blocks?"
While that sounds simple enough, estimating fees in Bitcoin is deceptively brutal. Three chaotic forces collide:
- Unpredictable Supply (A Bus Stop with No Timetable): Unlike blockchains with fixed slot clocks, Bitcoin blocks are discovered via a memoryless Poisson process. Blocks average 10 minutes, but variance is wild. A block might arrive 20 seconds after the last one—or you might wait an agonizing 75 minutes. The network doesn't "speed up" just because mempools are packed.
- Unpredictable Demand (Sudden Storms): Transaction volume is volatile. A sudden market breakdown, an exchange arbitrage run, or an NFT mint can flood network queues with high-paying transactions in a matter of minutes.
- Divergent Time Preferences: An arbitrageur needing confirmation in the very next block has a vastly different tolerance than someone consolidating cold-storage UTXOs on a Sunday evening.
To navigate this chaos, Bitcoin Core's estimatesmartfee RPC doesn't rely on guesswork or magic heuristics. Instead, it pairs a historical statistical engine with a real-time mempool simulator.
In this guide, we'll pull back the curtain on how this algorithm works under the hood: why obvious naive shortcuts collapse in practice, how Bitcoin Core tracks hundreds of fee buckets across time, and the clever relief valves it uses to keep you from dramatically overpaying
Why Intuitive Shortcuts Break Down
When developers first tackle fee estimation, two intuitive ideas immediately come to mind: look at the transactions waiting right now in the mempool, or look at the transactions that just got mined into past blocks.
In Bitcoin, both of these shortcuts turn out to be traps.
Trap 1: Looking Only at the Current Mempool
The most tempting shortcut is to pop the hood on your node's mempool (the local waiting room of unconfirmed transactions), sort everything by feerate, and pick a number just high enough to squeeze into the next virtual megabyte of space.
In practice, this falls flat for three reasons:
- There is No "Global Mempool": Bitcoin has no master waiting room. Every single node maintains its own local mempool shaped by its peer connections, uptime, memory ceilings, and local eviction rules. A transaction sitting at the top of your mempool might not even have reached miners yet, and vice versa.
- The "Out-of-Band" Ghost Ships: Miners routinely include transactions that never circulated across the public P2P network—pool payout distributions, private transaction deals, or users paying mining pools directly for priority through private acceleration APIs. Relying strictly on what you can see in your local waiting room leaves you blind to these private transactions.
- Point-in-Time Fragility: Mempool conditions are ephemeral. A snapshot tells you what is waiting right this second, but tells you nothing about what will happen 3 minutes from now. If a sudden burst of transactions arrives after you broadcast, your transaction is pushed backward down the queue. Even worse: a static snapshot cannot tell you how many blocks a massive backlog will take to drain.
Trap 2: Looking Only at Historical Mined Blocks
If the live mempool is too erratic, why not look backward? Why not compute the average or median feerate of transactions confirmed in the last five or ten blocks?
This approach fails for equally stubborn reasons:
- Classic Survivorship Bias: Mined blocks only display the victors—the transactions that paid enough to succeed. They tell you absolutely nothing about the transactions that underpaid, got stranded in mempools for days, or were dropped entirely. Basing your future fees solely on confirmed transactions guarantees you will underestimate fees the moment congestion ramps up.
- Off-Peak Distortions: When blocks are discovered unusually fast or during quiet Sunday night lulls, miners scrape the bottom of the barrel, including transactions that paid the bare-minimum relay feerate (1 sat/vB) just to fill empty space. If those low rates bleed into your rolling average, your wallet will spit out an artificially cheap estimate right as Monday morning transaction volume surges—leaving your transaction stranded.
- The Lag Problem: History is rear-facing. By the time a sudden fee spike shows up in historical block averages, several blocks have already passed. Users underpay on the way up (getting stuck) and overpay on the way down (wasting sats long after the traffic jam has cleared).
The Dual Architecture: Weather Forecast vs. Historical Climate
To avoid these traps, Bitcoin Core splits the problem between two distinct systems:
- The Block Policy Estimator: The deep statistical historian. It tracks historical confirmation probabilities over days and weeks across hundreds of feerate intervals. (Think of it as the regional climate model.)
- The Mempool Policy Estimator: The real-time observer. It simulates candidate block templates directly against the unconfirmed transactions currently sitting in the node's local memory. (Think of it as looking out the window to see if it's currently raining.)
The Mempool Policy Estimator: A Short-Range Tool with Strict Guardrails
Because simulating the live mempool mimics the naive mempool approach we just critiqued, Bitcoin Core places strict handcuffs on it:
- It is only ever used for immediate confirmation targets of 1 or 2 blocks. Beyond two blocks, future incoming traffic makes point-in-time simulations meaningless.
- It fills a candidate block template just like a miner would, sorting waiting transactions by fee. From this simulated block, it extracts the feerate distribution:
- For an economical estimate, it returns the 75th percentile feerate of the block template.
- For a conservative estimate, it returns the 50th percentile (median) feerate.
The 6-Block Health Check: Never Trusting a Blind Node
What if your node just rebooted twenty minutes ago? Or what if your internet connection hiccuped, leaving your mempool half-empty? Or what if miners are packing blocks with private transactions you never saw?
Bitcoin Core refuses to trust the Mempool Policy Estimator unless the node's local mempool passes a strict sanity check:
- The node tracks transaction weight across the last 6 mined blocks (roughly the past hour).
- It cross-checks what percentage of that mined transaction weight was already present in its own mempool before the blocks were found.
- If the node's mempool successfully accounted for at least 75% of the weight across those 6 blocks, the mempool is certified as healthy and representative of the wider network.
If the node has observed fewer than 6 blocks since startup, or if coverage slips below 75%, the node acknowledges that its local view may be distorted. It quietly turns off the mempool estimator and falls back entirely on the historical Block Policy Estimator.
The Historical Engine: The Block Policy Estimator
While the mempool estimator checks what is waiting at the door right now, the Block Policy Estimator asks a fundamental statistical question:
"Historically, what is the lowest feerate where transactions had an acceptably high probability (such as 85%) of confirming within $N$ blocks?"
To answer this without melting the node's memory or getting fooled by random noise, Bitcoin Core constructs its model through several deliberate layers.
Step 1: Chopping an Infinite Spectrum into 240 Buckets
Transactions broadcast with arbitrary, continuous feerates—12.3 sat/vB, 15.82 sat/vB, 104.11 sat/vB. Tracking every unique decimal feerate is impossible. Worse, it would scatter data so thinly that almost every feerate would have only one or two data points, making statistical analysis useless.
Bitcoin Core solves this by quantizing feerates into discrete intervals called buckets:
- The lowest bucket begins at
0.1 sat/vB(100 satoshis per thousand virtual bytes). - Each bucket boundary scales up by 5% (
1.05multiplier). - The buckets grow exponentially all the way to
10,000 sat/vB, producing roughly 240 distinct buckets.
Conceptually, a bucket is a dedicated statistical ledger for a narrow feerate band. Inside each bucket, Bitcoin Core treats all transactions as paying roughly the same rate and maintains five running tallies:
- Total Confirmed: The total count of transactions in this bucket that were ever mined into blocks.
- Sum of Feerates: The cumulative feerates of those confirmed transactions (allowing the node to compute the bucket's precise average feerate).
- Confirmed-Within Counters: An array of cumulative counters tracking confirmation speeds. Each counter records how many transactions confirmed in $\le Y$ blocks.
- Failed Counters: Counters recording how many transactions in this bucket left the mempool unconfirmed after waiting for $\ge Y$ blocks.
- Unconfirmed Transactions by Entry Height: A breakdown of waiting transactions organized by the block height at which they entered the mempool.
Step 2: The Journey of a Transaction Across Events
A node never trusts second-hand gossip about transaction performance: it only tracks transactions it personally observed entering its mempool. To keep overhead minimal, the node doesn't store entire transactions in memory for fee estimation. It only remembers two integers: the block height when the transaction arrived and its bucket index.
From there, it updates its bucket counters across three lifecycle milestones:
- Event 1: Arrival (Transaction Enters the Mempool)
The node identifies the transaction's bucket and increments the count of unconfirmed transactions for that bucket at the current block height. - Event 2: Victory (Transaction Confirmed in a Block)
When a block arrives containing the transaction, the node calculates how long it waited:
blocks_to_confirm = mined_height - entry_height
Inside that transaction's bucket:- Total Confirmed increases by 1.
- Sum of Feerates increases by the transaction's feerate.
- For every target
Y ≥ blocks_to_confirm, the Confirmed-Within counter increases by 1. (Notice the cumulative logic: if a transaction confirms in 2 blocks, it also successfully confirmed in $\le 3$ blocks, $\le 4$ blocks, and so forth.) - The transaction is retired from the bucket's unconfirmed ledger.
- Event 3: Defeat (Transaction Evicted or Abandoned)
If a transaction is dropped due to mempool memory limits or replaced via RBF, the node calculates how long it waited:
blocks_waited = current_height - entry_height
Inside that bucket:- For every target
Y ≤ blocks_waited, the Failed Counter increases by 1 (recording that the transaction waited at least $Y$ blocks and failed to confirm). - The transaction is removed from the unconfirmed ledger.
- For every target
Step 3: Computing the Confirmation Fraction
When a user asks: "Can I get confirmed within $N$ blocks?", the estimator evaluates candidate buckets using the Confirmation Fraction:
$\text{Confirmation Fraction} = \frac{\text{Confirmed Within } N \text{ Blocks}}{\text{Total Confirmed} + \text{Failed (Waited } \ge N\text{)} + \text{Still Waiting (Waited } \ge N\text{)}}$
Notice who gets excluded from the denominator: transactions that entered the mempool recently and have been waiting for fewer than $N$ blocks. They haven't had their full window of opportunity yet, so penalizing the bucket for their presence would artificially skew the success rate downward.
Concrete Example 1: Calculating the Confirmation Fraction
Suppose we want to know whether paying [20.0 sat/vB – 21.0 sat/vB] reliably confirms within 3 blocks:
- 85 transactions in this bucket confirmed within 3 blocks or fewer.
- 90 transactions confirmed in total (5 transactions took 4 or 5 blocks).
- 2 transactions were evicted after waiting 3 or more blocks.
- 8 transactions are currently sitting in the mempool, having already waited 3 or more blocks without confirmation.
- (15 transactions entered just 1 or 2 blocks ago and are still waiting; these are deliberately excluded).
We calculate: $\text{Denominator} = 90 \text{ (Total Confirmed)} + 2 \text{ (Evicted } \ge 3) + 8 \text{ (Still Waiting } \ge 3) = 100$
$\text{Confirmation Fraction} = \frac{85}{100} = 0.85 \text{ (85%)}$
This bucket delivers an 85% historical success rate for a 3-block target.
Step 4: Top-Down Scanning and Merging Sparse Buckets
What happens if a feerate bucket only saw a single transaction over the last two days?
- If that lone transaction got lucky and confirmed in the next block, the bucket shows a misleading 100% confirmation rate.
- If it got unlucky, it shows 0%.
Making decisions based on single-transaction samples is statistical Russian roulette. To prevent this, Bitcoin Core enforces two rules: evaluate from the top down, and merge sparse buckets.
- Why Scan Top-Down?
Miners are greedy: they pick the highest paying transactions first. Therefore, absurdly high fee buckets almost always pass with near 100% success. The estimator starts at the top and scans downward toward cheaper fees until it discovers the boundary where confirmation certainty breaks down. - Merging Adjacent Buckets:
If a bucket does not contain enough transactions to meet the minimum sample size, the estimator doesn't discard it. It merges it with the next lower bucket, and keeps grouping adjacent lower buckets until the combined cluster reaches statistical significance. - Halting at the Boundary:
Once a merged group has enough samples, the estimator checks its combined confirmation fraction against the target threshold (e.g., 85%):- If it passes, the algorithm marks this feerate range as a safe candidate and keeps probing downward to see if the user can get away with paying even less.
- The moment a group fails, the scan halts immediately. The last passing group marks the floor.
- Picking the Fee: Within the winning bucket group, the estimator finds the bucket containing the median transaction and returns that bucket's average feerate.
Concrete Example 2: Scanning and Merging in Action
Suppose our required sample threshold is 10 transactions, our confirmation target is 3 blocks, and our required success threshold is 85%.
The algorithm begins scanning downward from the top:
- Bucket
[50.0 – 52.5 sat/vB]:- Has 25 transactions (clears the 10-transaction minimum).
- Confirmation fraction: 24 / 25 = 96%.
- Passes. The algorithm records this and tests lower rates.
- Bucket
[30.0 – 31.5 sat/vB]:- Contains only 4 transactions (too sparse; below the 10-transaction floor).
- The estimator refuses to evaluate it alone. It merges it with the adjacent lower bucket
[28.5 – 30.0 sat/vB], which has 7 transactions. - Combined range
[28.5 – 31.5 sat/vB]now holds $4 + 7 = 11$ transactions (meeting the threshold). - Combined confirmation fraction: 10 / 11 = 90.9%.
- Passes. The algorithm records this as the new best candidate and continues lower.
- Bucket
[25.0 – 28.5 sat/vB]:- Contains 15 transactions (sufficient data).
- Combined confirmation fraction: 8 / 15 = 53.3%.
- Fails (well below 85%).
The scan halts on the spot. The lowest passing range was [28.5 – 31.5 sat/vB]. The estimator takes the median transaction in that cluster, returning an estimate of 29.8 sat/vB.
Step 5: Teaching the Node to Forget (Exponential Decay & Half-Life)
Cumulative counters introduce a dangerous flaw: historical inertia.
Imagine a chaotic Monday afternoon where a market flash-crash drives feerates to 120 sat/vB for six hours. Tens of thousands of transactions confirm at panic rates, while lower fee buckets register zero progress.
Now wake up on Tuesday morning. Network traffic has returned to normal. People paying 15 sat/vB are confirming within a block or two. But if your node kept permanent cumulative counters, those thousands of high-fee transactions from yesterday would continue dominating the denominator. The algorithm would remain trapped in yesterday's panic, advising users to pay 100+ sat/vB long after the network cleared.
To prevent this, Bitcoin Core implements an exponential decay factor ($D$, where $0 < D < 1$) that acts like ink gradually fading on a whiteboard. Every time a new block is mined, all historical counters are multiplied by $D$:
$\text{Counter}_{\text{new}} = \text{Counter}_{\text{old}} \times D$
This mathematical erosion applies across Total Confirmed, Confirmed-Within, Failed, and Feerate Sum counters.
When a new block is mined:
- Every historical ledger entry is shrunk by multiplying by $D$.
- The fresh observations from the newly mined block are stacked on top with full weight ($+1.0$).
Over time, older network events dissolve into statistical background noise.
The Intuition of Half-Life
The clearest way to picture the decay factor $D$ is through its half-life—how many blocks must pass before a historical data point loses half of its influence:
$\text{half-life} = \frac{\ln(0.5)}{\ln(D)}$
Bitcoin Core sets its short-term decay factor to 0.962:
- $0.962^{18} \approx 0.50$
- This equals a half-life of 18 blocks (approximately 3 hours).
A transaction that confirmed 18 blocks ago carries only 50% of its original weight today. After 36 blocks (~6 hours), it has faded to 25%; after 54 blocks (~9 hours), just 12.5%. This exponential fading allows the estimator to adapt quickly to calm waters without suffering complete amnesia from a single unusual block.
Concrete Example 3: Decaying Away Yesterday's Spike
During an intense congestion surge, high-fee bucket [60.0 – 63.0 sat/vB] recorded 100 confirmed transactions, while low bucket [15.0 – 16.0 sat/vB] had 0 confirmations because it was completely priced out.
The surge ends:
- Over the next 18 blocks, traffic normalizes. 20 new transactions confirm in the cheap bucket
[15.0 – 16.0 sat/vB]. - Nobody pays 60 sat/vB anymore (0 new transactions enter that bucket).
Every block, all counters are multiplied by $0.962$. After 18 blocks ($0.962^{18} \approx 0.50$):
- The high-fee bucket has decayed: $100 \times 0.50 =$ 50 effective transactions.
- The 20 new transactions in the lower bucket entered throughout those 18 blocks, maintaining an effective weight of 15 to 18 transactions.
Because of decay, the lower bucket's fresh confirmations rapidly accumulate dominance, while the phantom of the 60 sat/vB spike is cut in half every 3 hours. Within half a day, the 15 sat/vB bucket re-establishes itself as the passing fee rate.
Why the Minimum Sample Size Isn't a Magic Number
Earlier, we mentioned that the algorithm requires around 10 to 20 transactions before considering a merged bucket valid. Where does that number come from?
It isn't an arbitrary guess hardcoded by developers. It is mathematically tied directly to the decay factor!
Bitcoin Core requires an average historical arrival rate of at least $S = 0.5$ transactions per block. If new data arrives at rate $S$ and decays at rate $D$ per block, the infinite series converges to a steady-state sample sum:
$\text{Sample Threshold} = \frac{S}{1 - D}$
Plugging in our short-term decay rate ($D = 0.962$) and $S = 0.5$:
$\text{Sample Threshold} = \frac{0.5}{1 - 0.962} = \frac{0.5}{0.038} \approx 13.2 \text{ transactions}$
This is why the algorithm merges buckets until gathering an effective weight of roughly 13 to 21 transactions. The threshold is the natural equilibrium of the decay mathematics.
Reality Defense: Protecting Against the Real World
If Bitcoin generated blocks like clockwork every ten minutes on the second, basic historical probability would be enough. But Bitcoin operates in a messy real world governed by Poisson randomness and shifting human time horizons.
The Triple Safety Net: Defending Against Block Droughts
Bitcoin block intervals follow a memoryless Poisson process. While the long-term average is 10 minutes, the variance is notorious: miners occasionally find three blocks in 4 minutes, and other times an unlucky drought stretches for 70 minutes without a single block.
During a 70-minute dry spell, transactions keep pouring into mempools. When a block is finally struck, an entire hour's worth of transactions fights for a single megabyte of space.
If an estimator only checked whether 85% of transactions confirmed within $N$ blocks during average conditions, an unlucky block drought right after you broadcast would leave your transaction stranded.
To protect users against this tail risk, Bitcoin Core runs three separate target-and-threshold tests for any requested target $N$:
| Check | Target Tested | Success Threshold | Purpose |
|---|---|---|---|
| 1. Fast-Track Check | Half Target ($N / 2$) | 60% | Ensures the transaction confirms promptly if blocks arrive quickly. |
| 2. Baseline Check | Target ($N$) | 85% | The standard confirmation target under normal conditions. |
| 3. Tail-Risk Safety Net | Double Target ($2 \times N$) | 95% | The catastrophe buffer. Demands near-certainty within twice the target time to survive an unlucky block drought. |
The Maximum Rule: Choosing the Highest Fee
Bitcoin Core evaluates all three tests and selects the maximum feerate among them:
$\text{Recommended Feerate} = max(\text{Feerate}_{N/2}, \text{Feerate}_{N}, \text{Feerate}_{2N})$
By taking the maximum, the algorithm guarantees that all three safety requirements are met simultaneously. If surviving a block drought requires a higher fee to achieve that 95% buffer, the estimator automatically steps up to protect you.
Concrete Example 4: The Tail-Risk Buffer at Work
Suppose a user requests confirmation within 6 blocks (roughly 1 hour on average):
- Half Target check (3 blocks @ 60% probability): Scanning buckets shows that 18.0 sat/vB was enough.
- Baseline check (6 blocks @ 85% probability): Scanning buckets shows that 20.0 sat/vB was enough.
- Double Target check (12 blocks @ 95% probability): Scanning buckets shows that achieving 95% certainty within 12 blocks required 24.0 sat/vB.
Notice that the 95% test at double the target demanded a higher feerate (24 sat/vB) than the standard 85% test (20 sat/vB).
Why? Because historically, when a Poisson block drought struck, transactions paying only 20 sat/vB got pushed back by accumulating backlogs, and some were still stranded after 12 blocks. Reaching 95% resilience against worst-case delays required 24 sat/vB.
By taking $\max(18.0, 20.0, 24.0) = \mathbf{24.0 \text{ sat/vB}}$, the algorithm shields the user from multi-hour limbo.
The Three Time Horizons: Goldfish vs. Elephant Memory
A single decay rate cannot serve all users.
- If you need confirmation within 2 to 6 blocks (under an hour), you need an agile estimator with a short memory that shakes off past spikes quickly.
- But what if you are setting a confirmation target of 144 blocks (1 day) or 1008 blocks (1 week)? With a 3-hour half-life, data from 24 hours ago would decay down to less than 0.5% of its original weight. It would be mathematically impossible to track whether a transaction confirmed within a day!
- Conversely, using a slow, 1-week memory for next-block estimates would make the node sluggish, forcing users to overpay for hours after a spike clears.
Bitcoin Core solves this by operating three independent tracking engines in parallel, each tuned with its own decay rate and tracking horizon:
| Horizon | Decay Factor ($D$) | Half-Life | Maximum Tracked Target | Target Resolution |
|---|---|---|---|---|
| Short (Agile) | 0.962 | ~18 blocks (3 hours) | 12 blocks (~2 hours) | 1 block |
| Medium (Balanced) | 0.9952 | ~144 blocks (1 day) | 48 blocks (~8 hours) | 2 blocks |
| Long (Deep Memory) | 0.99931 | ~1008 blocks (1 week) | 1008 blocks (~1 week) | 24 blocks |
Query Routing and the Monotonicity Override
When you query target $N$, Bitcoin Core follows two common-sense rules:
- Shortest Horizon Rule: The estimator always selects the shortest horizon capable of tracking target $N$:
- Targets 2 to 12 query the Short Horizon.
- Targets 13 to 48 query the Medium Horizon.
- Targets 49 to 1008 query the Long Horizon.
- The Monotonicity Override (Common-Sense Sanity):
Common sense dictates that being willing to wait longer should never cost you more money.
However, because the Medium Horizon has a longer memory than the Short Horizon, a recent drop in network fees registers in the Short Horizon first. If a user asks for target 14 (Medium Horizon) and gets 22 sat/vB, but the Short Horizon at its maximum capacity (target 12) shows that 16 sat/vB is already sufficient, Bitcoin Core overrides the estimate and lowers it to 16 sat/vB.
Concrete Example 5: Querying Different Horizons
Network fees spiked yesterday but have plunged over the last 4 hours:
- Scenario A: Urgent Target ($N = 4$ blocks)
Queries the Short Horizon. Thanks to its 3-hour half-life, yesterday's spike has already decayed into insignificance. The node returns a responsive fee of 12.5 sat/vB. - Scenario B: Patient Target ($N = 20$ blocks)
Target 20 exceeds the Short Horizon's 12-block limit, so it queries the Medium Horizon.- With its 1-day memory, the Medium Horizon still retains remnants of yesterday's congestion and calculates 19.0 sat/vB.
- The estimator checks the maximum target of the shorter horizon (target 12 in Short Horizon), which yields 14.0 sat/vB.
- Applying the monotonicity override, the estimator returns 14.0 sat/vB.
Conservative Mode vs. Economical Mode
When calling estimatesmartfee, wallets can specify either CONSERVATIVE (the default) or ECONOMICAL mode. This setting configures how defensively the algorithm treats fee drops:
- Economical Mode (The Optimizer):
- Evaluates the 95% safety check only within the shortest time horizon covering the target.
- Allows shorter horizons to pull down fee recommendations via monotonicity overrides.
- Best for: Cost-sensitive users, background balance reallocations, or non-urgent payments where an occasional delay is an acceptable trade-off for saving sats.
- Conservative Mode (The Insurance Policy):
- Requires that the 95% safety check passes not just in the shortest horizon, but across all longer time horizons as well.
- Ignores shorter-horizon downward overrides for the safety test, preventing temporary lulls from dragging estimates down prematurely.
- Best for: Time-sensitive transactions, merchant settlements, or payments where getting stuck for hours would cause headaches.
The Grand Coordination: Why We Take the Minimum
We now arrive at the full picture of estimatesmartfee.
For targets beyond 2 blocks ($N > 2$), the decision is simple: Bitcoin Core relies exclusively on the historical Block Policy Estimator, because a live mempool snapshot cannot predict conditions several hours down the road.
However, for immediate confirmation targets ($N \le 2$), Bitcoin Core consults both estimators simultaneously.
And when both return a valid answer, it applies the Minimum Selection Rule:
$\text{Recommended Feerate} = min(\text{Feerate}_{\text{Block Policy}}, \text{Feerate}_{\text{Mempool Policy}})$
The Intuitive Paradox: Why Take the Minimum?
Wait a second. In the previous section, we saw that to protect against tail risk, the estimator took the maximum among three safety checks. Why on earth are we taking the minimum here?
Taking the minimum seems risky at first glance, but it serves as an essential relief valve against historical lag.
Consider what occurs the moment a major fee surge ends:
- Two hours ago, intense congestion drove feerates to 80 sat/vB.
- The Block Policy Estimator—even with its fast 3-hour half-life—still remembers that surge and calculates that confirming in 2 blocks historically required 50 sat/vB.
- But right now, the storm has passed. The mempool is virtually empty. Miners are scooping up transactions paying just 3 sat/vB.
If Bitcoin Core relied only on historical data, every user querying fees would be forced to overpay by 16x for the next several hours until the counters decayed.
By taking the minimum, the Mempool Policy Estimator steps in as an instant circuit breaker. Because it simulates the next block directly against the unconfirmed transactions waiting right now, it sees that the backlog has evaporated and returns 3 sat/vB.
$\min(50, 3) = \mathbf{3 \text{ sat/vB}}$
Taking the minimum punctures historical inertia, saving users from paying yesterday's panic prices today.
Conversely, if congestion is building up in real-time, the two estimators complement each other: the live mempool reflects the immediate queue, while the historical policy ensures fees aren't set too low based on empty past blocks.
Summary & Key Takeaways
Bitcoin Core's estimatesmartfee solves an extraordinarily difficult puzzle: how to price transactions accurately in a pure first-price auction without a central auctioneer, fixed block clocks, or in-protocol base fee adjustments.
Rather than relying on brittle heuristics or attempting to forecast the future, it balances statistical history against real-time observation:
- Feerate Bucketing: Groups continuous fees into roughly 240 exponentially scaled intervals (5% steps), making statistical tracking manageable.
- Top-Down Scanning & Merging: Evaluates from the highest fee downward (matching miner incentives) and merges sparse buckets to prevent small-sample distortions.
- Exponential Decay (EWMA): Multiplies historical counters by decay factors every block, ensuring older network states fade away systematically (a 3-hour half-life for short-term tracking).
- Triple Safety Net for Poisson Variance: Tests $N/2$ (60%), $N$ (85%), and $2N$ (95%) and takes the maximum, guaranteeing resilience against unlucky block droughts.
- Three Parallel Time Horizons: Uses Short, Medium, and Long horizons so that urgent transactions stay agile while patient transactions benefit from days of steady context.
- Live Mempool Simulation & The Minimum Rule: For immediate targets ($\le 2$ blocks), verifies mempool health over 6 blocks and takes $\min(\text{Block Policy}, \text{Mempool Policy})$, creating an instant relief valve that prevents users from overpaying after a fee spike clears.
By combining the stability of historical climate models with the real-time reactivity of looking out the window, Bitcoin Core delivers reliable fee guidance across quiet nights and wild fee surges alike.
References & Further Reading
Documentation & Design Notes
- High-Level Description of Bitcoin Core's Fee Estimation Algorithm by Alex Morcos
The foundational design notes and algorithm rationale from the author of Bitcoin Core's modern fee estimator. - An Introduction to Bitcoin Core Fee Estimation by John Newbery
A conceptual overview explaining the history, motivations, and trade-offs of Bitcoin fee estimation. - Bitcoin Core Fee Estimate Algorithm by Ian Yang
A deep dive breaking down confirmation fractions and internal tracking structures.
Bitcoin Core Source Code
src/policy/fees/block_policy_estimator.cpp
Implementation of historical fee buckets, decay mechanics, triple-threshold evaluation, and time horizons.src/policy/fees/mempool_estimator.cpp
Implementation of the simulated block template percentile calculation and the 6-block health check.src/policy/fees/estimator_man.cpp
The manager orchestrating both estimators and enforcing the minimum selection rule.