🥷 Try it live — no local setup. ICP Ninja is a web-based IDE that builds and deploys this project to the mainnet for free, right in your browser. Click the badge above, or hit Deploy if you're already in Ninja. To build and run it locally instead, follow the steps below.
This example demonstrates how a canister can read its own query statistics using the management canister's canister_status endpoint. It retrieves metrics such as the total number of query calls, instructions executed, and payload bytes.
Query stats are aggregated with a 2-epoch delay, not updated per call:
- Each epoch is 60 blocks on local PocketIC (vs 600 on mainnet)
- Blocks advance every ~100ms with auto-progress enabled
- Stats for epoch N are only committed once 2/3+ of nodes have submitted records for epoch N+1
Only query calls are tracked — calls made without --query go through consensus as update calls and are not counted in query_stats.num_calls_total.
Two things are required for stats to appear locally:
- Use
--query—icp canister callmakes update calls by default; only query calls are tracked inquery_stats - Make 13+ calls per round — PocketIC simulates a 13-node subnet and uses integer division (
num_calls / 13); fewer than 13 calls round to zero
bash test-stats.sh makes 13 calls every 3 seconds for up to 30 seconds.
- Node.js
- icp-cli:
npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm
git clone https://github.com/dfinity/examples
cd examples/rust/query_statsFast test (verifies API shape; stats may show 0 due to aggregation delay):
icp network start -d
icp deploy
bash test.sh
icp network stopFull demonstration (generates load, polls until non-zero stats appear):
icp network start -d
icp deploy
bash test-stats.sh
icp network stopRefer to the security best practices for information on security and best practices for your ICP app.