Quotas and Rate Limits
Aptos Build uses a system of organization-level quotas and per-project rate limits to manage the usage of our APIs.
- Quota: The projects the organization is allowed at a top level (e.g. number of processors, amount of CUs / streams, etc).
- Limit: The limit that applies to a single project. The sum of the limits must fit within the quotas.
This system allows you allocate your quota to each project as needed, e.g. 90% of your CU quota to the mainnet version of your project and 10% to the testnet version, 6 streams to the mainnet project, 2 to the testnet project. You can adjust your quota allocation on the quotas page.
Limits apply on a per-project basis (not on a per-key basis or a per-organization basis). If one project hits any of its limits, some requests will be rejected with HTTP 429 errors. Other projects will not be affected, usage doesn’t “overflow” to another project’s quota.
Quota Types
Summary
- Subtracted on a per-request basis.
- Tracked over a sliding 5-minute window.
Requests to Aptos Build APIs are measured in terms of Compute Units (CUs). CUs measure the relative cost of a request on our infrastructure. For example, a given call to /v1/accounts/0x1
(the Node API) might cost 250 CUs while a call to /v1/graphql
(the Indexer API) might cost 500 CUs, indicating that the nfra cost of the second request is 2x higher than the first. Compared to just rate limiting based on request count, Compute Units allow us to capture that some requests are more resource intensive than others.
Compute Unit Calculation
The method for calculating the CUs used by a request differs per upstream type (e.g. Node API vs. Indexer API) and endpoint (e.g. /v1/view
vs. /v1/accounts
), but as a general rule of thumb, the more complex a request is (gas used, time taken, etc.), the more CUs it will consume. We use a variety of factors to calculate the cost of a request, and our approach is subject to change at any time. Broadly speaking, the behaviour is as described below.
Node API
The current approach for this upstream is quite simple.
upstream_processing_time * multiplier * exponential_factor
In other words, cost is just a function of how long the upstream takes to process the request. In general, node API requests are dominated by I/O time on the database. The more complex a query is, the longer it takes, the higher the cost in CUs.
Expensive, long running queries have an outsized impact on our infrastructure, so we scale the cost exponentially.
Node API (VM Endpoints)
Requests to endpoints that involve execution with the Move VM (e.g. /v1/transactions/simulate
or /v1/transactions/view
) return the cost of that execution in terms of gas. We use this gas cost and some multiplier to get the final gas cost:
gas_cost * multiplier
Indexer API (Other Endpoints)
We use the same formula as with the Node API, albeit with different multipliers.