Improving EOS MAX Transactions Per Second Calculation

edited August 2018

The purpose of this post is to share our proposed methodology for the Transaction Per Second calculations on the EOS blockchain and invite scrutiny and criticism. Part of our motivation is to show accurate and reliable information on our EOS Network Monitor.

Assumptions

1) Blocktimes are always multiples of 500 ms, and never zero. So you can have blocktimes of 500 ms, 1000 ms, 1500 ms, 2000 ms, etc. And you'll never have block times of 0 ms, 300 ms, 750 ms, 1050 ms, etc.

2) Transactions are evenly spaced in the interval of time it takes to add a block. In other words, the rate of transactions inside of a blocktime are constant. So if a block with 6000 transactions gets added to the blockchain in 6 seconds, TPS = 1000 for the entire six seconds between the addition of the previous block on this one.

3) We want to report actual maximum Transactions Per Second, as opposed to the rate maximums. So if we add 9000 transactions to the blockchain in .5 seconds, it achieves a rate of 18000 TPS, but the actual maximum would be 9000 plus the number of transaction added before and/or after this half second, such that the total time considered is one second.

4) Block timestamps are accurate. In reality, there is latency between different block producers. We propose to treat this as a separate problem for later. Latency is not on the blockchain, but in the log files of different BPs.

Some terms

Let's label blocks using letters: A, B, C, etc.

Let's call the number of transactions in each block: NA, NB, NC, etc.

Let's define the block time of block B as the timestamp of block B minus the timestamp of block A expressed in seconds. And let's use TA, TB, TC, etc to refer to timestamps.

Let's define the TPS Run Rate of a block as the number of transactions divided by timestamp. So the TPS Run Rate of block B would be NB/TB. Let's label the TPS Rates for each block as RA, RB, RC.

Example:

So if NB = 10, and TB = .5, then RB is 20. In the half second it took to add block B, 10 transactions were added to the EOS blockchain. For this half second, transactions were being added at a rate of 20 per second. RB = 20.

Calculating TPS under normal conditions (all block times are 500 ms)

Under normal conditions when all block times are 500 Max TPS candidates can be calculated by simply summing every adjacent pair of blocks and comparing it to the existing Max TPS.

NA + NB
NB + NC
etc.

There is never a need to consider the second that straddles three blocks, say, from B's timestamp minus 250ms to C's timestamp plus 250ms.

What causes non-standard block times?

We did a quick analysis of non-standard blocktimes for 100,000 blocks starting from block # 11M.

This spreadsheet shows the results. Every time we saw a non-standard block time, we also noted some information about the block which came before it.

There were 1,319 blocks out of 100,000 with non-standard block times, or 1.3%.

Of these, 72% had blocktimes of 1000ms.

95 blocks, or 7.2% of those with non-standard block times had a blocktime >= 3000 ms.

The worst blocktimes were 12500 ms (1 instance), 9000ms (1), 8500 (2), 7500 (1), 7000 (1), and 6500 (20).

The clearest cause of non-standard block times seems be the transition from one BP to another. Only 108 blocks, or 8.2% of those with non-standard times were produced by the same BP who had produced the previous block.

Of the 95 blocks with blocktimes >= 3000 ms, only one was produced by the same BP who'd produced the previous blocks.

There was almost no correlation between the size of a non-standard blocktime and the number of the transactions in the block. There was also almost no correlation between the size of a non-standard blocktime and the number of transactions in the previous block. We should probably do a more comprehensive study at look at ALL blocks and see if there's a correlation between transaction count and ANY non-standard block time.

Calculating MAX TPS in EOS

Here is the point of the article. Please criticize this methodology:

check 1

We look backwards from every block and decide whether and how much to add transactions from the previous block, and also whether to trim transactions from blocks which took a long time to make:

• If TB = .5, consider the following as a MAX TPS candidate

RB(TB)+RA(1-TB)

or since TB = .5, we can use

(RB + RA)/2

• If TB >= 1, consider the following as a Max TPS candidate

RB/TB

edge case

This is almost sufficient, but it would neglect to consider the TPS for the following edge case:
TA = .5, NA = 1
TB = .5, NB = 1000
TC = 1, NC = 4

(a near-empty block, followed by a fast block with a lot of transactions, followed by a slow block with a medium number of transactions)

Using only the above logic, we would conclude that the Max TPS across the 2 seconds it took to produce these three blocks is 1001 (RA + RB)/2.

check 2

In some situations, as in the edge case, we have to look forward from each block and average in part of the transactions from the next block.

• If we encounter a TC >= 1 AND TB < 1 then we consider the following as a Max TPS candidate

RB(TB) + RC(1 - TB)

or since TB = .5, we can use

(RB + RC)/2

With check 2, the edge case listed above results in the Max TPS being (RB + RC)/2 or 1002.

Conclusion

We think this is a solid approach to the MAX TPS calculation. Comments and criticism are very welcome.

• Rate vs Actual That's what we were showing originally actually — the Max RATE. So if a half-second block had 9000 tx. The rate would be 18000. But then we thought it'd be better to list the actual TPS.

Not rates which have been achieved for a half second, but actually how many txs were added to the block in any given second of time.

• Assumption #2 and dealing with non-standard block times    • Correction:

If TB >= 1, consider the following as a Max TPS candidate
RB/TB

It should be just RB. Not RB/TB.

In simple terms: If the block lasts longer than a second, consider that block's rate all by itself as a maximum.