For AI agents: Documentation index at /llms.txt

Skip to content

Cycle costs

Canisters pay for the resources they consume and operations they perform using cycles. The price of cycles is pegged to XDR (Special Drawing Rights): 1 trillion cycles = 1 XDR. USD values throughout this page use 1 XDR = $1.366430; see XDR exchange rate at the end of this page for the current rate and how to look it up programmatically.

You can use the pricing calculator to estimate the cost for your app.

AbbreviationNameIn numbersXDR valueApprox. USD value
TTrillion1_000_000_000_0001~$1.37
BBillion1_000_000_0000.001~$0.00137
MMillion1_000_0000.000001~$0.00000137
kThousand1_00010⁻⁹~$0.00000000137

Costs scale with the number of nodes in the subnet. The base cost tables below assume a 13-node application subnet. For a 34-node (fiduciary) subnet, costs scale as 34 * (cost / 13):

  • 13-node subnet: Standard application subnets. No scaling needed: costs are as listed.
  • 34-node subnet: Fiduciary subnets (higher security for financial applications). Costs are approximately 2.6× the 13-node cost.

See Subnet types for subnet-specific details.

USD values use the rate stated in the intro. Use cycle counts for precise budgeting.

OperationDescriptionWho pays13-node cycles~USD34-node cycles~USD
Query callQuery information from a canisterN/AFreeFreeFreeFree
Canister creationCreate a new canisterCreated canister500_000_000_000~$0.6831_307_692_307_692~$1.787
Compute allocation (per % per second)Reserved compute per secondCanister with allocation10_000_000~$0.000013726_153_846~$0.0000357
Update message executionPer update message executed (base fee)Target canister5_000_000~$0.000006813_076_923~$0.0000179
1B instructions executedPer 1B Wasm instructions (on top of base fee)Executing canister1_000_000_000~$0.001372_615_384_615~$0.00357
Xnet call (request + response)Inter-canister call overheadSending canister260_000~$0.00000036680_000~$0.00000093
Xnet byte transmissionPer byte in inter-canister callSending canister1_000~$0.000000001372_615~$0.0000000036
Ingress message receptionPer ingress message receivedReceiving canister1_200_000~$0.00000163_138_461~$0.0000043
Ingress byte receptionPer byte in ingress messageReceiving canister2_000~$0.00000000275_230~$0.0000000071
GiB storage per secondStorage cost per GiB per secondCanister with storage127_000~$0.000000174332_153~$0.000000454

Storage cost per GiB per month (30 days):

SubnetCycles~USD
13-node~329 billion~$0.45
34-node~861 billion~$1.18

Each update message execution is charged as a base fee plus a per-instruction fee (the Update message execution and 1B instructions executed rows in the Cost table above):

total = base_fee + per_instruction_fee * num_instructions

Current values (13-node subnet):

  • base_fee = 5_000_000 cycles (~$0.0000068 USD)
  • per_instruction_fee = 1 cycle (so 1B instructions = 1B cycles ≈ $0.00137 USD)

By default canisters are scheduled best-effort. Setting compute_allocation guarantees execution slots:

  • 1%: Scheduled every 100 rounds
  • 2%: Scheduled every 50 rounds
  • 100%: Scheduled every round

Total allocatable compute capacity per subnet is 299%. The per-second cost is 10M cycles * allocation_percent on a 13-node subnet: see the Compute allocation row in the Cost table above for exact figures.

When a canister grows its memory (via memory.grow, ic0.stable_grow(), or Wasm installation), the system moves cycles from the canister’s main balance into a reserved cycles balance to cover future storage payments.

  • If subnet usage is below 750 GiB: reservation per byte = 0 (no advance reservation).
  • If subnet usage is above 750 GiB: reservation per byte scales linearly from 0 up to 10 years of payments at subnet capacity (2 TiB).

Reserved cycles are non-transferable. Controllers can disable reservation by setting reserved_cycles_limit = 0, but opted-out canisters cannot allocate new memory when subnet usage exceeds 750 GiB.

Threshold signing and key derivation are core ICP protocol capabilities: the cryptographic operations happen entirely within the ICP network, distributed across the nodes of a designated subnet. The extra cost reflects computationally intensive threshold cryptography and cross-subnet coordination.

sign_with_ecdsa and sign_with_schnorr are charged per signature. The fee is determined by the subnet where the signing key resides, not the calling canister’s subnet. ecdsa_public_key and schnorr_public_key carry no cycle cost.

Key nameAlgorithm(s)EnvironmentSigning subnetCycles~USD
test_key_1ECDSA (secp256k1), Schnorr (bip340secp256k1, ed25519)Testing13-node (fuqsr)10_000_000_000~$0.0137
key_1ECDSA (secp256k1), Schnorr (bip340secp256k1, ed25519)Production34-node fiduciary (pzp6e)26_153_846_153~$0.0357

If the canister may be blackholed or called by other canisters, send more cycles than the listed cost: unused cycles are refunded, and this ensures calls succeed if the signing subnet grows in node count.

vetkd_derive_key is charged per key derivation. vetkd_public_key carries no cycle cost. The fee is determined by the subnet where the VetKey resides, not the calling canister’s subnet.

Key nameEnvironmentSigning subnetCycles~USD
test_key_1Testing13-node (fuqsr)10_000_000_000~$0.0137
key_1Production34-node fiduciary (pzp6e)26_153_846_153~$0.0357

If the canister may be blackholed or called by other canisters, send more cycles than the listed cost: unused cycles are refunded.

These features involve outbound calls to external networks. How many nodes take part in each call is the primary driver of the additional cost: the whole subnet for a fully replicated outcall, and fewer for the modes that reduce replication (see HTTPS outcalls below). The subsections below are ordered by pricing mechanism: HTTPS outcalls first as the base primitive, then the two RPC canisters that build on it, then the native chain integrations that use a two-tier pricing model.

Outcalls have two pricing versions, chosen per call by the pricing_version field of http_request. Version 1 prices the request and response bytes that a call reserves. Version 2 prices the resources a call actually consumes, and is also the only pricing available to flexible_http_request, which has no pricing_version field.

Rather than hard-coding either formula, read the cost at runtime: ic0.cost_http_request for version 1, ic0.cost_http_request_v2 for version 2.

Version 1 (default, deprecated). Costs scale with subnet size (n = number of nodes):

total_fee = base_fee + size_fee
base_fee = (3_000_000 + 60_000 * n) * n
size_fee = (400 * request_bytes + 800 * max_response_bytes) * n

request_bytes is the total serialized request size (URL + headers + body + transform name/context). max_response_bytes defaults to 2 MB (2,000,000 bytes, decimal) if not explicitly set by the canister, which on a 13-node subnet costs roughly 20.85 billion cycles.

Component13-node cycles~USD34-node cycles~USD
Per call (base)49_140_000~$0.0000671171_360_000~$0.000234
Per request byte5_200~$0.000000007113_600~$0.0000000186
Per reserved response byte10_400~$0.000000014227_200~$0.0000000372

Version 2 (pay-as-you-go). The price has three parts: a base fee charged when the call is accepted, a usage fee charged for each node that performs the outcall, and a delivery fee for putting the result into a block. max_response_bytes appears in none of them. It still caps the response, and because the worst-case usage that bounds the reservation is computed from it, a larger value means more of the payment is withheld while the call is in flight, but it no longer sets the price.

What a call is charged, once it settles:

n = subnet size. K = responses delivered (1 unless flexible).
base_fee = (1_000_000 + 50 * request_bytes + replication_term) * n
replication_term = 140_000 * n + 800 * n * n fully replicated
= 90_000 * n + (2_000 * n + 100_000) * min_responses otherwise
usage_fee = 50 * raw_response_bytes + 300 * roundtrip_ms
+ transform_instructions / 13
(+ 50 * n * response_bytes non-replicated and flexible only)
delivery_fee = n * (10 * n + 600) * (response_bytes (+ 181 * K flexible only))
(+ (2_000 * n + 100_000) * n * (K - min_responses) flexible only)

usage_fee is charged for each node that performs the outcall: all n of them for a fully replicated call, one for a non-replicated call, total_requests for a flexible one. The 13 dividing transform_instructions is not the node count: outcall fees are calibrated against a reference subnet size of 13, and this is the only term that carries that constant, so a node is charged the same for a transform on every subnet. response_bytes is the size after the transform. A non-replicated call (is_replicated = false) takes the otherwise branch with min_responses = 1. A flexible call that does not set replication defaults min_responses to floor(2 / 3 * n) + 1.

Component13-node cycles~USD34-node cycles~USD
Base, per fully replicated call38_417_600~$0.0000525227_283_200~$0.000311
Base, per request byte650~$0.00000000091_700~$0.0000000023
Usage, per raw response byte650~$0.00000000091_700~$0.0000000023
Usage, per millisecond of round trip3_900~$0.000000005310_200~$0.0000000139
Usage, per million transform instructions~1_000_000~$0.0000014~2_615_000~$0.0000036
Delivery, per delivered response byte9_490~$0.000000013031_960~$0.0000000437

The three usage rows are charged per node that performs the outcall, and the figures assume all n of them do and each consumes the same amount, as a fully replicated call is priced: a non-replicated call is charged them once, and a flexible call total_requests times. Which term dominates depends on the call: round-trip time is capped at 60 seconds, which is 234 million cycles on a 13-node subnet, while a transform that uses the full instruction limit costs about 5 billion and delivering a 2MB response about 19 billion.

What to attach. ic0.cost_http_request_v2 does not return the figure above. Neither how many nodes will respond nor which result they will produce is known when the call is made, and delivering the result has to be paid out of the per-node budgets, so the amount it returns reserves for the most expensive result the call could still produce. It therefore exceeds what the call settles at, and the difference is refunded.

Pass what you expect and you get a small reservation, at the cost of the outcall running within correspondingly tighter per-node limits. Pass the maxima a run could consume and you get the figure that cannot run short, which is also the most the system withholds:

ParameterMaximum
http_roundtrip_time_ms60_000, the longest the system waits for a response
raw_response_bytesmax_response_bytes, or 2_000_000 if it is unset
transformed_response_bytesthe same as raw_response_bytes, plus 1_024 bytes: the Candid encoding of a response delivered without a transform, the largest content a node can deliver. A transformed response itself is capped at max_response_bytes
transform_instructions5_000_000_000 (5 billion), the instruction limit of a query call

request_bytes and outcall_type follow from the request itself.

The four values size one budget per node; they are not four independent limits. The response size cap and the response timeout each node runs under are derived from whatever is left of that budget, so a low expectation on one input also tightens the others. Delivery of the result is paid out of what the nodes leave unspent, which means an expectation set below what the call needs can fail at delivery, after the request has already been made.

Either way, any attached surplus is refunded, so the charge follows the resources actually consumed. Those refunds arrive asynchronously: a node that never reported has its whole budget returned when the request times out, one minute after the response was delivered. A canister that reads its own balance right after an outcall will see it keep settling for a while afterwards, as further refunds arrive.

Calls to the EVM RPC canister use an HTTPS-outcall-based pricing structure with higher per-byte constants than standard HTTPS outcalls, scaled by the number of RPC services used for multi-provider consistency:

(
5_912_000
+ 60_000 * nodes_in_subnet
+ 2400 * request_size_bytes
+ 800 * max_response_size_bytes
) * nodes_in_subnet * rpc_services

Typical cost: 10^8 to 10^9 cycles (~$0.0001 to $0.001 USD). On a 34-node subnet with a 1 kB request and 1 kB response using one RPC service: ~$0.00052.

An additional 10_000_000 * nodes_in_subnet * rpc_services collateral cycles must be attached per call; these are consumed by the EVM RPC canister as a reserve for future pricing changes and are not returned to the caller. Any cycles you attach above the total minimum (formula + collateral) are returned, so it is safe to send more than needed. Start with 10_000_000_000 cycles and adjust based on observed costs. Use the requestCost query method on the EVM RPC canister to get an exact estimate before calling.

The SOL RPC canister prices each call using the standard HTTPS outcall formula plus a 10_000_000 cycles × n per-node processing fee, scaled by the number of RPC providers used:

total_fee = (
(3_000_000 + 60_000 * n) * n // base HTTP outcall fee
+ (400 * request_bytes + 800 * max_response_bytes) * n // size fee
+ 10_000_000 * n // processing fee
) * rpc_providers

n is the number of nodes in the subnet hosting the SOL RPC canister. Because each method uses a different default max_response_bytes and request serialization size, costs vary per method. As a reference point: getBalance with 3 RPC providers on a 34-node subnet costs approximately 1.7 billion cycles (~$0.0023 USD).

To get the exact cycle estimate for a specific call before attaching cycles, use the corresponding query endpoint on the SOL RPC canister: getBalanceCyclesCost, getBlockCyclesCost, getSlotCyclesCost, getTransactionCyclesCost, sendTransactionCyclesCost, and equivalents for each method.

See the Solana guide for integration examples.

The Bitcoin API uses a two-tier pricing model: a base cost that is actually charged, and a higher minimum to attach with the call. The minimum is set above the base cost to allow for future subnet growth; any cycles not consumed are refunded. bitcoin_get_utxos and bitcoin_get_block_headers add a per-instruction component on top of their base fee because the Bitcoin canister executes Wasm to process those requests. bitcoin_send_transaction has no minimum: its cost is deterministic (base fee plus a per-byte fee), and the full amount attached is charged.

Bitcoin Testnet / Regtest:

API callBase cost (cycles)Min. cycles to attach~USD (base)~USD (min. to attach)
bitcoin_get_balance4_000_00040_000_000~$0.0000055~$0.0000547
bitcoin_get_utxos20_000_000 + 0.4 × instructions4_000_000_000~$0.0000273 + inst.~$0.00547
bitcoin_get_current_fee_percentiles4_000_00040_000_000~$0.0000055~$0.0000547
bitcoin_get_block_headers20_000_000 + 0.4 × instructions4_000_000_000~$0.0000273 + inst.~$0.00547
bitcoin_send_transaction (base)2_000_000_000N/A~$0.00273N/A
bitcoin_send_transaction (per payload byte)8_000_000N/A~$0.0000109N/A
get_blockchain_info4_000_00040_000_000~$0.0000055~$0.0000547

Bitcoin Mainnet:

API callBase cost (cycles)Min. cycles to attach~USD (base)~USD (min. to attach)
bitcoin_get_balance10_000_000100_000_000~$0.0000137~$0.000137
bitcoin_get_utxos50_000_000 + 1 × instructions10_000_000_000~$0.0000683 + inst.~$0.0137
bitcoin_get_current_fee_percentiles10_000_000100_000_000~$0.0000137~$0.000137
bitcoin_get_block_headers50_000_000 + 1 × instructions10_000_000_000~$0.0000683 + inst.~$0.0137
bitcoin_send_transaction (base)5_000_000_000N/A~$0.00683N/A
bitcoin_send_transaction (per payload byte)20_000_000N/A~$0.0000273N/A
get_blockchain_info10_000_000100_000_000~$0.0000137~$0.000137

In Rust, the ic-cdk-bitcoin-canister crate handles cycle attachment automatically. In Motoko, use (with cycles = amount). See the Bitcoin guide for implementation details.

The Dogecoin integration API follows the same two-tier pricing model as the Bitcoin API. There is no testnet pricing tier: the fees below apply to Dogecoin Mainnet only.

API callBase cost (cycles)Min. cycles to attach~USD (base)~USD (min. to attach)
dogecoin_get_balance10_000_000100_000_000~$0.0000137~$0.000137
dogecoin_get_utxos50_000_000 + 1 × instructions10_000_000_000~$0.0000683 + inst.~$0.0137
dogecoin_get_current_fee_percentiles10_000_000100_000_000~$0.0000137~$0.000137
dogecoin_get_block_headers50_000_000 + 1 × instructions10_000_000_000~$0.0000683 + inst.~$0.0137
dogecoin_send_transaction (base)5_000_000_000N/A~$0.00683N/A
dogecoin_send_transaction (per payload byte)20_000_000N/A~$0.0000273N/A

dogecoin_get_utxos and dogecoin_get_block_headers add a per-instruction component because the Dogecoin canister executes Wasm to process those requests; the minimum to attach covers this variable cost. dogecoin_send_transaction has no minimum: its cost is deterministic, and the full amount attached is charged.

See the Dogecoin guide for integration patterns.

The cycle price is fixed by protocol: 1 trillion cycles = 1 XDR. This ratio is set by NNS governance and does not change with ICP token price movements.

All USD values on this page use 1 XDR = $1.366430 (May 22, 2026). Use cycle counts for precise budgeting; only the USD conversion fluctuates.

The Cycles Minting Canister (CMC) (rkp4c-7iaaa-aaaaa-aaaca-cai) calls the exchange rate canister (XRC) every 5 minutes for the current ICP/XDR rate. The CMC exposes get_icp_xdr_conversion_rate, which returns xdr_permyriad_per_icp: the number of XDR per ICP, expressed in units of 1/10000 (for example, 19482 means 1 ICP = 1.9482 XDR). This is an ICP/XDR rate; the CMC does not track XDR/USD.

Manual lookup: The IMF’s SDR valuation page is the authoritative source. The page returns HTTP 403 to automated HTTP clients and cannot be fetched programmatically.

ICP Dashboard API (unsigned, easy for scripts): Fetch the ICP/USD price and the ICP/XDR rate, then derive XDR/USD:

Terminal window
# ICP/USD (returns [[timestamp, "price_as_string"]])
GET https://ic-api.internetcomputer.org/api/v3/icp-usd-rate
# ICP/XDR in permyriad (returns [[timestamp, xdr_permyriad_per_icp]])
GET https://ic-api.internetcomputer.org/api/v3/icp-xdr-conversion-rates?limit=1
xdr_usd = icp_usd / (xdr_permyriad_per_icp / 10_000)

Example: ICP/USD = $2.67, ICP/XDR = 19482 / 10000 = 1.9482 → XDR/USD = 2.67 / 1.9482 ≈ $1.37.

The ICP Dashboard API is not certified: responses are unsigned and not verifiable by the network.

CMC metrics endpoint (Prometheus, unsigned): The CMC exposes a Prometheus metrics endpoint at https://rkp4c-7iaaa-aaaaa-aaaca-cai.raw.icp.net/metrics that includes cmc_icp_xdr_conversion_rate (current ICP/XDR) and cmc_avg_icp_xdr_conversion_rate (30-day moving average used for node provider rewards). Neither is certified. Apply the same formula to derive XDR/USD.

From canister code (certified): Call the XRC for ICP/USD as a crypto/fiat pair (1B cycles, refunded if unused), and call the CMC get_icp_xdr_conversion_rate for ICP/XDR. Derive XDR/USD = ICP_USD / (xdr_permyriad_per_icp / 10_000). See Fetch exchange rates for XRC integration code.