*Posted by Sacha Saint-Leger on December 12, 2019*

By some estimates zkRollup could help Ethereum increase it throughput to 3000 transactions per second (tps). This essay is an attempt to verify this claim.

Did you know that the Istanbul upgrade includes an EIP that allows Ethereum to scale up to 3000 TPS?

— eric.eth (@econoar) December 5, 2019

To put this in context, 2000 tps is what the Visa network currently averages.

Ethereum currently supports around 30 tps. So as you can see, if these estimates are correct, this is a pretty important performance improvement.

The Istanbul hard fork — which took place on December 7th — is the latest upgrade to Ethereum.

Istanbul contains two Ethereum Improvement Proposals (EIPs) that make zk-SNARKs cheaper — EIP-1108 and EIP-2028.

EIP-1108 includes much-needed gas repricings that open the door to rollup innovation. These repricings reduce the gas costs of verifying zk-SNARKs substantially.

With #ethereum Istanbul now activated, verifying proofs is much cheaper. A Groth16 proof verification costs about 200k gas (and then 8k per input) and PLONK should be similar!

— Kobi Gurkan (@kobigurk) December 8, 2019

To quote directly from the EIP:

Simple summary: The elliptic curve arithmetic precompiles are currently overpriced. Re-pricing the precompiles would greatly assist a number of privacy solutions and scaling solutions on Ethereum. Rationale: Existing protocols would benefit immensely from cheaper elliptic curve cryptography

EIP-2028 lowers the gas cost of calldata from 68 gas per byte to a lower cost (we estimate 16 gas per byte). And since our data availability solution is to place data on the main chain, via calldata, this allows us to increase transaction throughput.

Now that we have an insight into how the two EIPs benefit zkRollup scaling solutions, let’s crunch the numbers!

- The block gas limit currently accepted by miners is 10,000,000 gas.
- 21,000 gas is charged per Ethereum transaction as a base fee (for a simple transfer).
- One block is added to the chain approximately every 15 seconds.

Given these figures, we can work out Ethereum’s max throughput:

- The maximum number of transactions per block is 10M / 21k = 476.
- Which gives us a throughput of 476 transactions / 15 seconds = 32 transactions per second.

Each zkRollup block (what we call a batch) contains 2048 (vanilla Eth) transactions and a zk-proof. So we have to calculate gas costs for two types of data — transactions and proofs:

- Each transaction is 8.125 bytes. At a cost of 68 gas/byte that ‘s 552.5 gas per transaction. Since there are 2048 transactions per batch, the cost (per batch) is 552.5 * 2048 = 1,131,520 gas for transactions.
- The cost of a proof is 800,000 gas. One proof per batch means a cost per batch of 800,000 gas for proofs.
- So each rollup batch costs 1,131,520 + 800,000 = 1,931,520 gas.

How many zkRollup batches can we insert into an Ethereum block given the limitation of 10M gas per block ?

- 10M / 1,931,520 = 5.17 batches. For the sake of simplicity, let’s go with approximately 5 batches per block.
- If 5 batches are inserted into an Ethereum block, and each batch holds 2048 transactions, this means we can fit 5 * 2048 = 10,240 transactions per block.
- 10,240 transactions / 15 seconds = 682 transactions per second.

As before, each batch (remember a batch is just a zkRollup block) contains 2048 (vanilla Eth) transactions and a zk-proof. However, thanks to EIPs 1108 and 2028, the gas costs of both the transactions and the proof have now changed:

- Each transaction is 8.125 bytes. At a cost of 16 gas/byte that’s 130 gas per transaction. Since there are 2048 transactions per batch, the cost (per batch) is 130 * 2048 = 266,240 gas for transactions.
- The cost of generating a proof is now 350,000 gas. One proof per batch means a cost per batch of 350,000 gas for proofs.
- So each rollup batch costs 266,240 + 350,000 = 616,240 gas.

How many zkRollup batches can we insert into an Ethereum block given the limitation of 10M gas per block ?

- 10M / 616,240 = 16.22 batches. For the sake of simplicity, let’s round this to the nearest 5 and say approximately 15 batches per block.
- If 15 batches are inserted into an Ethereum block, and each batch holds 2048 transactions, this means we can fit 15 * 2048 = 30,720 transactions per block.
- 30,720 transactions / 15 seconds = 2048 transactions per second.

Since increases in throughput under zkRollup are directly related to decreases in transaction costs, another way of thinking about the above is the following:

- Right now it costs around 21,000 gas to send a vanilla Ethereum transaction.
- Ethereum with ZkRollup (before Istanbul) would have brought this cost down to just under 1000 — approximately 945 gas.
- Post Istanbul, the cost is now 300 gas.

Here’s a neat little summary table relating transaction cost to throughput under all three scenarios:

Note that to calculate the Ethereum with ZkRollup transaction costs, we divide the gas cost per proof —800,000 before, and 350,000 after Istanbul — by the number of transactions in a batch (2048) — since there’s one proof per batch this equates to amortising the cost of a proof over all the transactions in a batch. We then add this figure to the data storage gas cost per transaction — 552.5 before and 130 after Istanbul — in other words, to the cost of storing the transaction data in calldata.

As stated at the beginning of this essay, 2000 tps is what the Visa network currently averages. So although we haven’t quite lived up to Eric’s claim of 3000 tps, a max throughput of 2048 tps is still a pretty big deal. And with slightly different assumptions to the one’s we’ve made, 3000 tps doesn’t seem implausible.

Before we get too carried away, it’s important to remember that this is a theoretical maximum. In practice, things aren’t so simple.

Practically speaking, to fit 15 batches into 1 block, requires an average batch creation time of 1 per second (assuming 15 second block times).

Remember, each zkRollup batch requires a short cryptographic proof (zk-SNARK) that proves the integrity of the transactions in that batch. It turns out that generating this proof is computationally very expensive. In fact, it’s the major bottleneck to achieving our theoretical throughput limit.

To give you an idea, at the moment, using one CPU and three GPUs, it takes us several minutes to generate such a proof.

And while there are obvious performance improvements to be had through parallelization, bringing the proof generation time down from several minutes to several seconds, while keeping costs reasonable, remains an important challenge.

(Note that once a rollup transaction aggregator (what we call an operator) has “mined” a batch, he or she must verify the proof on-chain. This verification acts as a sort of “database update” for the other operators. In practice this means batch n+1 can only be “mined” after the proof for batch n has been generated and verified.)

While proof generation is the major bottleneck here, it’s not the only remaining challenge. Setting up servers that are able to process 2000 transactions per second is not a trivial issue. Neither is verifying all the signatures involved. We’ll also need a pretty advanced block explorer just to handle all this information…

Of course, we’re still working on all these parts. And we’re not going to stop until we’ve solved them.

After all, if we didn’t believe it were possible, we wouldn’t be in this space :)