Skip to main content

Paying for resources in cycles

Beginner
Concept

Overview

Canisters pay for consumed resources by burning cycles. These resources include storage, messaging, and execution. To obtain cycles, ICP tokens can be converted into cycles.

Replication

Replication refers to the number of times a canister is replicated, which is dependant on the canister's subnet.

Local development

When a canister is deployed to a local development environment, the canister is deployed to a single node. Cycles charged to locally deployed canisters 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 canister is running on 13 nodes and is replicated 13 times. On a 34-node subnet, the canister 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 canisters on high-replication subnets, your canister 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:

AbbreviationNameIn numbersCycles XDR valueCycles USD value
TTrillion1_000_000_000_00011.336610
BBillion1_000_000_0000.0010.001336610
MMillion1_000_0000.0000010.000001336610
kThousand1_0000.0000000010.000000001336610

The reverse gas model

ICP charges the canister 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 ICP's 'reverse gas model'.

ICP does not use the term 'gas', it uses the term 'cycles'.

You can learn more about the reverse gas model.

One downside of the ICP reverse gas model is that it requires prerequisite steps and ongoing maintenance for developers. Canisters must have their cycles balances maintained and regularly topped up as they continuously use resources. The canister will be removed from the network if it runs out of cycles. However, a freezing threshold can be set that pauses a canister'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 canister's cycles, such as CycleOps.

Learn how to query a canister's cycles balance.

Learn how to top up a canister.

Canister operations and resources

Canisters 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:

Canister calls overview

Each type of canister operation and resource has a different cycles cost associated with it. The canister 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.

Canister creation

Canister creation costs 100B cycles or approximately $0.13 USD. Canisters can be created by users or other canisters.

Messaging

A canister can receive messages from users and other canisters. In canister-to-canister messages, the sending canister pays message transmission costs. In user-to-canister messages, the receiving canister covers the message transmission costs (see reverse gas model). User-to-canister 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 typeBase feePer byte fee
Query call00
Canister-to-canister260K1K
User-to-canister (ingress)1.2M2K

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 canister executes the function specified in the message. The execution cost consists of a fixed execution fee and per-instruction fee (on application subnets (13 nodes), 10 instructions cost 4 cycles) 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).

Compute allocation

By default, canisters are scheduled for execution in a "best-effort" manner. Canisters that require guaranteed execution can get a share of compute capacity by setting compute_allocation in their canister settings. Compute allocation is expressed in percents and denotes the percentage of an execution core reserved for the canister.

Setting even 1% compute allocation provides a significant advantage over canisters that use the "best-effort" scheduling:

  • For 1% compute allocation, the canister will receive 1% of an execution core and is guaranteed to be scheduled every 100 rounds (assuming it executes only non-DTS messages).

  • For 2% compute allocation, the canister will receive 2% of an execution core and is guaranteed to be scheduled every 50 rounds.

  • For 50% compute allocation, the canister will receive 50% of an execution core and is guaranteed to be scheduled every other round.

  • For 100% compute allocation, the canister will receive 100% of an execution core and is guaranteed to be scheduled every round.

The allocatable compute capacity is 299% per subnet. Compute allocation is guaranteed if it is configured.

Compute is a finite resource and is priced as such. The current fee for 1% compute allocation per second is 10M cycles (or $0.0000133661 USD). Therefore, a canister that requests 100% compute allocation would be charged 10M * 100 cycles per second.

Storage

Canisters 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.

Canisters can reserve storage on a subnet through the memory_allocation setting. However, the canister 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 Internet Computer uses a resource reservation mechanism that was adopted by the community in NNS proposal 12604.

When a canister allocates new storage bytes, the system sets aside some number of cycles from the main balance of the canister 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 canister settings.

These operations reserve some cycles by moving them from the main balance of the canister 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 is 0.
  • If subnet usage is above 450GiB, then the amount of reserved cycles per allocated byte grows linearly depending on the subnet usage, from 0 to 10 years worth of storage payments at the subnet capacity (which is currently 750GiB).

A controller of a canister can disable resource reservation by setting the reserved_cycles_limit=0 in canister settings. Such opted-out canisters 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 and 400 * n each request byte and 800 * n for each response byte, where n 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 threshold signatures, such as threshold ECDSA and threshold Schnorr, is available in the threshold signatures documentation.

  • EVM RPC Pricing for the EVM RPC canister is available in the EVM RPC canister documentation.

Who is responsible for paying cycles?

Canisters are responsible for paying cycles for their own canister creation, compute resources, storage resources, and execution resources. For certain canister calls, the canister responsible for paying the cycles may vary.

  • Ingress messages: The receiving canister is responsible for paying.
  • Inter-canister calls: Each canister pays for the calls that it sends.
  • Local processing: Each canister pays for local processing.
  • Child canisters: Responsible for paying for themselves.

Cycles price breakdown

The table below details the cost of compute, storage transmissions and canister calls. The ICP pricing calculator can be used to get a comprehensive estimate of what a dapp may cost based on the number of canisters, calls, and features used.

Canister transmissionDescriptionWho is responsible for paying the cycles fee?13-node subnets cycles cost13-node subnets USD cost34-node subnets34-node subnets USD cost
Query callQuery information from a canister.N/AFreeFreeFreeFree
Canister creationFor creating canisters on a subnet.Created canister100B$0.133661000000100B / 13 * 34$0.349574923077
Compute percent allocated per secondFor each percent of the reserved compute allocation (a scarce resource).Canister with allocation10M$0.00001336610010M / 13 * 34$0.000034957492
Update message executionFor every update message executed.Target canister590K$0.000000788600590K / 13 * 34$0.000002062492
1B executed instructionsFor every 1B instructions executed when executing update type messages.Canister executing instructions400M$0.000534644000400M / 13 * 34$0.001398299692
Xnet callFor every inter-canister call performed (includes the cost for sending the request and receiving the response).Sending canister260K$0.000000347519260K / 13 * 34$0.000000908895
Xnet byte transmissionFor every byte sent in an inter-canister call (for bytes sent in the request and response).Sending canister1K$0.0000000013371K / 13 * 34$0.000000003496
Ingress message receptionFor every ingress message received.Receiving canister1.2M$0.0000016039321.2M / 13 * 34$0.000004194899
Ingress byte receptionFor every byte received in an ingress message.Receiving canister2K$0.0000000026732K / 13 * 34$0.000000006991
GiB storage per secondFor storing a GiB of data per second.Canister with storage127K$0.000000169749127K / 13 * 34$0.000000443960
HTTPS outcalls
HTTPS outcall (per call)For sending an HTTPS outcall to a server outside the IC, per message (http_request).Sending canister49_140_000$0.000065681015171_360_000$0.000229041490
HTTPS outcall request message size (per byte)For sending an HTTPS outcall to a server outside the IC, per request byte (http_request).Sending canister5_200$0.00000000695013_600$0.000000018178
HTTPS outcall response message size (per byte)For sending an HTTPS outcall to a server outside the IC, per reserved response byte (http_request).Sending canister10_400$0.00000001390127_200$0.000000036356

The following table shows the calculated storage cost per GiB for a 30-day month:

13-node subnets34-node subnets
GiB Storage Per MonthFor storing a GiB of data per month$0.446150495$1.70

Common errors related to cycles include:

Further readings

Monitoring cycles usage

Getting cycles back from a canister

Topping up canisters

Counting instructions