diff --git a/docs/content/guides/developer/advanced/congestion-control.mdx b/docs/content/guides/developer/advanced/congestion-control.mdx index a41be1d142876..3ac947d565af9 100644 --- a/docs/content/guides/developer/advanced/congestion-control.mdx +++ b/docs/content/guides/developer/advanced/congestion-control.mdx @@ -3,11 +3,11 @@ title: Congestion Control description: Congestion control is the system that limits the rate of transactions writing to a single shared object, preventing the network from becoming overloaded with checkpoints that take too long to execute. --- -The Sui network’s object-based architecture allows us to process many different user transactions massively in parallel, in a way that’s not possible on most other networks. However, if multiple transactions are all writing to the same shared object, they must execute in sequential order. There is a limit to how many transactions we can process that touch one specific object. +Congestion control is the system that limits the rate of transactions writing to a single shared object, preventing the network from becoming overloaded with checkpoints that take too long to execute. -**Congestion control** is the system that limits the rate of transactions writing to a single shared object, preventing the network from becoming overloaded with checkpoints that take too long to execute. +The Sui network’s object-based architecture allows processing many different user transactions massively in parallel, in a way that’s not possible on most other networks. However, if multiple transactions are all writing to the same shared object, they must execute in sequential order. There is a limit to how many transactions the network can process that touch one specific object. -If you see transactions fail with the error `ExecutionCancelledDueToSharedObjectCongestion`, you are observing congestion control at work! Read this document to learn: +If you see transactions fail with the error `ExecutionCancelledDueToSharedObjectCongestion`, you are observing congestion control at work! Continue reading to learn: - How transaction space is allocated on a congested shared object. - How to bid for priority access to limited space. - How to structure your applications and transactions for maximum throughput. @@ -20,9 +20,7 @@ Sui's congestion control algorithm runs every time a new batch of sequenced tran 1. Each transaction's **execution cost is estimated** using the [`TotalGasBudgetWithCap`](https://github.com/MystenLabs/sui/blob/main/crates/sui-core/src/authority/shared_object_congestion_tracker.rs#L143) heuristic. -1. The [`SharedObjectCongestionTracker`](https://github.com/MystenLabs/sui/blob/main/crates/sui-core/src/authority/shared_object_congestion_tracker.rs) keeps a running tally of how much **per-object congestion budget** is used. If *all* shared objects used by the transaction have enough budget left, the transaction is scheduled. Otherwise it is **deferred** until the next commit. - -1. When a transaction is scheduled, it consumes budget for the *mutable* shared objects that it uses. (*Immutable* shared objects don't consume any budget, because multiple immutable uses of a shared object can be executed in parallel.) +1. The [`SharedObjectCongestionTracker`](https://github.com/MystenLabs/sui/blob/main/crates/sui-core/src/authority/shared_object_congestion_tracker.rs) keeps a running tally of how much **per-object congestion budget** is used. If *all* shared objects used by the transaction have enough budget left, the transaction is scheduled. In that case, it consumes budget for the *mutable* shared objects that it uses. (*Immutable* shared objects don't consume any budget, because multiple immutable uses of a shared object can be executed in parallel.) Otherwise it is **deferred** until the next commit. ### Priority ordering of transactions @@ -32,20 +30,18 @@ Transaction priority is determined solely by **gas price**. If you want your tra :::note -We are actively developing an improved algorithm for estimating transaction execution cost, which we hope will significantly increase capacity for most use cases. This document describes how the current algorithm works. +We are actively developing an improved algorithm for estimating transaction execution cost. This document describes how the current algorithm works. ::: -Sui limits the per-commit execution capacity of each shared object. If transactions touching a shared object are smaller, more of them can fit. If they're bigger, not as many will fit. +Sui limits the per-commit execution capacity of each shared object. If transactions touching a shared object have a low estimated cost, more of them can fit. If they have a high estimated cost, not as many will fit. How is the estimated cost of a transaction determined for congestion control purposes? We use a heuristic called [`TotalGasBudgetWithCap`](https://github.com/MystenLabs/sui/blob/main/crates/sui-core/src/authority/shared_object_congestion_tracker.rs#L143). -- A transaction's initial estimated cost is simply its **gas budget**. (Unfortunately, the final gas price of a transaction is not known until after execution, which is too late for us to use in scheduling.) +- A transaction's initial estimated cost is simply its **gas budget**. (Unfortunately, the final gas cost of a transaction is not known until after execution, which is too late for us to use in scheduling.) - For transactions with a very high gas budget, the estimated cost is then lowered to an upper limit that is determined based on the number of `MoveCall`s and the number of Move `Input`s in each call. -This means that **if you want to make your transaction consume less space on a mutable shared object**, you must lower its gas budget, reduce the number of `MoveCall`s and Move `Input`s, or both. - ### Transaction deferral If a transaction is not able to be scheduled because it's trying to use a congested shared object with no space left, it will be **deferred**. This means that validators will hold onto the transaction try again to schedule it with the next commit, each time prioritizing all waiting transactions by gas price. @@ -56,4 +52,14 @@ If a transaction has been deferred for several commits without successfully bein At the protocol level, Sui is configured with a fixed per-commit limit and burst capacity for each shared object. On average, a shared object's activity cannot exceed the per-commit limit. However, the limit may be exceeded temporarily by short bursts of traffic. -There is no way to increase the total execution capacity of a particular shared object. That limit is set by the network to ensure that validators, full nodes, and indexers can all execute checkpoints in a reasonable amount of time. \ No newline at end of file +There is no way to increase the total execution capacity of a particular shared object. That limit is set by the network to ensure that validators, full nodes, and indexers can all execute checkpoints in a reasonable amount of time. + +## Practical takeaways + +- For priority access to a congested shared object, set a higher gas price. + +- Set a gas budget that is close to your actual execution cost. You can use dry runs to estimate this. Be aware that some transactions have variable cost. + +- If your object `O` is congested, optimize the gas usage of the functions that are commonly used to access the object. For example, if all the accesses to your object happen via Move function `f`, halving the gas usage of `f` will effectively double the number of transactions that can touch `O` in a single checkpoint (assuming the gas budget is correspondingly decreased). + +- When designing Move packages, avoid using a single shared object if possible. For example, a DEX application with a single, main shared object and dynamic fields for each currency pair would suffer much more congestion than one with a separate object per currency pair.