A week ago, I made a bitcoin transaction moving some sats to another wallet. My source wallet recommended a fee of 671 sats and while I knew I could update the fee before the transaction is confirmed, I was curious how long until a miner would add it to a block at that low low fee. I had one confirmation in roughly 12 minutes. Total fees paid: $0.21. So did I just move a little over $1000 for 20 cents? In under 15mins? Resisting all censorship? Yes! I wanted to understand transaction fees better, especially how they are estimated so I did some research.

In this article, I dive into Bitcoin transaction fees - specifically what they are, how they are estimated, and why they are important on the Bitcoin blockchain.

For any Bitcoin transaction, the fee is simply the difference between the sum total of the inputs and the sum total of the outputs.

**Why include fees?**

Every 10 minutes on average, a new block with potentially many transactions is mined and added to the blockchain. Each new block makes previously-confirmed transactions and blocks more secure. More on this in Section 11 of the Bitcoin whitepaper.

The primary reward for miners who successfully mine a block is new bitcoin. This is called the block subsidy and it halves programmatically every 210,000 blocks (or roughly every 4 years) to control supply. This is the only way *new* bitcoin is created.

The other reward for miners is transaction fees. Each block contains many transactions, each with fees attached to incentivize their confirmation.

The sum of these rewards is known as the block reward. As the block subsidy tends to zero in line with Bitcoin's monetary policy, the block reward will eventually constitute transaction fees only.

**How transaction fees are calculated**

Transaction fees are a function of the size of the transaction (in bytes, not the value sent) as well as the demand and supply market forces within the Bitcoin network at that time.

**On market forces**

On the supply side, Bitcoin has a cap on block size at 4 million weight units (WU) that limits the amount of transaction data that can be added to a block. However, Bitcoin's block discovery follows a Poisson distribution meaning that while the difficulty adjustment targets an average of one block every 10 minutes over long periods of time, the time within which blocks arrive over shorter periods of time, is unpredictable.

A new block may arrive in less than a second or more than 30 minutes after the previous block. It is important to understand that the waiting time between blocks is always 10 minutes. If you make a Bitcoin transaction now and check your node's log to find the previous block was mined 8 minutes ago, you are still expected to wait 10 minutes on average before the next block appears because mining is a memoryless process.

Regardless of when a new block is discovered, and since block size is limited, all the high fee transactions are drained out of the mempool first. Naturally, miners will prioritize transactions with high fee rates. I'll come back to this later on.

On the demand side, you have different users, each with their unique preferences. Some are willing to pay high fees on their transactions for faster confirmation while others are okay with waiting longer periods. More transactions also typically take place during business days. Furthermore, changes in bitcoin price can affect the level of congestion on the network as demand fluctuates.

**On size of the transaction**

Transaction size is usually calculated in virtual bytes (vB). Larger transactions take up more space in the block so it follows that they typically pay fees on a per-byte basis. Most wallets show users a fee rate which is calculated in satoshis per unit of data your transaction will consume on the blockchain and abbreviated as sats/vByte. The total fee paid by your transaction is then determined by multiplying the fee rate by the size of your transaction.

**Analysing the size of “normal” transactions**

All non-segwit transactions contain the following fields:

Field | Size |

Version | 4 bytes |

# of inputs | 1 byte for up to 252 inputs |

# of outputs | 1 byte for up to 252 outputs |

Outputs | variable |

Locktime | 4 bytes |

For each input, we find the following fields:

Field | Size |

Ref transaction hash | 32 bytes |

Ref Output index | 4 bytes |

Unlocking Script Length | 1 byte for a scriptSig up to 252 bytes. |

ScriptSig | variable |

Sequence | 4 bytes |

For each output, we find the following fields:

Field | Size |

Value/amount | 8 bytes |

Locking Script Length | 1 byte for numbers 1 to 252 |

ScriptPubKey | variable |

For non-segwit transactions, each byte of data counts for 4 Weight Units.

So, let’s look at this non-segwit transaction as an example.

Here’s the transaction hex:

```
0100000001c8dbff8f335233499b475c35e3d5a99674cf041cb5ccecb926917fa8faf3b53a05000000fc0047304402201f0df63262e990fdbe01924836f6b0817bb5e124edb582d24a9345173430dcdd02200ecce8cd37909a7d26ad51528e6d50652aee0d3394885d4be50cdccafdb3fa66014730440220760dd785352dd7fdcac9459c4e969b9be1e3f686da817a59a0d5e492eb6970240220184ab3303558974554c3509ea991c9321b100ad2a39ab6f100f954bfd7aa0350014c695221021e93ae8a3dfd54da1c49b523c00dde5974d585fe59c92d6c0a1d41250bd9ca292103af3317a1a9f8cf8e81ce66128b2b9023514d42a1511cf09771e565bcdecfb37e2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053aeffffffff0280a21900000000002200206ffd48f065e61dd8e1091f1aa9819cf5b45692d68e1ce3691aaf69014e26715576ce0500000000002200202122f4719add322f4d727f48379f8a8ba36a40ec4473fd99a2fdcfd89a16e04800000000
```

If we decode the hex, we get:

Data | Detail | Raw bytes | Multiplier | Total WU | Cumulative total |

01000000 | Version 1 | 4 | 4x | 16 | 16 |

01 | # of inputs (1) | 1 | 4x | 4 | 20 |

c8 ... 3a | Ref output hash | 32 | 4x | 128 | 148 |

05000000 | Ref output index | 4 | 4x | 16 | 164 |

fc | Script length | 1 | 4x | 4 | 168 |

0047...ae | P2SH Script | 252 | 4x | 1008 | 1176 |

ffffffff | Sequence | 4 | 4x | 16 | 1192 |

02 | # of outputs (2) | 1 | 4x | 4 | 1196 |

80a2190000000000 | Value for output #1 | 8 | 4x | 32 | 1228 |

22 | Script length for output #1 | 1 | 4x | 4 | 1232 |

002...76ce | P2WSH Script for output #1 | 36 | 4x | 144 | 1376 |

0500000000002200 | Value for output #2 | 8 | 4x | 32 | 1408 |

20 | Script length for output #2 | 1 | 4x | 4 | 1412 |

212...048 | P2WSH Script for output #2 | 32 | 4x | 128 | 1540 |

00000000 | Locktime(0) | 4 | 4x | 16 | 1556 |

The total size of the transaction is 1556 Weight Units. We can divide this by 4 to get the transaction size in virtual bytes which is 389vB.

**Analysis**: With the total input of 0.02118974 BTC and a combined output of 0.02060534, the total fees paid for this transaction is 0.0005844 BTC or 58,440 sats. From that, we can deduce the fee rate as 150 sats/vB. Given that this is a non-segwit transaction, the transaction size could have been smaller, therefore, requiring less fees.

Before segwit, each block was limited to 1MB of data. Segwit's activation introduced a block size limit increase to a realistic 2MB or 4MB theoretically, depending on the types of transactions in the block. Since block weight is calculated in weight units, and one byte of a transaction's non-witness data is worth 4 weight units while one byte of witness data is worth 1 weight unit, it is critical to understand that if a block contains only non-segwit transactions, the 4 million weight unit limit will be equivalent to the old 1MB limit.

#### Analysing the size of segwit transactions

Segwit transactions include extra fields like segwit marker, segwit flag, and Witness Data. All segwit data only counts for 1 WU for each byte of data which is why transaction size is smaller.

Let's dissect a segwit transaction. Here's the transaction hex:

```
02000000000104d00c17272700f550acf497e58ed363aa5936f6cb9e5f38d3017bc7df8876264a0c00000000fdffffff507edacb050beb8b464e59481106b6e18e49e30bc5767dae031c564f873cd1880100000000fdffffff62e5bac3018f0634892ce0d8b1f544d44604c6327473b42d29a551396de962b90000000000fdffffff9386294e7f4814689f1d4dfd98f77464a365bf1f99e5bb77a28cf508a82095ff010000006a473044022004cb8e6be705aa1716f998cba290deab940e80ef55524f3ac8183dd118146799022039d38230e2f863d31b4dc3540a1feb151e96a249ad7b2ca7627d536f41e8c7b2012102347f6038e5e7bef533aa2368289699fb33307639e7429fb21aa44bc75b981e5afdffffff01757d380000000000160014617ce12b116c47d3a7e42cc397a7d1b54a78b00d0247304402200878f95f1d65558ae53f6137053f62e0880c2515c9f612129e0c57466a0b5a7202206d9da85f70cdac3d9d2e3a2659a908fc8543c36245df9b701636e7bde94b830e0121020d031ea1eb8acd3403a667bf9668149a71ce82ecae6033e02a99e6872ca4560302473044022014569fd7719206fb49b74c0382bc2c80e1607c3c08f46df2893d37cba4400be502207086e9bc5f143dce6cc16dfd62d7b001770242076c70728fa277063b5ad9083c012102a9475d31d113c981b77e06fb2b83bbcc682c5a98104f47d29139b58f697aba6d02473044022052ee83f71bb88a8f33b53f638dd6998f925f0c2ff419fce7cde7315c3b6a084a02202a1c0c89c84d2361443316d2f83bb8ec6e3cdb454614fb0f0b614056f3db5d4b012103e8817a0aa5404064b5852d26ded6f165fc394378286226c2b4f139fe98319a3a0012440b00
```

If we decode the hex, we get the following data:

Data | Detail | Raw bytes | Multiplier | Total WU | Cumulative total |

02000000 | Version 2 | 4 | 4x | 16 | 16 |

00 | segwit marker | 1 | 1x | 1 | 17 |

01 | segwit flag | 1 | 1x | 1 | 18 |

01 | # of inputs (1) | 1 | 4x | 4 | 22 |

cab ... 2cf | Ref output hash | 32 | 4x | 128 | 150 |

14000000 | Ref output index | 4 | 4x | 16 | 166 |

fd | Script length | 1 | 4x | 4 | 170 |

00 (empty) | P2WPKH Script | 0 | 4x | 0 | 0 |

fdffffff | Sequence | 4 | 4x | 16 | 186 |

02 | # of outputs (2) | 1 | 4x | 4 | 190 |

6406010000000000 | Value for output #1 | 8 | 4x | 32 | 222 |

16 | Script length for output #1 | 1 | 4x | 4 | 226 |

001...40f | P2SH Script for output #1 | 22 | 4x | 88 | 314 |

60361e0000000000 | Value for output #2 | 8 | 4x | 32 | 346 |

17 | Script length for output #2 | 1 | 4x | 4 | 350 |

a91...587 | P2WSH Script for output #2 | 23 | 4x | 92 | 442 |

0247 ... 4976 | Witness Data | 107 | 1x | 107 | 549 |

2b550900 | Locktime(0) | 4 | 4x | 16 | 565 |

The total size of this transaction is 565 WU or 142vB. If we review the transaction again, you can see that the total input is 0.02118172 BTC and the combined output value is 0.02047172 BTC. The fee paid therefore is 0.00071 BTC or 71,000 sats. We can deduce that the fee rate is 500 sats/vB. This is quite expensive. However, we can also see that the transaction opted into Replace By Fee (RBF) - BIP125 so it is possible the user bumped the fees to get the transaction mined into a block faster.

**On Fee Rate**

Miners will prioritise transactions with high fee rates rather than fees. The difference is crucial, because a large transaction (in terms of WU) could have a massive fee, but still have a lower fee rate than a load of smaller sized transactions. In this case, the miner would fill the block with many smaller, high fee-rate transactions.

**Conclusion**

The variations in demand and supply established a dynamic fee market which introduced fee estimation algorithms making it possible for users to make trade-offs between confirmation time and transaction cost. The algorithms make recommendations for how much fees are necessary to get a specific transaction of predetermined size confirmed in the shortest possible time, while taking into consideration prevailing market conditions. However, this attempt to predict the future is not without its shortcomings.