Skip to content
Tyrone Software
Crypto

Why a Bitcoin fee depends on bytes, not on the amount

Abstract illustration for the article Why a Bitcoin fee depends on bytes, not on the amount

Sending 0.001 BTC and sending 10 BTC cost the same fee if the transactions have the same shape. Bitcoin fees pay for space in a block, and the value moved is irrelevant to a miner.

Weight and virtual size

Since SegWit, block capacity is measured in weight units. A block can hold up to 4,000,000 weight units. Each byte of non-witness data counts 4 units, and each byte of witness (signature) data counts 1. The virtual size, vsize or vbytes, is the weight divided by 4. So a block is at most 1,000,000 vbytes, and the fee rate is expressed as satoshis per vbyte (sat/vB).

That is why SegWit spending is cheaper: the signature data is discounted, which shrinks the vsize of each input.

Table comparing the virtual size and fee of a simple Bitcoin payment with legacy and native SegWit addresses
The amount sent does not appear anywhere in this calculation.

Typical sizes

Approximate figures used by most wallet documentation:

  • A P2PKH (legacy) input is about 148 vB and an output about 34 vB.
  • A P2WPKH (native SegWit) input is about 68 vB and an output about 31 vB.
  • A transaction has around 10 vB of fixed overhead.

A payment with one native SegWit input, a recipient output and a change output is therefore around 140 vB. At 10 sat/vB the fee is around 1,400 satoshis. The same payment from legacy inputs and outputs is around 226 vB, about 60% more. The figures vary by script type (Taproot inputs are around 58 vB for key-path spends, for instance), so use your wallet library's size estimation for real transactions.

Many small inputs cost more

Because each input adds bytes, a wallet holding fifty small outputs pays much more to spend them than a wallet with one output of the same total value. That is one reason wallets consolidate inputs when fees are low, and a reason to think about the shape of your deposits if you run a service that receives many small payments.

Stuck transactions

If a transaction pays too low a fee rate, it waits in the mempool, and nodes can drop it after some time (the default in Bitcoin Core is two weeks). There are two standard remedies:

  • RBF (replace-by-fee, BIP 125): the sender broadcasts a replacement spending the same inputs with a higher fee. The transaction has to signal that it is replaceable, though recent Bitcoin Core versions have moved toward allowing replacement for every unconfirmed transaction by default, which is an area of ongoing change.
  • CPFP (child pays for parent): the receiver or the sender spends an output of the stuck transaction in a new one with a high fee, and miners consider both together.

In code

Never derive fee rates from a hard-coded number. Fee estimation endpoints (estimatesmartfee in Bitcoin Core, or the public mempool APIs) return a rate for a target number of blocks, and you multiply by the vsize you calculated. Keep the result as an integer number of satoshis, and rounding up is the safe direction.

Batching cuts the shared overhead across recipients

A service paying out to several recipients at once, an exchange processing withdrawals or a payroll-style payout, pays a fixed per-transaction overhead (roughly 10.5 vB) and one input only once, no matter how many recipients are paid in that same transaction, while paying it separately would repeat that overhead for every single payment. Combining five native SegWit payments that would otherwise be five separate transactions (about 140 vB each, 702.5 vB total) into one transaction with one input and six outputs, five recipients plus one change output, comes to about 264.5 vB, roughly 62% less total space for the same five payments. The saving grows with the number of recipients batched together, since the fixed overhead and the single input are what is being shared, while each additional output still costs its own roughly 31 vB regardless of batching; it is a straightforward argument for batching withdrawals when fee rates are elevated, at the cost of recipients no longer getting their own independent, immediately-broadcastable transaction the moment their specific payout is ready.

Keep reading

Technologies

  • Python
  • PHP
  • Laravel
  • Django
  • PostgreSQL
  • MySQL
  • HTML5
  • CSS3
  • Bootstrap