B++ Logo

Transaction Fees

Transaction fees are payments made to miners for including transactions in blocks. Understanding how fees work is essential for ensuring your transactions confirm in a timely manner.

Why Fees Exist

Fees serve multiple purposes:

  1. Incentivize miners: Reward miners for processing transactions
  2. Prevent spam: Make it expensive to flood the network
  3. Prioritize transactions: Higher fees = faster confirmation
  4. Economic security: Fees will replace block rewards over time

Fee Calculation

Fee Rate

Fees are calculated based on fee rate (satoshis per virtual byte):

Fee = Transaction Size (vbytes) × Fee Rate (sat/vB)

Example:
- Transaction size: 250 vbytes
- Fee rate: 10 sat/vB
- Total fee: 2,500 satoshis (0.000025 BTC)

Virtual Size (vbytes)

Since SegWit, transactions use virtual size instead of raw bytes:

Virtual Size = Weight / 4

Where:
Weight = (Base Size × 4) + Total Size

Base Size: Transaction without witness data
Total Size: Transaction with witness data

Fee Estimation

Methods

Wallets estimate fees using several approaches:

  1. Mempool analysis: Look at pending transactions
  2. Fee estimation APIs: Services like mempool.space
  3. Bitcoin Core RPC: estimatesmartfee command
  4. Historical data: Analyze past fee patterns

Fee Targets

Common confirmation targets:

TargetDescriptionTypical Fee Rate
Next blockHighest priority50-200+ sat/vB
3 blocks~30 minutes20-50 sat/vB
6 blocks~1 hour10-20 sat/vB
EconomyNo rush1-10 sat/vB

Code Examples

Estimating Fees

Calculating Transaction Fee


Fee Bumping

When a transaction is stuck in the mempool because the fee rate is too low, you can increase the effective fee using Replace-by-Fee (RBF) or Child Pays for Parent (CPFP).

Replace-by-Fee (RBF) and BIP 125

RBF allows replacing an unconfirmed transaction with a new version that pays higher fees. The replacement must spend the same inputs and generally the same outputs (with stricter rules in BIP 125).

BIP 125 Replaceability Rules

For a replacement to be accepted by BIP 125-compliant nodes:

  1. Replaceability signal: The original transaction must signal that it is replaceable. This is done by setting the sequence of at least one input to a value below 0xfffffffe (and not 0xffffffff, which is used for locktime opt-out). In practice, nSequence < 0xfffffffe on any input makes the tx replaceable.

  2. Higher fee: The replacement must pay a higher total fee than the original.

  3. Higher fee rate: The replacement must have a higher fee rate (sat/vB) than the original.

  4. No new unconfirmed inputs: All inputs must be either:

    • already in the mempool, or
    • confirmed in the chain. The replacement cannot add inputs that are themselves unconfirmed and not in the mempool (to prevent dependency chains that complicate replacement).
  5. Output and amount constraints: The replacement cannot add new outputs, cannot remove outputs, and cannot lower any output amount. It can only change the fee (by reducing one or more output amounts or by adding/using extra inputs that are already confirmed or in the mempool).

Full RBF

Full RBF (Replace-By-Fee regardless of signaling) is a policy option on some nodes (including Bitcoin Core 24+ with -mempoolfullrbf=1). With full RBF, any unconfirmed transaction can be replaced by a higher-fee version, even if the original did not signal replaceability (sequence was 0xffffffff). This is not consensus; it is a relay policy. Miners and node operators may or may not enable it. When enabled, it allows fee bumping of "non-RBF" transactions, but recipients of unconfirmed outputs should treat them as replaceable.

Replaceability in Wallets

  • Senders: To allow RBF, wallets set nSequence to e.g. 0xfffffffd (or lower) on at least one input. Many wallets enable this by default.
  • Receivers: If you receive an unconfirmed payment, assume it can be double-spent or replaced until it has confirmations. For high-value accepts, wait for 1–6 confirmations.

Child Pays for Parent (CPFP)

CPFP is used when you cannot replace the original (e.g., you are the recipient and don’t control the inputs, or the original is not RBF-signaling). You create a child transaction that spends an output of the stuck (parent) transaction and attach a high enough fee so that miners are willing to mine both parent and child together. Miners evaluate the package (parent + child) by the combined fee and combined size; a high-fee child makes the package profitable.

Parent Transaction:
- Fee: 2 sat/vB (too low)
- Status: Stuck in mempool
- Has an output to you

Child Transaction:
- Spends the parent’s output to you
- Fee: e.g. 50 sat/vB
- Miner includes both; combined fee makes the package attractive

CPFP works only if you control an output of the parent (e.g., you received the payment). The child must be valid and, under typical package relay rules, the parent+child package must meet the node’s fee and size policies.

Transaction Pinning

Pinning is a class of attacks where an attacker tries to prevent a victim’s transaction from being replaced or from being mined, for example:

  • RBF pinning: The replacement is made to violate BIP 125 (e.g., by making the victim’s replacement depend on unconfirmed inputs that are not in the mempool, or by other rule games) so nodes reject it.
  • CPFP pinning: The victim’s child (or the package) is made to fail package validation, or the attacker spends the same parent output in a way that blocks the victim’s child.

Package relay and package RBF (see below) are designed to make fee bumping more robust and to reduce pinning: for example, by allowing replacement of a package (parent + child) and by standardizing how packages are validated and relayed.

Package Relay and Package RBF

Package relay (and related package RBF ideas) allow nodes to accept and relay a package of related transactions (e.g., parent + child) as a unit. The mempool and block construction logic can then:

  • Evaluate the package’s total fee and total size when deciding to accept or to mine it.
  • In package RBF, allow a replacement that is itself a package (e.g., a new parent+child that replaces a previous parent, or that bumps the effective fee of an unconfirmed parent via a new child).

As of this writing, package relay and package RBF are in BIP process and/or implemented as optional node policy (e.g., in Bitcoin Core). They are important for Lightning and other Layer 2 protocols that need to reliably fee-bump on-chain transactions.

When to Use RBF vs CPFP

SituationUse
You are the sender and control the inputsRBF: Create a replacement that pays more (and meets BIP 125).
You are the recipient and the sender did not enable RBF or you can’t replaceCPFP: Spend the output you received with a high-fee child.
You use Lightning or other L2RBF and CPFP (and, where available, package RBF) are used by the implementation to bump commitment or HTLC transactions.

Fee Market Dynamics

Supply and Demand

High Demand (many transactions):
- Mempool fills up
- Fees increase
- Users compete for block space

Low Demand (few transactions):
- Mempool empties
- Fees decrease
- Even low fees confirm quickly

Historical Patterns

Fees fluctuate based on:

  • Network activity: More users = higher fees
  • Block space competition: Limited space = bidding war
  • Market events: Price movements affect activity
  • Time of day: Regional usage patterns

Best Practices

For Users

  1. Use fee estimation: Don't guess fees
  2. Choose appropriate priority: Don't overpay for non-urgent transactions
  3. Use SegWit/Taproot: Lower fees for same functionality
  4. Monitor mempool: Check current conditions before sending

For Developers

  1. Implement fee estimation: Use APIs or RPC
  2. Support RBF: Allow fee bumping
  3. Handle fee errors: Gracefully handle insufficient fees
  4. Test fee logic: Verify calculations are correct


Resources