🥷 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 ic.canister_status. 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
- Minimum wait: 2 epochs × 60 blocks × 100ms ≈ 12 seconds;
bash test-stats.shpolls up to 30 seconds to accommodate slower machines
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.
Three 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 - Keep making queries continuously —
set_epoch_from_heightis only invoked during query execution; queries must keep running across epoch boundaries to flush accumulated stats into the payload pipeline
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 - ic-mops:
npm install -g ic-mops
git clone https://github.com/dfinity/examples
cd examples/motoko/query_statsFast test (verifies API shape; stats show 0 due to aggregation delay):
icp network start -d
icp deploy
bash test.sh
icp network stopFull demonstration (generates load, waits ~20s, verifies non-zero stats):
icp network start -d
icp deploy
bash test-stats.sh
icp network stopbash test-stats.sh calls load() 13 times with --query every 3 seconds (up to 30 seconds total), verifying non-zero stats once they appear.
Refer to the security best practices for information on security and best practices for your ICP app.