1.6 Managing canisters
Now that you have canisters deployed, the next step is to learn how to manage those canisters. Managing a canister includes obtaining the canister's usage information, setting an identity as the canister's controller, and deleting a canister.
The ICP management canister
The ICP management canister exposes management functionality to end users and canisters. While it is titled the 'management canister,' it is not actually a canister that exists with an isolated state, Wasm code, etc., but rather a system API. It is important to know the management canister's role, however, to understand some of the more advanced ICP features, such as threshold ECDSA and the Bitcoin integration.
Management operations such as updating a canister, creating a canister, and stopping or starting a canister are sent to the management canister to be executed. When executed, the messages are sent to the relevant subnet and intercepted by the execution environment, which triggers the execution of the operation.
- Prerequisites
Obtaining a canister's ID
Each canister has a unique identifier that can be used to interact with the canister. These unique IDs can be used to access the canister's frontend or Candid UI in a web browser, such as when you accessed the frontend of your hello_world dapp in the last tutorial. Having a canister's ID is also important for executing management functions of the canister, such as setting ownership for the canister.
As an example, to get the canister ID of your hello_world_backend
canister that's been deployed locally, use the command:
dfx canister id hello_world_backend
Output
bkyz2-fmaaa-aaaaa-qaaaq-cai
Obtaining canister information
Next, to view the canister's controller(s) and the Wasm module hash, use the command:
dfx canister info hello_world_backend
Output
Controllers: bnz7o-iuaaa-aaaaa-qaaaa-cai x4d3z-ufpaj-lpxs4-v7gmt-v56ze-aub3k-bvifl-y4lsq-soafd-d3i4k-fqe
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
Adding an identity as a controller of a canister
To add another identity as an additional controller of the canister, first, let's create a new identity:
dfx identity new ControllerExample
Then, get the principal value for this new identity with the command:
dfx identity use ControllerExample
dfx identity get-principal
Output
lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
Copy this value. You'll then use the dfx canister update-settings
command to add this principal to be a controller of your hello_world_backend
canister, but first, you need to switch back to your previously created identity, since only existing controllers can add new controllers:
dfx identity use DeveloperLiftoff
Then, use the dfx canister update-settings
command:
dfx canister update-settings hello_world_backend --add-controller PRINCIPAL_ID
For example, to use your principal value from above:
dfx canister update-settings hello_world_backend --add-controller lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
This command adds the principal lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
as an additional controller of your hello_world_backend
canister. To confirm that this principal has been added, you can run the dfx canister info
command again:
dfx canister info hello_world_backend
Now you can see this principal listed as a controller:
Controllers: bnz7o-iuaaa-aaaaa-qaaaa-cai lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae x4d3z-ufpaj-lpxs4-v7gmt-v56ze-aub3k-bvifl-y4lsq-soafd-d3i4k-fqe
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
You can remove this principal with the command:
dfx canister update-settings hello_world_backend --remove-controller PRINCIPAL_ID
Alternatively, you can use the --set-controller
flag instead of the --add-controller
flag. If any controllers are set using the --set-controller
flag, any other existing controllers will be removed. For example, re-run the command above, but use the --set-controller
flag instead:
dfx canister update-settings hello_world_backend --set-controller lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
You will be warned that you'll be removing yourself as a controller since you're setting the ControllerExample
identity as the sole controller while you're using the DeveloperLiftoff
identity. Accept this warning.
Then, rerun the dfx canister info hello_world_backend
command. The output should now be:
Controllers: lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
Managing the running state of a canister
Once a canister has been deployed, it is in a Running state and can receive and process requests from other canisters or end users.
Canisters are placed in the Running state by default, but there may be situations where a canister needs to be temporarily or permanently stopped. For example, before a canister is upgraded, it may be stopped to ensure proper message handling if a message is in progress or should be rolled back. Stopping a canister is also a requirement if the canister is going to be deleted.
To check the current state of a canister by specifying its name, such as:
dfx canister status hello_world_backend
Output
Canister status call result for hello_world_backend.
Status: Running
Controllers: lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Memory Size: Nat(2363181)
Balance: 3_100_000_000_000 Cycles
Reserved: 0 Cycles
Reserved Cycles Limit: 5_000_000_000_000 Cycles
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
Stopping a canister works in a similar fashion. For example, to stop a canister, run the command:
dfx canister stop hello_world_backend
Output
Stopping code for canister hello_world_backend, with canister_id 5o6tz-saaaa-aaaaa-qaacq-cai
Then you can verify that the canister has been stopped by rerunning the dfx canister status
command:
dfx canister status hello_world_backend
Output
Canister status call result for hello_world_backend.
Status: Stopped
Controllers: lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Memory Size: Nat(2363181)
Balance: 3_100_000_000_000 Cycles
Reserved: 0 Cycles
Reserved Cycles Limit: 5_000_000_000_000 Cycles
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
Then to start the canister again, run the command:
dfx canister start hello_world_backend
Output
Starting code for canister hello_world_backend, with canister_id 5o6tz-saaaa-aaaaa-qaacq-cai
Checking the cycles balance of a canister
To check a canister's cycles balance, you must be the controller of the canister. The cycles balance can be seen in the output of the dfx canister status
command, such as:
dfx canister status hello_world_backend
The output will resemble the following, where the value Balance
refers to the main cycles balance and Reserved
refers to the reserved cycles balance:
Canister status call result for 5o6tz-saaaa-aaaaa-qaacq-cai.
Status: Stopped
Controllers: lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Memory Size: Nat(2363181)
Balance: 3_100_000_000_000 Cycles
Reserved: 0 Cycles
Reserved Cycles Limit: 5_000_000_000_000 Cycles
Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17
Topping up a canister's cycles balance
Depositing cycles into a canister's cycles balance is known as "topping up." For production canisters, which consistently use cycles over time to pay for the canister's resources on the mainnet, topping up the canister is routine maintenance.
While you must be a canister's controller in order to view the cycles balance of the canister, anyone can top up a canister using one of the following methods:
- Using ICP in your account.
- Using the cycles ledger.
- Using the NNS dapp web UI.
- Using a third-party service such as CycleOps.
Local development fabricates cycles as needed for canister deployment. To learn about topping up canisters on the mainnet, read more about how to use ICP or cycles.
Setting the canister's freezing threshold
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 hello_world_backend
canister, use the command:
dfx canister update-settings hello_world_backend --freezing-threshold 3472000
Then, you can confirm that this threshold has been set by running the dfx canister status hello_world_backend
command again:
Canister status call result for hello_world_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
Deleting a canister
Deleting a canister will withdraw any cycles from that canister and return them to the identity associated with the canister's controller principal. When a canister is deleted, the canister's code, state, and canister ID are removed.
Canisters must be stopped before they can be deleted:
dfx canister stop hello_world_backend
Then you can run the command:
dfx canister delete hello_world_backend

Did you get stuck somewhere in this tutorial, or do you feel like you need additional help understanding some of the concepts? The ICP community has several resources available for developers, like working groups and bootcamps, along with our Discord community, forum, and events such as hackathons. Here are a few to check out:
- Developer Discord
- Developer Liftoff forum discussion
- Developer tooling working group
- Motoko Bootcamp - The DAO Adventure
- Motoko Bootcamp - Discord community
- Motoko developer working group
- Upcoming events and conferences
- Upcoming hackathons
- Weekly developer office hours to ask questions, get clarification, and chat with other developers live via voice chat.
- Submit your feedback to the ICP Developer feedback board