Skip to content

docs: cycle cost docs follow-up — ICP formula, worked example, instruction profiling, cost traps #274

Description

@marc0olo

Follow-up to #272.

After reviewing the cycle cost documentation restructured in #272, the following gaps remain. All are additive changes to existing pages — no new files, no structural changes, no sidebar edits.

Gap 1: The "how much ICP to buy" formula is never written out

The cycle→XDR→ICP conversion chain is documented in pieces but never assembled. A developer cannot answer "I need 5T cycles — how much ICP do I buy?" without reading three separate sections.

Proposed fix: Add a concise formula + worked example in docs/guides/canister-management/cycles-management.mdx immediately after the budget guidance sentence:

icp_needed = (cycles_needed / 1_000_000_000_000) / (xdr_permyriad_per_icp / 10_000)

Example: need 5T cycles, CMC returns xdr_permyriad_per_icp = 19482 → 1 ICP = 1.9482 XDR → 5 / 1.9482 ≈ 2.57 ICP to purchase.

Gap 2: No worked cost estimation example

All per-operation numbers exist in docs/references/cycle-costs.md but there is no example that combines them. A developer with a canister using HTTPS outcalls + threshold signing + storage + compute cannot find a single synthesized monthly cost estimate.

Proposed fix: Add a "Worked example" section to docs/references/cycle-costs.md — e.g. a canister making 1,000 HTTPS outcalls/day, 10 ECDSA signatures/day, storing 500 MiB, executing 100M instructions/call × 50 calls/day — that walks through each cost line and arrives at a monthly cycle total and ICP purchase estimate.

Gap 3: Instruction count is impossible to estimate before deployment

The docs state "1B instructions = 1B cycles" but do not explain how to measure the instruction count of a canister call. performance_counter() (the Wasm instruction counter available via ic0.performance_counter(0)) is not mentioned anywhere.

Proposed fix: Add a "Measuring instruction counts" paragraph to docs/guides/canister-management/optimization.md showing ic0.performance_counter(0) in Rust (ic_cdk::api::performance_counter(0)) and the equivalent in Motoko (Prim.performanceCounter(0)), with a note that sampling before/after a block gives the instruction cost of that block.

Gap 4: HTTPS outcall max_response_bytes default is a silent cost trap

If max_response_bytes is not set it defaults to 2 MiB. On a 34-node subnet: 2_097_152 × 27_200 cycles/byte ≈ 57B cycles per call regardless of actual response size — even for a 200-byte response. This is not flagged as dangerous anywhere in the cost docs.

Proposed fix: Add a warning callout in the HTTPS outcalls section of docs/references/cycle-costs.md:

Always set max_response_bytes explicitly. The default (2 MiB) charges for the full reserved size even if the actual response is 1 KB. On a 34-node subnet that is approximately 57B cycles per call.

Gap 5: Freezing threshold and burn rate are never connected

The cycles-management guide recommends "90 days for production" but never explains that this requires estimated_daily_burn × threshold_days in cycle reserves. A developer setting a 90-day threshold on a canister burning 5B cycles/day needs 450B cycles reserved — this is non-obvious.

Proposed fix: Add a formula immediately below the freezing threshold section in docs/guides/canister-management/cycles-management.mdx:

required_balance ≥ estimated_daily_burn × threshold_days

Example: 5B cycles/day × 90 days = 450B cycles minimum balance before the threshold triggers.

Gap 6: Pricing calculator is mentioned without explanation

https://3d5wy-5aaaa-aaaag-qkhsq-cai.icp0.io/ is linked once with no description of inputs or how to interpret results. It should either get a one-sentence description or be promoted more visibly from cycles-management.mdx.


Files to change

File Changes
docs/references/cycle-costs.md Gap 2 (worked example) + Gap 4 (max_response_bytes warning)
docs/guides/canister-management/cycles-management.mdx Gap 1 (ICP formula) + Gap 5 (burn rate formula) + Gap 6 (calculator description)
docs/guides/canister-management/optimization.md Gap 3 (performance_counter guidance)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions