News

Saving up to 80% on Bitcoin transaction fees by batching payments

Saving up to 80% on Bitcoin transaction fees by batching payments

Saving up to 80% on Bitcoin transaction fees by batching payments

By: David A. Harding

What if I told you that there’s a way you can save more than 80% on transaction fees by compressing your Bitcoin transactions? You’d probably think I was crazy or was proposing a radical change to the Bitcoin system. But I’m not.

Since the earliest version of Bitcoin, it has been possible to combine multiple Bitcoin payments into a single transaction, significantly reducing overhead. In this article, we’ll describe why payment batching works, how much it can save you, how to use it, and how much block chain space would be saved if it was used more frequently.

Inputs, change outputs, and payment outputs

Let’s imagine buying lunch at a local pub. First, we’ll pay with physical cash to see how it works and then we’ll switch to electronic cash — that is, bitcoin — to see the similarities.

Alice the customer has a pleasant lunch at Bob’s Pub and is presented with a bill by her waiter Charlie for $10. Alice pays Bob with a twenty dollar bill and receives $10 in change.

Bitcoin transactions work basically the same way. To keep the examples simple, let’s imagine one bitcoin equals one dollar. Alice receives the bill for 10 BTC and starts a transaction by adding a 20 BTC input from her wallet. Then she adds two outputs: a 10 BTC output that goes to Bob and another 10 BTC output that returns the change to her own wallet.

Here’s what Alice’s serialized Bitcoin transaction looks like, with the different parts colored according to how they’re used: white for the boilerplate parts of the transaction, pink for Alice’s input, green for Alice’s change, and blue for the payment to Bob.

Byte map of a P2PKH transaction with one change output and one payment output

And here are the sizes of each part of the transaction:

  • Container (white): 10 bytes
  • Input (pink): 148 bytes
  • Change output back to Alice (green): 34 bytes
  • Payment output to Bob (blue): 34 bytes
  • Total: 226 bytes

But wait, Alice almost forgot to tip Charlie for his excellent service. For physical cash, Alice makes a second transaction by taking the $10 she received in change, trading it for some small denomination money, and leaving a 15% tip of $1.50 on the table, keeping the other $8.50 in change for herself.

In Bitcoin, Alice also creates a second transaction in order to pay Charlie a tip. Since each normal single-payment transaction in Bitcoin has exactly the same parts as the transaction illustrated above, the second transaction requires adding another 226 bytes to the block chain for a total of 452 bytes.

A more efficient way

Alice could increase her efficiency by combining these two separate payments into a single transaction. For physical cash, this is similar to Alice paying her original bill by handing Charlie $20 in physical cash and telling him to pay both Bob and himself by only bringing back $8.50 in change — keeping the rest ($1.50, or 15%) as a tip.

In Bitcoin, Alice adds an additional output to her transaction (shown below in yellow) that pays Bob his 1.5 BTC tip:

Byte map of a P2PKH transaction with one change output and two payment outputs

Here’s are the sizes in the new batched payment:

  • Container (white): 10 bytes
  • Input (pink): 148 bytes
  • Change output (green): 34 bytes
  • Payment output to Bob (blue): 34 bytes
  • Payment output to Charlie (yellow): 34 bytes
  • Total: 260 bytes

This total of 260 bytes is considerably less than the 452 bytes it took us to create two separate transactions in the previous section.

Looking closely, we can see that the only difference in byte sizes between a single payment and a batched payment is the number of non-change outputs. Everything else in the transaction stays the same. This allows us to create a quick function for computing the amount of bytes used per payment as the number of payments (outputs) in a single transaction increases.

We add up the bytes used by the container, input, and change output (10 + 148 + 34). Then for each additional payment, we add 34 bytes to the transaction (x * 34). Finally, we divide the total bytes by the number of payments (x) to get the number of bytes used per payment. Here’s the result of plotting our function:

Even batching just a few payments can significantly reduce block space usage

We see that combining 10 payments together is about 25% the byte size of 10 payments made separately, saving about 75%. Slightly more can be saved as the number of payments per transaction increases.

Potential problems

A few months ago, the Bitcoin exchange Kraken increased its withdrawal fees to 0.0025 BTC (about $7 USD at the time); after a number of customer complaints, they instituted payment batching and lowered their fee to $0.001 (about $2.80 at the time).

This has a notable downside. When you receive your withdrawal from Kraken, you can look up your transaction on a block chain explorer and see the addresses of everyone else who received a payment in the same transaction. You don’t know who those recipients are, but you do know they received bitcoins from Kraken the same as you.

That’s not good for privacy, but it’s also perhaps not the worst thing. If Kraken made each of those payments separately, they might still be connected together through the change outputs and perhaps also by certain other identifying characteristics that block chain analysis companies and private individuals use to fingerprint particular spenders.

However, it is something to keep in mind if you’re considering batching payments where privacy might be especially important or already somewhat weak, such as making payroll in a small company where you don’t want each employee to learn the other employees’ salaries.

Using transaction batching yourself

For a high-frequency spender such as an exchange, payment batching can pay an immediate large dividend in saved transaction fees (or happier customers if the savings is passed along). This is especially true for businesses that already use Bitcoin Core or other full nodes with a similar API. Instead of sending payments with the `sendtoaddress` RPC like this:

sendtoaddress 1FjdYJTkdmA2KYvGqRX3G3WJeTFABgUJsJ 1.23
sendtoaddress 194hTHKyJchh6dV8a5Ce5Jd1ENEaxMyKUK 4.56

You batch payments using the `sendmany` RPC like this:

sendmany ‘’ ‘{“1FjdYJTkdmA2KYvGqRX3G3WJeTFABgUJsJ”: 1.23, “194hTHKyJchh6dV8a5Ce5Jd1ENEaxMyKUK”: 4.56}’

For lower frequency spenders, the first step of payment batching is waiting until you have several different payments you want to send at the same time. For example, say you want to renew a domain on Gandi.net, buy a gift card to Amazon.com from Gyft.com, and pay your monthly VPN bill from PrivateInternetAccess.com. Open Bitcoin Core, go to the Send screen, and enter the address and amount for the first merchant (Gandi in our example). Then click the Add Recipient button:

Click the Add Recipient button to add an additional payment

New enter the address and amount for the second merchant, click the Add Recipient button again, and enter the address and amount for the third merchant:

Bitcoin Core with three different recipients in a single transaction

Then select your fee and other options like normal and click Send. If you pay close attention to fees, you’ll notice the overall fee for this transaction is slightly higher than that for a normal single payment (because this transaction is about 68 bytes larger than a normal single payment), but you’ll also notice that’s about 57% percent less than you’d pay for three separate normal single payments.

Realistically, how much space could we save?

Not every payment can or should be batched, but I think there’s a way we can get a quick estimate of how much payment batching could save us on Bitcoin today. When we look at a block, we can see which transactions have inputs that are also outputs of an earlier transaction in the same block.

All of the related payments in a single block could’ve been batched without any reduction in speed, and possibly with minimum reduction in privacy, so we’ll use that as a rough approximation of the minimum amount of block space we could save if payment batching was more widely used. If users are willing to wait longer to send their transactions, they could batch even more payments and save even more block space.

Writing some quick code and taking a look at an arbitrarily-selected recent block, block 480,000, we get the following statistics:

  • Actual total size of all transactions: 997,883 bytes
  • Hypothetical size if all related transactions in that block were batched: 907,839 bytes
  • Bytes saved: 90,044
  • Percentage savings: 9%

At the time of writing, the average fee rate over the past 144 blocks (one day) is 236 satoshis per base byte and the Bitcoin price is $4,550 USD, so if each of the 144 blocks in an average day saved 90,000 bytes, the estimated savings available would be about 30.58 BTC or $140,000 USD per day.

Follow us on: Facebook


Tags

Related Articles