From 412d5b38cdb08006050ed53757edb5c33a47eb23 Mon Sep 17 00:00:00 2001 From: Bjoern Tackmann Date: Fri, 31 Jul 2026 11:16:33 +0200 Subject: [PATCH 01/11] spec: add subnet_metrics management canister endpoint Proposal for discussion. Adds a subnet_metrics endpoint returning the subnet block height plus the four subnet-wide metrics that are currently only reachable by external users via the certified state tree path /subnet//metrics. --- .../ic-interface-spec/abstract-behavior.md | 39 +++++++++++++++++++ .../references/ic-interface-spec/changelog.md | 8 ++++ .../ic-interface-spec/management-canister.md | 32 +++++++++++++++ docs/references/management-canister.md | 18 +++++++++ public/references/ic.did | 19 +++++++++ 5 files changed, 116 insertions(+) diff --git a/docs/references/ic-interface-spec/abstract-behavior.md b/docs/references/ic-interface-spec/abstract-behavior.md index a99ca398..43d1c800 100644 --- a/docs/references/ic-interface-spec/abstract-behavior.md +++ b/docs/references/ic-interface-spec/abstract-behavior.md @@ -3056,6 +3056,45 @@ S with ``` +#### IC Management Canister: Subnet Metrics + +:::note + +The subnet metrics management canister API is considered EXPERIMENTAL. Canister developers must be aware that the API may evolve in a non-backward-compatible way. + +::: + +The management canister returns subnet-wide metrics for the subnet hosting the calling canister. The definition of the metrics values +is not captured in this formal semantics. + +Conditions + +```html + +S.messages = Older_messages · CallMessage M · Younger_messages +(M.queue = Unordered) or (∀ CallMessage M' | FuncMessage M' ∈ Older_messages. M'.queue ≠ M.queue) +M.callee = ic_principal +M.method_name = 'subnet_metrics' +M.arg = candid(A) +A.subnet_id = S.canister_subnet[M.caller] +R = + +``` + +State after + +```html + +S with + messages = Older_messages · Younger_messages · + ResponseMessage { + origin = M.origin + response = Reply (candid(R)) + refunded_cycles = M.transferred_cycles + } + +``` + #### IC Management Canister: Subnet information The management canister returns subnet metadata given a subnet ID. diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index 86e2fcfb..a30cee77 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -8,6 +8,14 @@ sidebar: ## Changelog {#changelog} +### 0.65.0 (2026-07-31) {$0_65_0} +* New management canister endpoint `subnet_metrics` returning subnet-wide metrics for the + subnet hosting the calling canister: the block height, the number of canisters, the + total canister state size, the total cycles consumed, and the total number of processed + transactions. All fields except the block height were previously only readable by + external users via the certified state tree path `/subnet//metrics`. + The API is EXPERIMENTAL. + ### 0.64.0 (2026-07-06) {$0_64_0} * New optional `permissions` field in request delegations restricting the kinds of requests the delegation applies for: the value `"queries"` restricts the delegation to query calls diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 386f669c..2bd1598f 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -749,6 +749,38 @@ A single metric entry is a record with the following fields: - `num_block_failures_total` (`nat64`): the number of failed block proposals by this node. +### IC method `subnet_metrics` {#ic-subnet_metrics} + +This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. + +:::note + +The subnet metrics management canister API is considered EXPERIMENTAL. Canister developers must be aware that the API may evolve in a non-backward-compatible way. + +::: + +Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. The subnet ID must be the subnet that hosts the calling canister; calls specifying any other subnet ID are rejected with reject code `CANISTER_REJECT`. + + + +All fields except `block_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. + +The fields returned are: + +- `block_height` (`nat`): the height of the block whose batch contains this call. The value is deterministic, i.e., it is a property of the block rather than of the node executing the call. It is monotonically non-decreasing for a given subnet, but it may jump if the subnet is recovered and it is not guaranteed to count from the subnet's first block. + +- `num_canisters` (`nat`): the number of canisters currently on this subnet. This is a current value, not a counter, so it decreases when canisters are deleted. + +- `canister_state_bytes` (`nat`): the total size in bytes of the state currently taken by canisters on this subnet. This is a current value, not a counter. + +- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on this subnet by all current and deleted canisters. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. + +- `update_transactions_total` (`nat`): the total number of transactions processed on this subnet. + + + +The counter fields `consumed_cycles_total` and `update_transactions_total` accumulate since the subnet was created, or since the respective metric was introduced for subnets that predate it. + ### IC method `subnet_info` {#ic-subnet_info} This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. diff --git a/docs/references/management-canister.md b/docs/references/management-canister.md index 7fb925df..f0110541 100644 --- a/docs/references/management-canister.md +++ b/docs/references/management-canister.md @@ -559,6 +559,24 @@ Returns a time series of node metrics for a given subnet. Returns up to 60 times - `num_blocks_proposed_total` (`nat64`) - `num_block_failures_total` (`nat64`) +### `subnet_metrics` + +> This API is **experimental** and may change in a non-backward-compatible way. + +Returns subnet-wide metrics for the subnet hosting the calling canister. Every field except `block_height` reports the same quantity that the certified state tree exposes at `/subnet//metrics`; this method makes those quantities available to canisters, which cannot read the state tree. + +- **Caller:** Canisters only +- **Parameters:** + - `subnet_id` (`principal`): must be the subnet hosting the caller +- **Returns:** + - `block_height` (`nat`): height of the block whose batch contains the call + - `num_canisters` (`nat`): canisters currently on the subnet + - `canister_state_bytes` (`nat`): current total size of canister state in bytes + - `consumed_cycles_total` (`nat`): total cycles removed from circulation on the subnet + - `update_transactions_total` (`nat`): total transactions processed on the subnet + +`consumed_cycles_total` and `update_transactions_total` are counters; `num_canisters` and `canister_state_bytes` are current values. + ### `subnet_info` Returns metadata about a subnet. diff --git a/public/references/ic.did b/public/references/ic.did index 8d6fab7a..2e7230e5 100644 --- a/public/references/ic.did +++ b/public/references/ic.did @@ -436,6 +436,24 @@ type node_metrics_history_result = vec record { node_metrics : vec node_metrics; }; +type subnet_metrics_args = record { + subnet_id : principal; +}; + +type subnet_metrics_result = record { + // Height of the block whose batch contains this call. + block_height : nat; + // Current number of canisters on this subnet. + num_canisters : nat; + // Current total size in bytes of the state taken by canisters on this subnet. + canister_state_bytes : nat; + // Total cycles removed from circulation on this subnet by all current and + // deleted canisters. + consumed_cycles_total : nat; + // Total number of transactions processed on this subnet. + update_transactions_total : nat; +}; + type subnet_info_args = record { subnet_id : principal; }; @@ -700,6 +718,7 @@ service ic : { // metrics interface node_metrics_history : (node_metrics_history_args) -> (node_metrics_history_result); + subnet_metrics : (subnet_metrics_args) -> (subnet_metrics_result); // subnet info subnet_info : (subnet_info_args) -> (subnet_info_result); From da04d01c6285b856008b5255a96da7ac778c72c6 Mon Sep 17 00:00:00 2001 From: Bjoern Tackmann Date: Fri, 31 Jul 2026 18:14:24 +0200 Subject: [PATCH 02/11] spec: address review feedback on subnet_metrics - Drop the own-subnet restriction: cross-subnet calls are handled by the existing message routing protocol, so no restriction is needed. - Report the subnet's latest certified height rather than the height of the block containing the call, and rename the field to certified_height. - Keep nat for all fields, since consumed_cycles_total cannot be nat64. --- .../ic-interface-spec/abstract-behavior.md | 3 +-- .../references/ic-interface-spec/changelog.md | 11 ++++----- .../ic-interface-spec/management-canister.md | 23 +++++++++++-------- docs/references/management-canister.md | 6 ++--- public/references/ic.did | 13 ++++++----- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/docs/references/ic-interface-spec/abstract-behavior.md b/docs/references/ic-interface-spec/abstract-behavior.md index 43d1c800..4a44d41b 100644 --- a/docs/references/ic-interface-spec/abstract-behavior.md +++ b/docs/references/ic-interface-spec/abstract-behavior.md @@ -3064,7 +3064,7 @@ The subnet metrics management canister API is considered EXPERIMENTAL. Canister ::: -The management canister returns subnet-wide metrics for the subnet hosting the calling canister. The definition of the metrics values +The management canister returns subnet-wide metrics given a subnet ID. The definition of the metrics values is not captured in this formal semantics. Conditions @@ -3076,7 +3076,6 @@ S.messages = Older_messages · CallMessage M · Younger_messages M.callee = ic_principal M.method_name = 'subnet_metrics' M.arg = candid(A) -A.subnet_id = S.canister_subnet[M.caller] R = ``` diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index a30cee77..143d5b85 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -9,12 +9,11 @@ sidebar: ## Changelog {#changelog} ### 0.65.0 (2026-07-31) {$0_65_0} -* New management canister endpoint `subnet_metrics` returning subnet-wide metrics for the - subnet hosting the calling canister: the block height, the number of canisters, the - total canister state size, the total cycles consumed, and the total number of processed - transactions. All fields except the block height were previously only readable by - external users via the certified state tree path `/subnet//metrics`. - The API is EXPERIMENTAL. +* New management canister endpoint `subnet_metrics` returning subnet-wide metrics for a + given subnet: the latest certified height, the number of canisters, the total canister + state size, the total cycles consumed, and the total number of processed transactions. + All fields except the certified height were previously only readable by external users + via the certified state tree path `/subnet//metrics`. The API is EXPERIMENTAL. ### 0.64.0 (2026-07-06) {$0_64_0} * New optional `permissions` field in request delegations restricting the kinds of requests diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 2bd1598f..83e3d030 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -759,23 +759,28 @@ The subnet metrics management canister API is considered EXPERIMENTAL. Canister ::: -Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. The subnet ID must be the subnet that hosts the calling canister; calls specifying any other subnet ID are rejected with reject code `CANISTER_REJECT`. +Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. The subnet ID does not have to be the subnet that hosts the calling canister. - +All fields except `certified_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. -All fields except `block_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. +In the following, *the subnet* refers to the subnet identified by the `subnet_id` argument. The fields returned are: -The fields returned are: +- `certified_height` (`nat`): the height of the latest state of the subnet for which the subnet has produced a certificate (see [Certification](./certification.md#certification)). Heights are consecutive numbers identifying the successive states of a subnet. This specification does not otherwise model state heights, and heights of different subnets are unrelated, so this value is only meaningful when compared against other values for the same subnet. + + The value is monotonically non-decreasing for a given subnet, but it may jump if the subnet is recovered, and it is not guaranteed to count from the subnet's first state. Note that the latest certified height is lower than the height of the subnet's latest state, because certification lags execution. + + All nodes of the subnet executing the call must return the same value, i.e., the value must not be derived from a single node's local view. + + -- `block_height` (`nat`): the height of the block whose batch contains this call. The value is deterministic, i.e., it is a property of the block rather than of the node executing the call. It is monotonically non-decreasing for a given subnet, but it may jump if the subnet is recovered and it is not guaranteed to count from the subnet's first block. -- `num_canisters` (`nat`): the number of canisters currently on this subnet. This is a current value, not a counter, so it decreases when canisters are deleted. +- `num_canisters` (`nat`): the number of canisters currently on the subnet. This is a current value, not a counter, so it decreases when canisters are deleted. -- `canister_state_bytes` (`nat`): the total size in bytes of the state currently taken by canisters on this subnet. This is a current value, not a counter. +- `canister_state_bytes` (`nat`): the total size in bytes of the state currently taken by canisters on the subnet. This is a current value, not a counter. -- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on this subnet by all current and deleted canisters. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. +- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on the subnet by all current and deleted canisters. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. -- `update_transactions_total` (`nat`): the total number of transactions processed on this subnet. +- `update_transactions_total` (`nat`): the total number of transactions processed on the subnet. diff --git a/docs/references/management-canister.md b/docs/references/management-canister.md index f0110541..2859b6ab 100644 --- a/docs/references/management-canister.md +++ b/docs/references/management-canister.md @@ -563,13 +563,13 @@ Returns a time series of node metrics for a given subnet. Returns up to 60 times > This API is **experimental** and may change in a non-backward-compatible way. -Returns subnet-wide metrics for the subnet hosting the calling canister. Every field except `block_height` reports the same quantity that the certified state tree exposes at `/subnet//metrics`; this method makes those quantities available to canisters, which cannot read the state tree. +Returns subnet-wide metrics for a given subnet, which does not have to be the subnet hosting the caller. Every field except `certified_height` reports the same quantity that the certified state tree exposes at `/subnet//metrics`; this method makes those quantities available to canisters, which cannot read the state tree. - **Caller:** Canisters only - **Parameters:** - - `subnet_id` (`principal`): must be the subnet hosting the caller + - `subnet_id` (`principal`): any subnet - **Returns:** - - `block_height` (`nat`): height of the block whose batch contains the call + - `certified_height` (`nat`): height of the subnet's latest certified state. Lags the subnet's latest state, since certification lags execution. - `num_canisters` (`nat`): canisters currently on the subnet - `canister_state_bytes` (`nat`): current total size of canister state in bytes - `consumed_cycles_total` (`nat`): total cycles removed from circulation on the subnet diff --git a/public/references/ic.did b/public/references/ic.did index 2e7230e5..c6b131dd 100644 --- a/public/references/ic.did +++ b/public/references/ic.did @@ -441,16 +441,17 @@ type subnet_metrics_args = record { }; type subnet_metrics_result = record { - // Height of the block whose batch contains this call. - block_height : nat; - // Current number of canisters on this subnet. + // Height of the latest state of the subnet for which the subnet has + // produced a certificate. + certified_height : nat; + // Current number of canisters on the subnet. num_canisters : nat; - // Current total size in bytes of the state taken by canisters on this subnet. + // Current total size in bytes of the state taken by canisters on the subnet. canister_state_bytes : nat; - // Total cycles removed from circulation on this subnet by all current and + // Total cycles removed from circulation on the subnet by all current and // deleted canisters. consumed_cycles_total : nat; - // Total number of transactions processed on this subnet. + // Total number of transactions processed on the subnet. update_transactions_total : nat; }; From f9861d3754ecd7eadbee79c0a5a16178b2633b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Tackmann?= <54846571+Dfinity-Bjoern@users.noreply.github.com> Date: Mon, 3 Aug 2026 09:55:49 +0200 Subject: [PATCH 03/11] Remove unnecessary clarification --- docs/references/ic-interface-spec/management-canister.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 83e3d030..aa196acd 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -759,7 +759,7 @@ The subnet metrics management canister API is considered EXPERIMENTAL. Canister ::: -Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. The subnet ID does not have to be the subnet that hosts the calling canister. +Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. All fields except `certified_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. From a4f8325dbfbf5f850b79ea76d26126e366acb12f Mon Sep 17 00:00:00 2001 From: Bjoern Tackmann Date: Mon, 3 Aug 2026 11:38:18 +0200 Subject: [PATCH 04/11] spec: use current block height in subnet_metrics Replace certified_height with block_height, defined as the height of the block in whose execution the call is processed on the target subnet. --- docs/references/ic-interface-spec/changelog.md | 6 +++--- .../ic-interface-spec/management-canister.md | 11 ++++------- docs/references/management-canister.md | 4 ++-- public/references/ic.did | 6 +++--- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index 143d5b85..c958bfd6 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -10,10 +10,10 @@ sidebar: ### 0.65.0 (2026-07-31) {$0_65_0} * New management canister endpoint `subnet_metrics` returning subnet-wide metrics for a - given subnet: the latest certified height, the number of canisters, the total canister + given subnet: the current block height, the number of canisters, the total canister state size, the total cycles consumed, and the total number of processed transactions. - All fields except the certified height were previously only readable by external users - via the certified state tree path `/subnet//metrics`. The API is EXPERIMENTAL. + All fields except the block height were previously only readable by external users via + the certified state tree path `/subnet//metrics`. The API is EXPERIMENTAL. ### 0.64.0 (2026-07-06) {$0_64_0} * New optional `permissions` field in request delegations restricting the kinds of requests diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index aa196acd..8d8a9b0d 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -761,18 +761,15 @@ The subnet metrics management canister API is considered EXPERIMENTAL. Canister Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. -All fields except `certified_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. +All fields except `block_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. In the following, *the subnet* refers to the subnet identified by the `subnet_id` argument. The fields returned are: -- `certified_height` (`nat`): the height of the latest state of the subnet for which the subnet has produced a certificate (see [Certification](./certification.md#certification)). Heights are consecutive numbers identifying the successive states of a subnet. This specification does not otherwise model state heights, and heights of different subnets are unrelated, so this value is only meaningful when compared against other values for the same subnet. +- `block_height` (`nat`): the current block height of the subnet, i.e., the height of the block in whose execution this call is processed. - The value is monotonically non-decreasing for a given subnet, but it may jump if the subnet is recovered, and it is not guaranteed to count from the subnet's first state. Note that the latest certified height is lower than the height of the subnet's latest state, because certification lags execution. - - All nodes of the subnet executing the call must return the same value, i.e., the value must not be derived from a single node's local view. - - + Heights are consecutive numbers identifying the successive blocks of a subnet. This specification does not otherwise model block heights, and heights of different subnets are unrelated, so this value is only meaningful when compared against other values for the same subnet. + The value is deterministic, i.e., it is a property of the block in whose execution the call is processed rather than of the node executing it, so all nodes of the subnet return the same value. It is monotonically non-decreasing for a given subnet, but it may jump if the subnet is recovered, and it is not guaranteed to count from the subnet's first block. - `num_canisters` (`nat`): the number of canisters currently on the subnet. This is a current value, not a counter, so it decreases when canisters are deleted. diff --git a/docs/references/management-canister.md b/docs/references/management-canister.md index 2859b6ab..d5729785 100644 --- a/docs/references/management-canister.md +++ b/docs/references/management-canister.md @@ -563,13 +563,13 @@ Returns a time series of node metrics for a given subnet. Returns up to 60 times > This API is **experimental** and may change in a non-backward-compatible way. -Returns subnet-wide metrics for a given subnet, which does not have to be the subnet hosting the caller. Every field except `certified_height` reports the same quantity that the certified state tree exposes at `/subnet//metrics`; this method makes those quantities available to canisters, which cannot read the state tree. +Returns subnet-wide metrics for a given subnet, which does not have to be the subnet hosting the caller. Every field except `block_height` reports the same quantity that the certified state tree exposes at `/subnet//metrics`; this method makes those quantities available to canisters, which cannot read the state tree. - **Caller:** Canisters only - **Parameters:** - `subnet_id` (`principal`): any subnet - **Returns:** - - `certified_height` (`nat`): height of the subnet's latest certified state. Lags the subnet's latest state, since certification lags execution. + - `block_height` (`nat`): the target subnet's current block height, i.e. the height of the block in whose execution the call is processed - `num_canisters` (`nat`): canisters currently on the subnet - `canister_state_bytes` (`nat`): current total size of canister state in bytes - `consumed_cycles_total` (`nat`): total cycles removed from circulation on the subnet diff --git a/public/references/ic.did b/public/references/ic.did index c6b131dd..2eb031f1 100644 --- a/public/references/ic.did +++ b/public/references/ic.did @@ -441,9 +441,9 @@ type subnet_metrics_args = record { }; type subnet_metrics_result = record { - // Height of the latest state of the subnet for which the subnet has - // produced a certificate. - certified_height : nat; + // Current block height of the subnet, i.e. the height of the block in + // whose execution this call is processed. + block_height : nat; // Current number of canisters on the subnet. num_canisters : nat; // Current total size in bytes of the state taken by canisters on the subnet. From b09b864036758faf4ac35324fa0fa221f2191370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Tackmann?= <54846571+Dfinity-Bjoern@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:04:31 +0200 Subject: [PATCH 05/11] Shorter and more precise formulation. --- docs/references/ic-interface-spec/management-canister.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 8d8a9b0d..01d75756 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -769,7 +769,7 @@ In the following, *the subnet* refers to the subnet identified by the `subnet_id Heights are consecutive numbers identifying the successive blocks of a subnet. This specification does not otherwise model block heights, and heights of different subnets are unrelated, so this value is only meaningful when compared against other values for the same subnet. - The value is deterministic, i.e., it is a property of the block in whose execution the call is processed rather than of the node executing it, so all nodes of the subnet return the same value. It is monotonically non-decreasing for a given subnet, but it may jump if the subnet is recovered, and it is not guaranteed to count from the subnet's first block. + The value is monotonically non-decreasing for a given subnet. - `num_canisters` (`nat`): the number of canisters currently on the subnet. This is a current value, not a counter, so it decreases when canisters are deleted. From 62c46b862f0cb1aa3c22fbd62151a911c70533c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Tackmann?= <54846571+Dfinity-Bjoern@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:04:50 +0200 Subject: [PATCH 06/11] Apply suggestion from @mraszyk Co-authored-by: mraszyk <31483726+mraszyk@users.noreply.github.com> --- docs/references/ic-interface-spec/management-canister.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 01d75756..49a35d33 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -777,7 +777,7 @@ In the following, *the subnet* refers to the subnet identified by the `subnet_id - `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on the subnet by all current and deleted canisters. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. -- `update_transactions_total` (`nat`): the total number of transactions processed on the subnet. +- `update_transactions_total` (`nat`): the total number of transactions processed on the subnet, i.e., the total number of messages executed in the replicated mode. From 97925b5e4a659673e4dfe47b92c598a56ef41559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Tackmann?= <54846571+Dfinity-Bjoern@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:05:11 +0200 Subject: [PATCH 07/11] Apply suggestion from @mraszyk Co-authored-by: mraszyk <31483726+mraszyk@users.noreply.github.com> --- docs/references/ic-interface-spec/management-canister.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 49a35d33..a8003353 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -779,8 +779,6 @@ In the following, *the subnet* refers to the subnet identified by the `subnet_id - `update_transactions_total` (`nat`): the total number of transactions processed on the subnet, i.e., the total number of messages executed in the replicated mode. - - The counter fields `consumed_cycles_total` and `update_transactions_total` accumulate since the subnet was created, or since the respective metric was introduced for subnets that predate it. ### IC method `subnet_info` {#ic-subnet_info} From 915aa21c97d6a8616324c95d85e25112d2a4a536 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Mon, 14 Sep 2026 08:24:37 +0000 Subject: [PATCH 08/11] spec: align subnet_metrics field semantics with the implementation Verified the subnet_metrics text field by field against the deployed replica (release-2026-09-03_04-41-base) and corrected three claims: * Only block_height describes the block in whose execution the call is processed. The other four fields are aggregates refreshed at block boundaries, so they describe an earlier block and need not be mutually consistent. * canister_state_bytes is refreshed only every 10 blocks, at heights that are multiples of 10, and reads 0 until the first refresh after the subnet was created. * consumed_cycles_total is not a monotonic counter: it nets out refunds of cycles charged in advance, so it can decrease. It also covers deleted canisters and cycles consumed on behalf of the subnet itself. update_transactions_total is monotonically non-decreasing. The state tree description of the same aggregates in index.md is corrected accordingly, including canister_state_bytes, which was described as accumulating since the subnet was created. --- docs/references/ic-interface-spec/index.md | 8 +++--- .../ic-interface-spec/management-canister.md | 16 +++++++----- docs/references/management-canister.md | 8 +++--- public/references/ic.did | 25 ++++++++++++++----- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/docs/references/ic-interface-spec/index.md b/docs/references/ic-interface-spec/index.md index 5a2b0935..726d6f9f 100644 --- a/docs/references/ic-interface-spec/index.md +++ b/docs/references/ic-interface-spec/index.md @@ -517,10 +517,10 @@ The state tree contains information about the topology of the Internet Computer. A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - - `num_canisters` (`nat`): The number of canisters on this subnet. - - `canister_state_bytes` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. - - `consumed_cycles_total` (`map`): The total number of cycles consumed by all current and deleted canisters on this subnet. It's a map of two values, a low part of type `nat` and a high part of type `opt nat`. - - `update_transactions_total` (`nat`): The total number of transactions processed on this subnet since this subnet was created. + - `num_canisters` (`nat`): The number of canisters on this subnet. This is a current value, not a counter, so it decreases when canisters are deleted. + - `canister_state_bytes` (`nat`): The total size of the state in bytes currently taken by canisters on this subnet. This is a current value, not a counter. Recomputing it is expensive, so it is refreshed only every 10 blocks, at heights that are multiples of 10, and reads 0 until the first refresh after this subnet was created. + - `consumed_cycles_total` (`map`): The total number of cycles removed from circulation on this subnet since this subnet was created. Besides the cycles charged to the canisters currently on this subnet, this includes the cycles charged to canisters that have since been deleted, and the cycles consumed on behalf of the subnet itself rather than charged to any individual canister. Cycles that are charged in advance and later refunded are excluded once the refund is accounted for, so this value can also decrease. It's a map of two values, a low part of type `nat` and a high part of type `opt nat`. + - `update_transactions_total` (`nat`): The total number of transactions processed on this subnet since this subnet was created, i.e., the total number of messages executed in the replicated mode. The value is monotonically non-decreasing. :::note diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index b741583e..bd330d8b 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -803,7 +803,11 @@ Given a subnet ID as input, this method returns a record of subnet-wide metrics All fields except `block_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. -In the following, *the subnet* refers to the subnet identified by the `subnet_id` argument. The fields returned are: +In the following, *the subnet* refers to the subnet identified by the `subnet_id` argument. + +Only `block_height` describes the block in whose execution the call is processed. The other four fields are aggregates that the subnet refreshes at block boundaries, so they describe the subnet as of an earlier block. They are not all refreshed at the same rate, so they need not be mutually consistent, and none of them should be read as a snapshot taken at `block_height`. + +The fields returned are: - `block_height` (`nat`): the current block height of the subnet, i.e., the height of the block in whose execution this call is processed. @@ -811,15 +815,15 @@ In the following, *the subnet* refers to the subnet identified by the `subnet_id The value is monotonically non-decreasing for a given subnet. -- `num_canisters` (`nat`): the number of canisters currently on the subnet. This is a current value, not a counter, so it decreases when canisters are deleted. +- `num_canisters` (`nat`): the number of canisters on the subnet. This is a current value, not a counter, so it decreases when canisters are deleted. -- `canister_state_bytes` (`nat`): the total size in bytes of the state currently taken by canisters on the subnet. This is a current value, not a counter. +- `canister_state_bytes` (`nat`): the total size in bytes of the state taken by canisters on the subnet. This is a current value, not a counter. Recomputing it is expensive, so it is refreshed only every 10 blocks, at heights that are multiples of 10, and can therefore be up to 10 blocks staler than the other fields. It reads 0 until the first refresh after the subnet was created. -- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on the subnet by all current and deleted canisters. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. +- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on the subnet. Besides the cycles charged to the canisters currently on the subnet, this includes the cycles charged to canisters that have since been deleted, and the cycles consumed on behalf of the subnet itself rather than charged to any individual canister. Cycles that are charged in advance and later refunded are excluded once the refund is accounted for, so this value can also decrease. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. -- `update_transactions_total` (`nat`): the total number of transactions processed on the subnet, i.e., the total number of messages executed in the replicated mode. +- `update_transactions_total` (`nat`): the total number of transactions processed on the subnet, i.e., the total number of messages executed in the replicated mode. The value is monotonically non-decreasing for a given subnet. -The counter fields `consumed_cycles_total` and `update_transactions_total` accumulate since the subnet was created, or since the respective metric was introduced for subnets that predate it. +`consumed_cycles_total` and `update_transactions_total` cover the whole lifetime of the subnet, or the period since the respective metric was introduced for subnets that predate it. ### IC method `subnet_info` {#ic-subnet_info} diff --git a/docs/references/management-canister.md b/docs/references/management-canister.md index 7c0d54f1..6258b3a5 100644 --- a/docs/references/management-canister.md +++ b/docs/references/management-canister.md @@ -578,12 +578,14 @@ Returns subnet-wide metrics for a given subnet, which does not have to be the su - `subnet_id` (`principal`): any subnet - **Returns:** - `block_height` (`nat`): the target subnet's current block height, i.e. the height of the block in whose execution the call is processed - - `num_canisters` (`nat`): canisters currently on the subnet - - `canister_state_bytes` (`nat`): current total size of canister state in bytes + - `num_canisters` (`nat`): canisters on the subnet + - `canister_state_bytes` (`nat`): total size of canister state in bytes - `consumed_cycles_total` (`nat`): total cycles removed from circulation on the subnet - `update_transactions_total` (`nat`): total transactions processed on the subnet -`consumed_cycles_total` and `update_transactions_total` are counters; `num_canisters` and `canister_state_bytes` are current values. +Only `block_height` is as of the block that processes the call. The other four fields are aggregates refreshed at block boundaries, so they describe an earlier block, and they are not refreshed in lockstep with each other. `canister_state_bytes` is the stalest: it is recomputed only every 10 blocks, at heights that are multiples of 10, so it can be up to 10 blocks behind the others, and it reads 0 until the first recomputation after the subnet was created. + +`update_transactions_total` only ever grows. `consumed_cycles_total` covers deleted canisters and cycles consumed by the subnet itself, and it nets out refunds of cycles charged in advance, so it can decrease. `num_canisters` and `canister_state_bytes` are current values, not counters. ### `subnet_info` diff --git a/public/references/ic.did b/public/references/ic.did index 7213ce3f..79746d02 100644 --- a/public/references/ic.did +++ b/public/references/ic.did @@ -451,18 +451,31 @@ type subnet_metrics_args = record { subnet_id : principal; }; +// Only `block_height` describes the block in whose execution the call is +// processed. The other four fields are aggregates refreshed at block +// boundaries, so they describe the subnet as of an earlier block, and they are +// not all refreshed at the same rate; see the individual fields. type subnet_metrics_result = record { // Current block height of the subnet, i.e. the height of the block in - // whose execution this call is processed. + // whose execution this call is processed. Monotonically non-decreasing for + // a given subnet; the heights of different subnets are unrelated. block_height : nat; - // Current number of canisters on the subnet. + // Number of canisters on the subnet. A current value, not a counter. num_canisters : nat; - // Current total size in bytes of the state taken by canisters on the subnet. + // Total size in bytes of the state taken by canisters on the subnet. A + // current value, not a counter. Recomputing it is expensive, so it is + // refreshed only every 10 blocks, at heights that are multiples of 10, and + // reads 0 until the first refresh after the subnet was created. canister_state_bytes : nat; - // Total cycles removed from circulation on the subnet by all current and - // deleted canisters. + // Total cycles removed from circulation on the subnet: the cycles charged + // to the canisters currently on the subnet, plus those charged to canisters + // that have since been deleted, plus those consumed on behalf of the subnet + // itself. Refunds of cycles charged in advance are netted out, so this + // value can also decrease. consumed_cycles_total : nat; - // Total number of transactions processed on the subnet. + // Total number of transactions processed on the subnet, i.e. the total + // number of messages executed in the replicated mode. Monotonically + // non-decreasing. update_transactions_total : nat; }; From b81b26c58786932584c9ea329d131c9949df9c19 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Mon, 14 Sep 2026 12:49:50 +0000 Subject: [PATCH 09/11] spec: drop burned_cycles comparison from subnet_metrics --- docs/references/ic-interface-spec/management-canister.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index bd330d8b..1526be68 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -819,7 +819,7 @@ The fields returned are: - `canister_state_bytes` (`nat`): the total size in bytes of the state taken by canisters on the subnet. This is a current value, not a counter. Recomputing it is expensive, so it is refreshed only every 10 blocks, at heights that are multiples of 10, and can therefore be up to 10 blocks staler than the other fields. It reads 0 until the first refresh after the subnet was created. -- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on the subnet. Besides the cycles charged to the canisters currently on the subnet, this includes the cycles charged to canisters that have since been deleted, and the cycles consumed on behalf of the subnet itself rather than charged to any individual canister. Cycles that are charged in advance and later refunded are excluded once the refund is accounted for, so this value can also decrease. Note that this aggregate is not the same quantity as the `burned_cycles` field of [`canister_metrics`](#ic-canister_metrics), which only reports cycles a canister burned explicitly via `ic0.cycles_burn`. +- `consumed_cycles_total` (`nat`): the total number of cycles removed from circulation on the subnet. Besides the cycles charged to the canisters currently on the subnet, this includes the cycles charged to canisters that have since been deleted, and the cycles consumed on behalf of the subnet itself rather than charged to any individual canister. Cycles that are charged in advance and later refunded are excluded once the refund is accounted for, so this value can also decrease. - `update_transactions_total` (`nat`): the total number of transactions processed on the subnet, i.e., the total number of messages executed in the replicated mode. The value is monotonically non-decreasing for a given subnet. From 2a94ddb387c6b3c8dabd2c7c66ed570e8bb70203 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Thu, 17 Sep 2026 09:58:49 +0000 Subject: [PATCH 10/11] spec: add million_round_instructions_total to subnet_metrics Documents dfinity/ic#11587, which adds a sixth field to the endpoint this branch specifies. It reports the total instructions the subnet accounted for across the execution phases of all rounds, in units of one million and rounded up, and unlike the four aggregates it has no path under `/subnet//metrics` in the certified state tree. Co-Authored-By: Claude Opus 5 (1M context) --- .../ic-interface-spec/management-canister.md | 8 +++++--- docs/references/management-canister.md | 9 ++++++--- public/references/ic.did | 11 ++++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 2b2433f8..d0a0af40 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -861,11 +861,11 @@ The subnet metrics management canister API is considered EXPERIMENTAL. Canister Given a subnet ID as input, this method returns a record of subnet-wide metrics describing that subnet's resource usage and performance. -All fields except `block_height` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. +The fields `num_canisters`, `canister_state_bytes`, `consumed_cycles_total`, and `update_transactions_total` report the same quantities that the certified state tree exposes at the path `/subnet//metrics` (see [Subnet information](./index.md#state-tree-subnet)). This method makes them available to canisters, which cannot read the state tree. The fields `block_height` and `million_round_instructions_total` have no path in the state tree and are only available through this method. In the following, *the subnet* refers to the subnet identified by the `subnet_id` argument. -Only `block_height` describes the block in whose execution the call is processed. The other four fields are aggregates that the subnet refreshes at block boundaries, so they describe the subnet as of an earlier block. They are not all refreshed at the same rate, so they need not be mutually consistent, and none of them should be read as a snapshot taken at `block_height`. +Only `block_height` describes the block in whose execution the call is processed. The other five fields are aggregates that the subnet refreshes at block boundaries, so they describe the subnet as of an earlier block. They are not all refreshed at the same rate, so they need not be mutually consistent, and none of them should be read as a snapshot taken at `block_height`. The fields returned are: @@ -883,7 +883,9 @@ The fields returned are: - `update_transactions_total` (`nat`): the total number of transactions processed on the subnet, i.e., the total number of messages executed in the replicated mode. The value is monotonically non-decreasing for a given subnet. -`consumed_cycles_total` and `update_transactions_total` cover the whole lifetime of the subnet, or the period since the respective metric was introduced for subnets that predate it. +- `million_round_instructions_total` (`nat`): the total number of instructions the subnet accounted for across the execution phases of all rounds, in units of one million and rounded up, so a value of `42` means 42 million instructions. Besides the executed Wasm instructions this also covers the fixed per-execution and per-canister overheads charged by the scheduler, and the charges for work performed outside of Wasm execution, such as compilation, chunk assembly, and snapshot operations. It is therefore not a Wasm instruction meter. The value is monotonically non-decreasing for a given subnet. + +`consumed_cycles_total`, `update_transactions_total`, and `million_round_instructions_total` cover the whole lifetime of the subnet, or the period since the respective metric was introduced for subnets that predate it. ### IC method `subnet_info` {#ic-subnet_info} diff --git a/docs/references/management-canister.md b/docs/references/management-canister.md index 1d5528ed..89a8140b 100644 --- a/docs/references/management-canister.md +++ b/docs/references/management-canister.md @@ -593,7 +593,7 @@ Returns a time series of node metrics for a given subnet. Returns up to 60 times > This API is **experimental** and may change in a non-backward-compatible way. -Returns subnet-wide metrics for a given subnet, which does not have to be the subnet hosting the caller. Every field except `block_height` reports the same quantity that the certified state tree exposes at `/subnet//metrics`; this method makes those quantities available to canisters, which cannot read the state tree. +Returns subnet-wide metrics for a given subnet, which does not have to be the subnet hosting the caller. The four aggregates (`num_canisters`, `canister_state_bytes`, `consumed_cycles_total`, and `update_transactions_total`) report the same quantities that the certified state tree exposes at `/subnet//metrics`; this method makes them available to canisters, which cannot read the state tree. `block_height` and `million_round_instructions_total` have no path in the state tree and are only available here. - **Caller:** Canisters only - **Parameters:** @@ -604,10 +604,13 @@ Returns subnet-wide metrics for a given subnet, which does not have to be the su - `canister_state_bytes` (`nat`): total size of canister state in bytes - `consumed_cycles_total` (`nat`): total cycles removed from circulation on the subnet - `update_transactions_total` (`nat`): total transactions processed on the subnet + - `million_round_instructions_total` (`nat`): total instructions the subnet accounted for across the execution phases of all rounds, in units of one million and rounded up -Only `block_height` is as of the block that processes the call. The other four fields are aggregates refreshed at block boundaries, so they describe an earlier block, and they are not refreshed in lockstep with each other. `canister_state_bytes` is the stalest: it is recomputed only every 10 blocks, at heights that are multiples of 10, so it can be up to 10 blocks behind the others, and it reads 0 until the first recomputation after the subnet was created. +Only `block_height` is as of the block that processes the call. The other five fields are aggregates refreshed at block boundaries, so they describe an earlier block, and they are not refreshed in lockstep with each other. `canister_state_bytes` is the stalest: it is recomputed only every 10 blocks, at heights that are multiples of 10, so it can be up to 10 blocks behind the others, and it reads 0 until the first recomputation after the subnet was created. -`update_transactions_total` only ever grows. `consumed_cycles_total` covers deleted canisters and cycles consumed by the subnet itself, and it nets out refunds of cycles charged in advance, so it can decrease. `num_canisters` and `canister_state_bytes` are current values, not counters. +`update_transactions_total` and `million_round_instructions_total` only ever grow. `consumed_cycles_total` covers deleted canisters and cycles consumed by the subnet itself, and it nets out refunds of cycles charged in advance, so it can decrease. `num_canisters` and `canister_state_bytes` are current values, not counters. + +`million_round_instructions_total` counts the executed Wasm instructions plus the scheduler's per-execution and per-canister overheads and the charges for work outside Wasm execution (compilation, chunk assembly, snapshots), so it is not a Wasm instruction meter. Like the other counters, it covers the subnet's whole lifetime, or the period since the metric was introduced for subnets that predate it. ### `subnet_info` diff --git a/public/references/ic.did b/public/references/ic.did index 33b8f9cb..63d94ff3 100644 --- a/public/references/ic.did +++ b/public/references/ic.did @@ -498,7 +498,7 @@ type subnet_metrics_args = record { }; // Only `block_height` describes the block in whose execution the call is -// processed. The other four fields are aggregates refreshed at block +// processed. The other five fields are aggregates refreshed at block // boundaries, so they describe the subnet as of an earlier block, and they are // not all refreshed at the same rate; see the individual fields. type subnet_metrics_result = record { @@ -523,6 +523,15 @@ type subnet_metrics_result = record { // number of messages executed in the replicated mode. Monotonically // non-decreasing. update_transactions_total : nat; + // Total instructions the subnet accounted for across the execution phases + // of all rounds, in units of one million and rounded up: a value of 42 + // means 42 million instructions. Besides the executed Wasm instructions it + // covers the fixed per-execution and per-canister overheads charged by the + // scheduler and the charges for work performed outside of Wasm execution, + // so it is not a Wasm instruction meter. Monotonically non-decreasing. + // Unlike the four fields above, it has no counterpart under + // `/subnet//metrics` in the certified state tree. + million_round_instructions_total : nat; }; type subnet_info_args = record { From bf13465220eacc9587428943ea161f03feeae6f6 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Thu, 17 Sep 2026 10:32:18 +0000 Subject: [PATCH 11/11] spec: merge the subnet_metrics changelog bullets into one Co-Authored-By: Claude Opus 5 (1M context) --- docs/references/ic-interface-spec/changelog.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index f2bdf4e5..20b6cddf 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -12,15 +12,15 @@ sidebar: * New management canister endpoint `subnet_metrics` returning subnet-wide metrics for a given subnet: the current block height, the number of canisters, the total canister state size, the total cycles consumed, the total number of processed transactions, and - the total number of instructions accounted for across all rounds. The four aggregates - were previously only readable by external users via the certified state tree path - `/subnet//metrics`; the block height and the instruction total have no path - there. The API is EXPERIMENTAL. -* The instruction total, `million_round_instructions_total`, is reported in units of one - million and rounded up. Besides the executed Wasm instructions it covers the fixed - per-execution and per-canister overheads charged by the scheduler and the charges for - work performed outside of Wasm execution, so it is not a Wasm instruction meter, and its - counter starts when a subnet's replica begins tracking it rather than at subnet creation. + the total number of instructions accounted for across all rounds + (`million_round_instructions_total`), in units of one million and rounded up. The four + aggregates were previously only readable by external users via the certified state tree + path `/subnet//metrics`; the block height and the instruction total have no + path there. Besides the executed Wasm instructions, the instruction total covers the + fixed per-execution and per-canister overheads charged by the scheduler and the charges + for work performed outside of Wasm execution, so it is not a Wasm instruction meter, and + its counter starts when a subnet's replica begins tracking it rather than at subnet + creation. The API is EXPERIMENTAL. ### 0.68.0 (2026-09-14) {$0_68_0} * New management canister method `flexible_http_request`, a variant of `http_request` in which a committee