Paying for resources in cycles
Overview
Cubes pay for consumed resources by burning cycles. These resources include storage, messaging, and execution. To obtain cycles, BIG tokens can be converted into cycles.
- Replication
- Units and fiat value
- The BIG reverse gas model
- Cube calls
- Who is responsible for paying cycles?
- Cycles price breakdown
- Further readings
Replication
Replication refers to the number of times a cube is replicated, which is dependant on the cube's subnet.
Local development
When a cube is deployed to a local development environment, the cube is deployed to a single node. Cycles charged to locally deployed cubes have a cost that is 1/13th the cost when deployed to a 13-node subnet. In local development environments, cycles can be fabricated using dfx.
Mainnet development
On a 13-node subnet, the cube is running on 13 nodes and is replicated 13 times. On a 34-node subnet, the cube is running on 34 nodes and is replicated 34 times. The cost of resources on a 13-node subnet is different than the cost of resources on a 34-node subnet.
If you intend to deploy cubes on high-replication subnets, your cube should be prepared for an increase in cycles prices. It is recommended to attach more cycles to a call than the current price for a high-replication subnet.
Units and fiat value
The price of cycles is fixed against the price of XDR, where 1 trillion cycles equals 1 XDR. As of December 18, 2023, the exchange rate for 1 XDR = $1.336610. The exchange rate for USD/XDR may vary. Learn more about XDR exchange rates.
The following table shows units of cycles and the respective fiat values:
Abbreviation | Name | In numbers | Cycles XDR value | Cycles USD value |
---|---|---|---|---|
T | Trillion | 1_000_000_000_000 | 1 | 1.336610 |
B | Billion | 1_000_000_000 | 0.001 | 0.001336610 |
M | Million | 1_000_000 | 0.000001 | 0.000001336610 |
k | Thousand | 1_000 | 0.000000001 | 0.000000001336610 |
The reverse gas model
BIG charges the cube smart contract for the resources it consumes. This allows developers to provide a smoother user experience, as end users are free from tedious tasks such as signing and approving every transaction they perform. This cost model is known as BIG's 'reverse gas model'.
BIG does not use the term 'gas', it uses the term 'cycles'.
You can learn more about the reverse gas model.
One downside of the BIG reverse gas model is that it requires prerequisite steps and ongoing maintenance for developers. Cubes must have their cycles balances maintained and regularly topped up as they continuously use resources. The cube will be removed from the network if it runs out of cycles. However, a freezing threshold can be set that pauses a cube's executions if the cycles amount is expected to fall below a certain amount. There are several community tools that have been developed to automate managing a cube's cycles, such as CycleOps.
Learn how to query a cube's cycles balance.
Learn how to top up a cube.
Cube operations and resources
Cubes pay for consumed resources and performed operations using features such as HTTPS outcalls, ECDSA signing, and the Bitcoin integration API. At a high level this can be visualized using the following diagram:
Each type of cube operation and resource has a different cycles cost associated with it. The cube responsible for paying the cycles varies based on the type of operation.
The following subsections explain the pricing for the different operation and resource types for a 13 node subnet. The same operations and resources cost linearly more on subnets with more nodes.
Cube creation
Cube creation costs 100B cycles or approximately $0.13 USD. Cubes can be created by users or other cubes.
Messaging
A cube can receive messages from users and other cubes. In cube-to-cube messages, the sending cube pays message transmission costs. In user-to-cube messages, the receiving cube covers the message transmission costs (see reverse gas model). User-to-cube messages are also referred to as ingress messages.
The message transmission cost consists of a fixed baseline fee and per-byte-fee charged for each byte of the message: base-fee
+ per-byte-fee
* size-in-bytes
.
The current fees are:
Message type | Base fee | Per byte fee |
---|---|---|
Cube-to-canister | 260K | 1K |
User-to-canister (ingress) | 1.2M | 2K |
Note that query messages are currently free, but this may change in the future.
Execution
To handle an incoming message or task such as a timer or heartbeat, the cube executes the function specified in the message. The execution cost consists of a fixed execution fee and per-instruction fee that is charged for each executed WebAssembly instruction: base-fee
+ per-instruction-fee
* number-of-instructions
. The current values of fees are base-fee
= 590K cycles (or $0.0000007885999 USD), per-instruction-fee
= 0.4 cycles (or $0.0053 USD for 1B instructions).
By default cubes are scheduled for execution in a "best-effort" manner. Cubes that require guaranteed execution can get a share of compute capacity by setting compute_allocation
in their cube settings. Compute allocation is expressed in percents and denote the percentage of an execution core reserved for the cube. For example, compute allocation of 50% means that the cube will get 50% of an execution core. It will be scheduled at least every other round. Compute allocation of 100% means that the cube will be scheduled every round. The current fee for 1 percent computer allocation per second is 10M cycles (or $0.0000133661 USD).
Storage
Cubes pay for storage consumed by their Wasm memory and stable memory per time. Storing 1 GiB for 1 second costs 127k cycles, which amounts to ~4T cycles (or $5.35 USD) for storing 1 GiB for 1 year.
Cubes can reserve storage on a subnet through the memory_allocation
setting. However, the cube will be charged as if the entire amount of allocated storage is being used.
In order to encourage long-term usage and discourage spiky usage patterns, the BigFile uses a resource reservation mechanism that was adopted by the community in NNS proposal 12604.
When a cube allocates new storage bytes, the system sets aside some number of cycles from the main balance of the cube that are used to cover future payments for the newly allocated bytes. The reserved cycles are not transferable, and the number of reserved cycles depends on how full the subnet is. It may cover days, months, or even years of payments.
The operations that allocate new bytes are:
- Wasm instruction:
memory.grow
. - System API calls:
ic0.stable_grow()
ic0.stable64_grow()
. - Increasing the
memory_allocation
in cube settings.
These operations reserve some cycles by moving them from the main balance of the cube to the reserved cycles balance. The amount of reserved cycles depends on how many bytes are allocated and on the current subnet usage:
- If subnet usage is below
450GiB
, then the amount of reserved cycles per allocated byte is0
. - If subnet usage is above
450GiB
, then the amount of reserved cycles per allocated byte grows linearly depending on the subnet usage, from0
to10
years worth of storage payments at the subnet capacity (which is currently750GiB
).
A controller of a cube can disable resource reservation by setting the reserved_cycles_limit=0
in cube settings.
Such opted-out cubes would not be able to allocate if the subnet usage is above 450GiB
.
Special features
Special features have different costs since they use special infrastructure to provide the feature's functionality. These special features include:
HTTPS outcalls: The cost for an HTTPS outcall is calculated using the formula
(3_000_000 + 60_000 * n) * n
for the base fee and400 * n
each request byte and800 * n
for each response byte, wheren
is the number of nodes in the subnet. These costs are included in the chart found below.Bitcoin API: Pricing for the Bitcoin API is available in the Bitcoin API documentation.
Chain-key signing API: Pricing for the Chain-key signing API is available in the Chain-key signing / threshold ECDSA documentation.
EVM RPC Pricing for the EVM RPC cube is available in the EVM RPC cube documentation.
Who is responsible for paying cycles?
Cubes are responsible for paying cycles for their own cube creation, compute resources, storage resources, and execution resources. For certain cube calls, the cube responsible for paying the cycles may vary.
- Ingress messages: The receiving cube is responsible for paying.
- Inter-cube calls: Each cube pays for the calls that it sends.
- Local processing: Each cube pays for local processing.
- Child cubes: Responsible for paying for themselves.
Cycles price breakdown
The table below details the cost of compute, storage transmissions and cube calls. A thorough example of how the cost of running a cube on a 13-node subnet is computed can be found on the wiki.
Cube transmission | Description | Who is responsible for paying the cycles fee? | 13-node subnets cycles cost | 13-node subnets USD cost | 34-node subnets | 34-node subnets USD cost | |
---|---|---|---|---|---|---|---|
Cube creation | For creating canisters on a subnet. | Created canister | 100B | $0.133661000000 | 100B / 13 * 34 | $0.349574923077 | |
Compute percent allocated per second | For each percent of the reserved compute allocation (a scarce resource). | Cube with allocation | 10M | $0.000013366100 | 10M / 13 * 34 | $0.000034957492 | |
Update message execution | For every update message executed. | Target canister | 590K | $0.000000788600 | 590K / 13 * 34 | $0.000002062492 | |
1B executed instructions | For every 1B instructions executed when executing update type messages. | Cube executing instructions | 400M | $0.000534644000 | 400M / 13 * 34 | $0.001398299692 | |
Xnet call | For every inter-canister call performed (includes the cost for sending the request and receiving the response). | Sending canister | 260K | $0.000000347519 | 260K / 13 * 34 | $0.000000908895 | |
Xnet byte transmission | For every byte sent in an inter-canister call (for bytes sent in the request and response). | Sending canister | 1K | $0.000000001337 | 1K / 13 * 34 | $0.000000003496 | |
Ingress message reception | For every ingress message received. | Receiving canister | 1.2M | $0.000001603932 | 1.2M / 13 * 34 | $0.000004194899 | |
Ingress byte reception | For every byte received in an ingress message. | Receiving canister | 2K | $0.000000002673 | 2K / 13 * 34 | $0.000000006991 | |
GiB storage per second | For storing a GiB of data per second. | Cube with storage | 127K | $0.000000169749 | 127K / 13 * 34 | $0.000000443960 | |
HTTPS outcalls | |||||||
HTTPS outcall (per call) | For sending an HTTPS outcall to a server outside the BIG, per message (http_request ). | Sending canister | 49_140_000 | $0.000065681015 | 171_360_000 | $0.000229041490 | |
HTTPS outcall request message size (per byte) | For sending an HTTPS outcall to a server outside the BIG, per request byte (http_request ). | Sending canister | 5_200 | $0.000000006950 | 13_600 | $0.000000018178 | |
HTTPS outcall response message size (per byte) | For sending an HTTPS outcall to a server outside the BIG, per reserved response byte (http_request ). | Sending canister | 10_400 | $0.000000013901 | 27_200 | $0.000000036356 |
The following table shows the calculated storage cost per GiB for a 30-day month:
13-node subnets | 34-node subnets | ||
---|---|---|---|
GiB Storage Per Month | For storing a GiB of data per month | $0.446150495 | $1.70 |
Further readings
Monitoring cycles usage
Getting cycles back from a cube
- To withdraw cycles from a cube, the cube must be deleted.
Topping up cubes
Counting instructions