> ## Documentation Index
> Fetch the complete documentation index at: https://cosmos-docs-sync-security-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# TMCore QA 34

# Tendermint Core QA Results v0.34.x

## 200 Node Testnet

### Finding the Saturation Point

The first goal when examining the results of the tests is identifying the saturation point.
The saturation point is a setup with a transaction load large enough to prevent the testnet
from being stable: the load runner tries to produce slightly more transactions than can
be processed by the testnet.

The following table summarizes the results for v0.34.x for the different experiments
(extracted from file [`v034_report_tabbed.txt`](https://raw.githubusercontent.com/cometbft/cometbft/v0.38.x/docs/qa/img34/v034_report_tabbed.txt)).

The X axis of this table is `c`, the number of connections created by the load runner process to the target node.
The Y axis of this table is `r`, the rate or number of transactions issued per second.

|       |   c=1 |   c=2 |   c=4 |
| :---- | ----: | ----: | ----: |
| r=25  |  2225 |  4450 |  8900 |
| r=50  |  4450 |  8900 | 17800 |
| r=100 |  8900 | 17800 | 35600 |
| r=200 | 17800 | 35600 | 38660 |

The table shows the number of 1024-byte-long transactions that were produced by the load runner
and processed by Tendermint Core during the 90 seconds of the experiment's duration.
Each cell in the table refers to an experiment with a particular number of websocket connections (`c`)
to a chosen validator and the number of transactions per second that the load runner
tries to produce (`r`). Note that the overall load the tool attempts to generate is $c \cdot r$.

We can see that the saturation point is beyond the diagonal that spans cells

* `r=200,c=2`
* `r=100,c=4`

given that the total number of transactions should be close to the product rate × the number of connections × experiment time.

All experiments below the saturation diagonal (`r=200,c=4`) have in common that the total
number of transactions processed is noticeably less than the product $c \cdot r \cdot 89$ (89 seconds, since the last batch never gets sent),
which is the expected number of transactions when the system is able to handle the load well.
With (`r=200,c=4`), we obtained 38660, whereas the theoretical number of transactions should
have been $200 \cdot 4 \cdot 89 = 71200$.

At this point, we chose an experiment at the limit of the saturation diagonal
in order to further study the performance of this release.
**The chosen experiment is (`r=200,c=2`)**.

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`),
where we can see that the load stays close to 0 most of the time.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_load-runner.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=fed72e6880b9614ac30a92ccaae087d7" alt="load-load-runner" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_load-runner.png" />

### Examining Latencies

The method described [here](/cometbft/latest/docs/qa/Method) allows us to plot the latencies of transactions
for all experiments.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_200node_latencies.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=d383b6f2dcce6932b4f8b8e1ee2c2d59" alt="all-latencies" width="658" height="462" data-path="cometbft/latest/docs/qa/img34/v034_200node_latencies.png" />

As we can see, even the experiments beyond the saturation diagonal managed to keep
transaction latency stable (i.e., not constantly increasing).
Our interpretation is that contention within Tendermint Core was propagated
via the websockets to the load runner;
hence, the load runner could not produce the target load but a fraction of it.

Further examination of the Prometheus data (see below) showed that the mempool contained many transactions
at steady state but did not grow much without quickly returning to this steady state. This demonstrates
that the Tendermint Core network was able to process transactions at least as quickly as they
were submitted to the mempool. Finally, the test script ensured that at the end of an experiment, the
mempool was empty so that all transactions submitted to the chain were processed.

Finally, the number of points present in the plot appears to be much less than expected given the
number of transactions in each experiment, particularly close to or above the saturation diagonal.
This is a visual effect of the plot; what appear to be points in the plot are actually potentially huge
clusters of points. To corroborate this, we have zoomed in the plot above by setting (carefully chosen)
tiny axis intervals. The cluster shown below looks like a single point in the plot above.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_200node_latencies_zoomed.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=3d9a4157e3a09a60c13be968f8e0fce5" alt="all-latencies-zoomed" width="658" height="462" data-path="cometbft/latest/docs/qa/img34/v034_200node_latencies_zoomed.png" />

The plot of latencies can be used as a baseline to compare with other releases.

The following plot summarizes average latencies versus overall throughput
across different numbers of WebSocket connections to the node into which
transactions are being loaded.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_latency_throughput.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=ba58de5c6a6cfa253516efe9ef840bb2" alt="latency-vs-throughput" width="640" height="480" data-path="cometbft/latest/docs/qa/img34/v034_latency_throughput.png" />

### Prometheus Metrics on the Chosen Experiment

As mentioned [above](#finding-the-saturation-point), the chosen experiment is `r=200,c=2`.
This section further examines key metrics for this experiment extracted from Prometheus data.

#### Mempool Size

The mempool size, a count of the number of transactions in the mempool, was shown to be stable and homogeneous
at all full nodes. It did not exhibit any unconstrained growth.
The plot below shows the evolution over time of the cumulative number of transactions inside all full nodes' mempools
at a given time.
The two spikes that can be observed correspond to a period where consensus instances proceeded beyond the initial round
at some nodes.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_mempool_size.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=e817046c6293ecb034e2f8f93b28a58f" alt="mempool-cumulative" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_mempool_size.png" />

The plot below shows the evolution of the average over all full nodes, which oscillates between 1500 and 2000
outstanding transactions.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_mempool_size_avg.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=01d865f42e97083fff28f3d59364700a" alt="mempool-avg" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_mempool_size_avg.png" />

The peaks observed coincide with the moments when some nodes proceeded beyond the initial round of consensus (see below).

#### Peers

The number of peers was stable at all nodes.
It was higher for the seed nodes (around 140) than for the rest (between 21 and 74).
The fact that non-seed nodes reach more than 50 peers is due to #9548.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_peers.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=cef51aab2bfe76c05c8382363dd87371" alt="peers" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_peers.png" />

#### Consensus Rounds per Height

Most nodes used only round 0 for most heights, but some nodes needed to advance to round 1 for some heights.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_rounds.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=f22a9006537b891e92e16263c3747fb7" alt="rounds" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_rounds.png" />

#### Blocks Produced per Minute, Transactions Processed per Minute

The blocks produced per minute are the slope of this plot.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_heights.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=bcc75df614e99c56e81b5958cf3e2d16" alt="heights" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_heights.png" />

Over a period of 2 minutes, the height goes from 530 to 569.
This results in an average of 19.5 blocks produced per minute.

The transactions processed per minute are the slope of this plot.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_total-txs.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=91ea5b509bb2ac0a08d75c52cff52e44" alt="total-txs" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_total-txs.png" />

Over a period of 2 minutes, the total goes from 64525 to 100125 transactions,
resulting in 17800 transactions per minute. However, we can see in the plot that
all transactions in the load are processed long before the two minutes.
If we adjust the time window for when transactions are processed (approx. 105 seconds),
we obtain 20343 transactions per minute.

#### Memory Resident Set Size

Resident Set Size of all monitored processes is plotted below.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_rss.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=9a45ae9b6495f059fdb78c2ee72d6a88" alt="rss" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_rss.png" />

The average over all processes oscillates around 1.2 GiB and does not demonstrate unconstrained growth.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_rss_avg.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=1fe277170d5f00df1fb5a8ee2043a40d" alt="rss-avg" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_rss_avg.png" />

#### CPU Utilization

The best metric from Prometheus to gauge CPU utilization on a Unix machine is `load1`,
as it usually appears in the
[output of `top`](https://www.digitalocean.com/community/tutorials/load-average-in-linux).

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_r200c2_load1.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=83baea43c831678bd1327bee9984a35b" alt="load1" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_r200c2_load1.png" />

It is contained in most cases below 5, which is generally considered acceptable load.

### Test Result

**Result: N/A** (v0.34.x is the baseline)

Date: 2022-10-14

Version: 3ec6e424d6ae4c96867c2dcf8310572156068bb6

## Rotating Node Testnet

For this testnet, we will use a load that can safely be considered below the saturation
point for the size of this testnet (between 13 and 38 full nodes): `c=4,r=800`.

N.B.: The version of CometBFT used for these tests is affected by #9539.
However, the reduced load that reaches the mempools is orthogonal to the functionality
we are focusing on here.

### Latencies

The plot of all latencies can be seen in the following plot.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_latencies.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=c226bc021649d70e36c3d4c0513073ac" alt="rotating-all-latencies" width="658" height="462" data-path="cometbft/latest/docs/qa/img34/v034_rotating_latencies.png" />

We can observe there are some very high latencies toward the end of the test.
Upon suspicion that they are duplicate transactions, we examined the latencies
raw file and discovered there are more than 100K duplicate transactions.

The following plot shows the latencies file where all duplicate transactions have
been removed, i.e., only the first occurrence of a duplicate transaction is kept.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_latencies_uniq.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=60d7189aec99864554bfea72bea4ff07" alt="rotating-all-latencies-uniq" width="658" height="462" data-path="cometbft/latest/docs/qa/img34/v034_rotating_latencies_uniq.png" />

This problem, existing in `v0.34.x`, will need to be addressed, perhaps in the same way
we addressed it when running the 200 node test with high loads: increasing the `cache_size`
configuration parameter.

### Prometheus Metrics

The set of metrics shown here are fewer than for the 200 node experiment.
We are only interested in those for which the catch-up process (blocksync) may have an impact.

#### Blocks and Transactions per Minute

Just as shown for the 200 node test, the blocks produced per minute are the gradient of this plot.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_heights.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=511dacb31496eed724f4eb6f6352b0ee" alt="rotating-heights" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_rotating_heights.png" />

Over a period of 5229 seconds, the height goes from 2 to 3638.
This results in an average of 41 blocks produced per minute.

The following plot shows only the heights reported by ephemeral nodes
(which are also included in the plot above). Note that the *height* metric
is only shown *once the node has switched to consensus*, hence the gaps
when nodes are killed, wiped out, started from scratch, and catching up.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_heights_ephe.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=7b28802196854af36bc142ef68d4428f" alt="rotating-heights-ephe" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_rotating_heights_ephe.png" />

The transactions processed per minute are the gradient of this plot.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_total-txs.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=2bbb29a92196dfe11675ba13e2a68e67" alt="rotating-total-txs" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_rotating_total-txs.png" />

The small lines we see periodically close to `y=0` are the transactions that
ephemeral nodes start processing when they are caught up.

Over a period of 5229 seconds, the total goes from 0 to 387697 transactions,
resulting in 4449 transactions per minute. We can see some abrupt changes in
the plot's gradient. This will need to be investigated.

#### Peers

The plot below shows the evolution in peers throughout the experiment.
The periodic changes observed are due to the ephemeral nodes being stopped,
wiped out, and recreated.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_peers.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=2310a5f9b9749cba2f570b6e61c5e792" alt="rotating-peers" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_rotating_peers.png" />

The validators' plots are concentrated at the higher part of the graph, whereas the ephemeral nodes
are mostly at the lower part.

#### Memory Resident Set Size

The average Resident Set Size (RSS) over all processes seems stable and slightly growing toward the end.
This might be related to the increase in transaction load observed above.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_rss_avg.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=804b8fcc38808f2b8d5c14d180aadd11" alt="rotating-rss-avg" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_rotating_rss_avg.png" />

The memory taken by the validators and the ephemeral nodes (when they are up) is comparable.

#### CPU Utilization

The plot shows metric `load1` for all nodes.

<img src="https://mintcdn.com/cosmos-docs-sync-security-docs/MgEE5qFncd6niaeC/cometbft/latest/docs/qa/img34/v034_rotating_load1.png?fit=max&auto=format&n=MgEE5qFncd6niaeC&q=85&s=e4e4093c0eb1736ce15c32dcc0167311" alt="rotating-load1" width="2890" height="1000" data-path="cometbft/latest/docs/qa/img34/v034_rotating_load1.png" />

It is contained under 5 most of the time, which is considered normal load.
The purple line, which follows a different pattern, is the validator receiving all
transactions via RPC from the load runner process.

### Test Result

**Result: N/A**

Date: 2022-10-10

Version: a28c987f5a604ff66b515dd415270063e6fb069d
