github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/docs/qa/TMCore-QA-34.md (about) 1 --- 2 order: 1 3 parent: 4 title: Tendermint Core QA Results v0.34.x 5 description: This is a report on the results obtained when running v0.34.x on testnets 6 order: 2 7 --- 8 9 # Tendermint Core QA Results v0.34.x 10 11 ## 200 Node Testnet 12 13 ### Finding the Saturation Point 14 15 The first goal when examining the results of the tests is identifying the saturation point. 16 The saturation point is a setup with a transaction load big enough to prevent the testnet 17 from being stable: the load runner tries to produce slightly more transactions than can 18 be processed by the testnet. 19 20 The following table summarizes the results for v0.34.x, for the different experiments 21 (extracted from file [`v034_report_tabbed.txt`](img34/v034_report_tabbed.txt)). 22 23 The X axis of this table is `c`, the number of connections created by the load runner process to the target node. 24 The Y axis of this table is `r`, the rate or number of transactions issued per second. 25 26 | | c=1 | c=2 | c=4 | 27 | :--- | ----: | ----: | ----: | 28 | r=25 | 2225 | 4450 | 8900 | 29 | r=50 | 4450 | 8900 | 17800 | 30 | r=100 | 8900 | 17800 | 35600 | 31 | r=200 | 17800 | 35600 | 38660 | 32 33 The table shows the number of 1024-byte-long transactions that were produced by the load runner, 34 and processed by Tendermint Core, during the 90 seconds of the experiment's duration. 35 Each cell in the table refers to an experiment with a particular number of websocket connections (`c`) 36 to a chosen validator, and the number of transactions per second that the load runner 37 tries to produce (`r`). Note that the overall load that the tool attempts to generate is $c \cdot r$. 38 39 We can see that the saturation point is beyond the diagonal that spans cells 40 41 * `r=200,c=2` 42 * `r=100,c=4` 43 44 given that the total number of transactions should be close to the product rate X the number of connections x experiment time. 45 46 All experiments below the saturation diagonal (`r=200,c=4`) have in common that the total 47 number of transactions processed is noticeably less than the product $c \cdot r \cdot 89$ (89 seconds, since the last batch never gets sent), 48 which is the expected number of transactions when the system is able to deal well with the 49 load. 50 With (`r=200,c=4`), we obtained 38660 whereas the theoretical number of transactions should 51 have been $200 \cdot 4 \cdot 89 = 71200$. 52 53 At this point, we chose an experiment at the limit of the saturation diagonal, 54 in order to further study the performance of this release. 55 **The chosen experiment is (`r=200,c=2`)**. 56 57 This is a plot of the CPU load (average over 1 minute, as output by `top`) of the load runner for (`r=200,c=2`), 58 where we can see that the load stays close to 0 most of the time. 59 60 ![load-load-runner](img34/v034_r200c2_load-runner.png) 61 62 ### Examining latencies 63 64 The method described [here](method.md) allows us to plot the latencies of transactions 65 for all experiments. 66 67 ![all-latencies](img34/v034_200node_latencies.png) 68 69 As we can see, even the experiments beyond the saturation diagonal managed to keep 70 transaction latency stable (i.e. not constantly increasing). 71 Our interpretation for this is that contention within Tendermint Core was propagated, 72 via the websockets, to the load runner, 73 hence the load runner could not produce the target load, but a fraction of it. 74 75 Further examination of the Prometheus data (see below), showed that the mempool contained many transactions 76 at steady state, but did not grow much without quickly returning to this steady state. This demonstrates 77 that Tendermint Core network was able to process transactions at least as quickly as they 78 were submitted to the mempool. Finally, the test script made sure that, at the end of an experiment, the 79 mempool was empty so that all transactions submitted to the chain were processed. 80 81 Finally, the number of points present in the plot appears to be much less than expected given the 82 number of transactions in each experiment, particularly close to or above the saturation diagonal. 83 This is a visual effect of the plot; what appear to be points in the plot are actually potentially huge 84 clusters of points. To corroborate this, we have zoomed in the plot above by setting (carefully chosen) 85 tiny axis intervals. The cluster shown below looks like a single point in the plot above. 86 87 ![all-latencies-zoomed](img34/v034_200node_latencies_zoomed.png) 88 89 The plot of latencies can we used as a baseline to compare with other releases. 90 91 The following plot summarizes average latencies versus overall throughput 92 across different numbers of WebSocket connections to the node into which 93 transactions are being loaded. 94 95 ![latency-vs-throughput](img34/v034_latency_throughput.png) 96 97 ### Prometheus Metrics on the Chosen Experiment 98 99 As mentioned [above](#finding-the-saturation-point), the chosen experiment is `r=200,c=2`. 100 This section further examines key metrics for this experiment extracted from Prometheus data. 101 102 #### Mempool Size 103 104 The mempool size, a count of the number of transactions in the mempool, was shown to be stable and homogeneous 105 at all full nodes. It did not exhibit any unconstrained growth. 106 The plot below shows the evolution over time of the cumulative number of transactions inside all full nodes' mempools 107 at a given time. 108 The two spikes that can be observed correspond to a period where consensus instances proceeded beyond the initial round 109 at some nodes. 110 111 ![mempool-cumulative](img34/v034_r200c2_mempool_size.png) 112 113 The plot below shows evolution of the average over all full nodes, which oscillates between 1500 and 2000 114 outstanding transactions. 115 116 ![mempool-avg](img34/v034_r200c2_mempool_size_avg.png) 117 118 The peaks observed coincide with the moments when some nodes proceeded beyond the initial round of consensus (see below). 119 120 #### Peers 121 122 The number of peers was stable at all nodes. 123 It was higher for the seed nodes (around 140) than for the rest (between 21 and 74). 124 The fact that non-seed nodes reach more than 50 peers is due to #9548. 125 126 ![peers](img34/v034_r200c2_peers.png) 127 128 #### Consensus Rounds per Height 129 130 Most nodes used only round 0 for most heights, but some nodes needed to advance to round 1 for some heights. 131 132 ![rounds](img34/v034_r200c2_rounds.png) 133 134 #### Blocks Produced per Minute, Transactions Processed per Minute 135 136 The blocks produced per minute are the slope of this plot. 137 138 ![heights](img34/v034_r200c2_heights.png) 139 140 Over a period of 2 minutes, the height goes from 530 to 569. 141 This results in an average of 19.5 blocks produced per minute. 142 143 The transactions processed per minute are the slope of this plot. 144 145 ![total-txs](img34/v034_r200c2_total-txs.png) 146 147 Over a period of 2 minutes, the total goes from 64525 to 100125 transactions, 148 resulting in 17800 transactions per minute. However, we can see in the plot that 149 all transactions in the load are processed long before the two minutes. 150 If we adjust the time window when transactions are processed (approx. 105 seconds), 151 we obtain 20343 transactions per minute. 152 153 #### Memory Resident Set Size 154 155 Resident Set Size of all monitored processes is plotted below. 156 157 ![rss](img34/v034_r200c2_rss.png) 158 159 The average over all processes oscillates around 1.2 GiB and does not demonstrate unconstrained growth. 160 161 ![rss-avg](img34/v034_r200c2_rss_avg.png) 162 163 #### CPU utilization 164 165 The best metric from Prometheus to gauge CPU utilization in a Unix machine is `load1`, 166 as it usually appears in the 167 [output of `top`](https://www.digitalocean.com/community/tutorials/load-average-in-linux). 168 169 ![load1](img34/v034_r200c2_load1.png) 170 171 It is contained in most cases below 5, which is generally considered acceptable load. 172 173 ### Test Result 174 175 **Result: N/A** (v0.34.x is the baseline) 176 177 Date: 2022-10-14 178 179 Version: 3ec6e424d6ae4c96867c2dcf8310572156068bb6 180 181 ## Rotating Node Testnet 182 183 For this testnet, we will use a load that can safely be considered below the saturation 184 point for the size of this testnet (between 13 and 38 full nodes): `c=4,r=800`. 185 186 N.B.: The version of CometBFT used for these tests is affected by #9539. 187 However, the reduced load that reaches the mempools is orthogonal to functionality 188 we are focusing on here. 189 190 ### Latencies 191 192 The plot of all latencies can be seen in the following plot. 193 194 ![rotating-all-latencies](img34/v034_rotating_latencies.png) 195 196 We can observe there are some very high latencies, towards the end of the test. 197 Upon suspicion that they are duplicate transactions, we examined the latencies 198 raw file and discovered there are more than 100K duplicate transactions. 199 200 The following plot shows the latencies file where all duplicate transactions have 201 been removed, i.e., only the first occurrence of a duplicate transaction is kept. 202 203 ![rotating-all-latencies-uniq](img34/v034_rotating_latencies_uniq.png) 204 205 This problem, existing in `v0.34.x`, will need to be addressed, perhaps in the same way 206 we addressed it when running the 200 node test with high loads: increasing the `cache_size` 207 configuration parameter. 208 209 ### Prometheus Metrics 210 211 The set of metrics shown here are less than for the 200 node experiment. 212 We are only interested in those for which the catch-up process (blocksync) may have an impact. 213 214 #### Blocks and Transactions per minute 215 216 Just as shown for the 200 node test, the blocks produced per minute are the gradient of this plot. 217 218 ![rotating-heights](img34/v034_rotating_heights.png) 219 220 Over a period of 5229 seconds, the height goes from 2 to 3638. 221 This results in an average of 41 blocks produced per minute. 222 223 The following plot shows only the heights reported by ephemeral nodes 224 (which are also included in the plot above). Note that the _height_ metric 225 is only showed _once the node has switched to consensus_, hence the gaps 226 when nodes are killed, wiped out, started from scratch, and catching up. 227 228 ![rotating-heights-ephe](img34/v034_rotating_heights_ephe.png) 229 230 The transactions processed per minute are the gradient of this plot. 231 232 ![rotating-total-txs](img34/v034_rotating_total-txs.png) 233 234 The small lines we see periodically close to `y=0` are the transactions that 235 ephemeral nodes start processing when they are caught up. 236 237 Over a period of 5229 minutes, the total goes from 0 to 387697 transactions, 238 resulting in 4449 transactions per minute. We can see some abrupt changes in 239 the plot's gradient. This will need to be investigated. 240 241 #### Peers 242 243 The plot below shows the evolution in peers throughout the experiment. 244 The periodic changes observed are due to the ephemeral nodes being stopped, 245 wiped out, and recreated. 246 247 ![rotating-peers](img34/v034_rotating_peers.png) 248 249 The validators' plots are concentrated at the higher part of the graph, whereas the ephemeral nodes 250 are mostly at the lower part. 251 252 #### Memory Resident Set Size 253 254 The average Resident Set Size (RSS) over all processes seems stable, and slightly growing toward the end. 255 This might be related to the increased in transaction load observed above. 256 257 ![rotating-rss-avg](img34/v034_rotating_rss_avg.png) 258 259 The memory taken by the validators and the ephemeral nodes (when they are up) is comparable. 260 261 #### CPU utilization 262 263 The plot shows metric `load1` for all nodes. 264 265 ![rotating-load1](img34/v034_rotating_load1.png) 266 267 It is contained under 5 most of the time, which is considered normal load. 268 The purple line, which follows a different pattern is the validator receiving all 269 transactions, via RPC, from the load runner process. 270 271 ### Test Result 272 273 **Result: N/A** 274 275 Date: 2022-10-10 276 277 Version: a28c987f5a604ff66b515dd415270063e6fb069d