Topping up a canister
Overview
A canister needs to have cycles deposited continuously into it to pay for the resources it uses. This process is known as 'topping up' the canister. Topping up canisters is routine maintenance.
Basic rules
Anyone can top up any canister deployed to ICP; you do not need to be the owner or controller of the canister. All you need is the canister's principal.
There are a few different ways to top up canisters, such as:
Using
dfx
.Through the NNS frontend dapp.
Through a third-party service (e.g. https://cycleops.dev).
Number of cycles
For ease of use, you can copy/paste the cycles amounts below:
Cycles | Number |
---|---|
1 million | 1000000 |
10 million | 10000000 |
100 million | 100000000 |
1 billion | 1000000000 |
10 billion | 10000000000 |
100 billion | 100000000000 |
1 trillion | 1000000000000 |
10 trillion | 10000000000000 |
100 trillion | 100000000000000 |
Canister top up workflows
The following examples will demonstrate how to interact with and top up a canister with the canister ID jqylk-byaaa-aaaal-qbymq-cai
with a million cycles (1000000). These instructions will work for any canister ID or cycles amount.
Checking the cycles balance of a canister
Canister cycles balances are not exposed publicly by default; you can only see them if you are the controller of a canister. Using jqylk-byaaa-aaaal-qbymq-cai
as an example, you can query it by calling:
dfx canister status jqylk-byaaa-aaaal-qbymq-cai --network ic
The output will look like this:
Canister status call result for jqylk-byaaa-aaaal-qbymq-cai.
Status: Running
Controllers: mto6d-zfnut-rlsxr-ogdeg-apo53-evpob-ljgnp-ma2x3-6yf3b-t4rd5-qqe t5j57-vyaaa-aaaal-qatsq-cai
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Memory Size: Nat(2471918)
Balance: 9_811_813_913_485 Cycles
Module hash: 0xe7866e1949e3688a78d8d29bd63e1c13cd6bfb8fbe29444fa606a20e0b1e33f0
Canisters can check their own balance programmatically. For example:
- Motoko
- Rust
Motoko canisters can use the ExperimentalCycles library to interact with cycles:
import Cycles "mo:base/ExperimentalCycles";
import Debug "mo:base/Debug";
actor {
public func main() : async() {
Debug.print("Main balance: " # debug_show(Cycles.balance()));
};
}
Rust canisters can use the function canister_balance128()
from the Rust IC CDK:
let current_canister_balance = ic_cdk::api::canister_balance();
Option 1: If you have ICP on your account
If you have ICP on the account associated with a dfx
identity, you can tell the ledger canister to take some of that ICP, convert it to cycles, and give it to a canister of your choice using the command dfx ledger top-up --icp <AMOUNT> <DESTINATION> --network ic
:
dfx ledger account-id
dfx ledger balance --network ic
dfx ledger top-up --icp 1 jqylk-byaaa-aaaal-qbymq-cai --network ic
- The
dfx ledger account-id
returns the ledger account ID of the currentdfx
identity used. - The
dfx ledger --network ic balance
command checks the balance on theaccount
associated with the currentdfx
identity used. -
top-up --icp 1 jqylk-byaaa-aaaal-qbymq-cai
command converts 1 ICP into cycles and uses them to refill canisterjqylk-byaaa-aaaal-qbymq-cai
. -
--network ic
tellsdfx
to use the mainnet as the network (rather than the local replica).
Option 2: If you have cycles
If you have a cycles balance associated with your developer identity, you can top up a canister with the command dfx cycles top-up <DESTINATION> <AMOUNT>
:
dfx cycles balance --network ic
dfx cycles top-up jqylk-byaaa-aaaal-qbymq-cai 1 --network ic
This workflow uses the cycles ledger, a feature that requires dfx
version 0.19.0
. To enable this feature, you will need to set the following environmental variable:
DFX_CYCLES_LEDGER_SUPPORT_ENABLE=1
- The
cycles balance --network ic
command checks the cycles balance of your identity on the mainnet. - The
cycles top-up
command transfers cycles to the canister of your choice.
Special case: topping up a cycles wallet
Please note that the cycles wallet will be removed from dfx
in a future release.
It is recommended to use the cycles ledger instead.
Cycles wallets are canisters like any other, so you can top them up as well. If you have a cycles wallet you control via dfx, there is another option as well for sending cycles from your cycles wallet to a canister of your choice: dfx wallet send [OPTIONS] <DESTINATION> <AMOUNT>
.
In this example, it is assumed you are sending cycles to a cycles wallet with the principal ID dfds-sddds-aaaal-qbsms-cai
.
dfx wallet balance --network ic
dfx wallet send 1000000 dfds-sddds-aaaal-qbsms-cai --network ic
- The
wallet balance --network ic
checks the cycles balance of your cycles wallet on the mainnet. - The
wallet send 1000000 dfds-sddds-aaaal-qbsms-cai --network ic
takes 1000000 cycles from your cycles wallet and sends them to cycles walletdfds-sddds-aaaal-qbsms-cai
.
Topping up a canister with the NNS frontend dapp
You can also top up any canister via the NNS frontend dapp:
Step 1: Navigate to the My Canisters section of the dapp.
Step 2: Click Link Canister.
Step 3: Add a canister principal. It is not necessary for the user to actually control said canister.
Step 4: Once the canister is added, click on that canister.
Step 5: Click
Add cycles
to add cycles using the ICP in your NNS frontend dapp.
Managing cycle depletion with freezing threshold
ICP features a mechanism to prevent canisters from running out of cycles. Canisters have a configurable freezing_threshold
, dynamically evaluated in cycles.
In the output of the dfx canister status
command, you may have noticed the freezing threshold
value. The freezing threshold is a value defined in seconds, which is used to calculate how many cycles a canister must retain in its cycles balance. This calculation is based off of the canister's memory consumption. The default freezing threshold value is 2_592_000s
, which corresponds to 30 days.
The freezing threshold is important because if a canister runs out of cycles, it will be uninstalled. The freezing threshold protects it from deletion, since if the cycles balance dips below the threshold, the canister will stop processing any new requests; however, it will continue to reply to existing requests.
For example, to set a freezing threshold for your poll_backend
canister, use the command:
dfx canister update-settings poll_backend --freezing-threshold 3472000
```
Then, you can confirm that this threshold has been set by running the `dfx canister status poll_backend --network ic ` command again:
```bash
Canister status call result for poll_backend.
Status: Stopped
Controllers: lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 3_472_000
Memory Size: Nat(2363181)
Balance: 3_100_000_000_000 Cycles
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
```