Transaction batching works by packaging up many customer send requests into a single transaction rather than creating a new transaction for every request. In doing so, we are able to amortize the overhead cost of a transaction across multiple send requests, which in turn reduces the effective transaction fee per request. This has the added benefit of also reducing the load on the overall Bitcoin network as each new block has limited space available and batching allows us to fit more payments in a smaller space.
A Simplified Example
Let’s take a look at a simple example. A Bitcoin transaction has 3 primary components:
Inputs: The coins being spent as part of the transaction.
Outputs: The payments being made, including the receiver’s address and amount.
Headers: Standard fields included on every transaction such as version info.
Transaction fees in Bitcoin are actually a function of the virtual byte size (or weight units) of the raw transaction, where larger sizes generally require larger fees to be paid (based on the current network fee rate). For the purpose of this example, we will just treat virtual bytes (vbytes) as standard bytes (see here to learn more about virtual bytes and changes that were introduced by SegWit).
Each of the three components above has a specific size and thus contributes to the overall transaction size in its own way. Assuming a fully native SegWit transaction, the three components have the following approximate sizes:
67 vbytes per input
31 vbytes per output
11 vbytes for headers
With this understanding, let’s compare two scenarios, one with batching and one without. (Note that for each scenario, to calculate the total fee, we will assume a network fee rate of 10 satoshis per vbyte.)
Scenario 1: No Batching
In this scenario we have three separate transactions. Each transaction has a single input and two outputs. The first output corresponds to the customer’s specific send request (an address and an amount), while the second output is sending any excess change back to Coinbase. (Note that the change output is required as the input amount being spent is not the same as the output amount being sent and there is generally some funds leftover.)
Each transaction above has a total size of 140 vbytes. Using a fee rate of 10 satoshis per vbyte, we can calculate that each of them have a transaction fee of 1400 satoshis.
Scenario 2: Batching
In this scenario, we batch all three of these requests into a single transaction. This transaction will still have one input, however, because we are batching requests together, we now have four outputs. The first three outputs correspond to each of our customers’ send requests while the last output is the change output for any remaining funds left over.
In the batched transaction example above, we can see that we have a total size of 202 vbytes for a total fee of 2020 satoshis. This equates to an effective fee of 673 satoshis per send request, or a 52% reduction in fees! This fee savings becomes even greater the more payments that we batch together.
Reflection 1: 75.2% Reduction in Consumer Transaction Fees
As previously stated, since launching on March 12th we have batched 100% of Consumer and Pro customer withdrawals. Over this time period, we have realized a 75.2% reduction in transaction fees saved, and passed 100% of those savings on directly to the customer.
In the chart below, you can see the Bitcoin transaction fee estimate (in satoshis) provided to Coinbase Consumer for a single send request over the last three months. As you can see, not only are fees significantly reduced, but they are also less volatile during periods of high activity such as the fee increases seen during mid-May.
Reflection 2: 95% Reduction in Transactions Generated Per Day
Something else we have seen from batching is a tremendous decrease in the overall transaction count that we generate per day. Instead of generating n transactions for n send requests, we now effectively generate a constant number c of transactions per day for n send requests, where c is based on how often we decide to batch up payments (today this happens at least once per minute). The chart below shows the magnitude of this change by showing unique transactions being broadcast per day in the weeks around the time of launch.
This is a win for us internally as it means our services are doing less work to achieve the same end result. This change has also had a positive impact on the overall Bitcoin network. By issuing the same number of send requests in a smaller footprint (fewer transactions and less block space needed), we are able to be more efficient and our overall impact on the network is reduced. Conservate estimates suggest that this has contributed to a 10–15% reduction in the number of confirmed transactions per day on the entire network. This transaction count reduction is beneficial for the network as a whole, and should help lower fees for all Bitcoin users.
Source: CoinmetricsReflection 3: 78% Reduction in Internal Alerts
Lastly, we’ve also seen significant gains in terms of internal operations. As engineers working on critical services for the business, we are constantly monitoring our systems and alerting engineers when services start operating outside of normal thresholds. One key metric here for Bitcoin is the time it takes for a send request to get processed and submitted to the network as a transaction. You can think of this as the delay between clicking the Send Now button on Coinbase Consumer and the time you actually see your transaction on the network.
Prior to batching, this delay would sometimes increase due to elevated levels of activity on the Bitcoin network as well as occasional delays between blocks getting mined by miners. Due to the way hot wallets work, we are almost always waiting on the change output from a previous transaction to get confirmed so that we can use those funds to fulfill another send request. When we were creating a separate transaction for every request, we had many more of these change outputs pending at any given time. This problem could sometimes introduce delays for subsequent send requests. Now that we are creating 95% fewer transactions, we have fewer change outputs to wait on and this problem has nearly gone away entirely.
The chart below shows related internal Bitcoin alerts for our on-call team over the last 6 months to showcase just how impactful this has been for us. In this time, we have seen a ~78% reduction in the number of alerts related to Bitcoin request processing and delays.
Conclusion
Transaction batching is an incredibly successful feature benefitting Coinbase customers, internal operations, and the entire Bitcoin network. If you enjoy working in a fun, high energy environment and want to work on scaling challenges like this one, check out our open positions on our careers page. We’d love to hear from you.
This website contains links to third-party websites or other content for information purposes only (“Third-Party Sites”). The Third-Party Sites are not under the control of Coinbase, Inc., and its affiliates (“Coinbase”), and Coinbase is not responsible for the content of any Third-Party Site, including without limitation any link contained in a Third-Party Site, or any changes or updates to a Third-Party Site. Coinbase is not responsible for webcasting or any other form of transmission received from any Third-Party Site. Coinbase is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement, approval or recommendation by Coinbase of the site or any association with its operators.
All images provided herein are by Coinbase unless otherwise provided.
was originally published in The Coinbase Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.