Unexplained multi-billion-cycle drain, zero query traffic, zero logged activity, canister has no real users yet

Canister ID available privately on request.

Happy to share with anyone from
the DFINITY team who wants to actually investigate.
dfx: 0.32.0 (deprecated, aware — migrating to icp-cli is on our list)
moc: 1.3.0

The precise measurement

Two dfx canister status calls, bracketed with date immediately before each:

Mon Aug  3 00:17:20 CEST 2026 → Balance: 1,672,802,214,952 cycles
Mon Aug  3 00:21:20 CEST 2026 → Balance: 1,663,976,997,344 cycles

Exactly 240 seconds apart. Drop: 8,825,217,608 cycles (~8.83B).
That’s ~36.77M cycles/sec sustained — the canister’s own reported
“Idle cycles burned per day” is 7,758,974,478 (~89,803 cycles/sec),
so this is ~409x the canister’s own idle rate. Extrapolated, ~3.18T/day
if sustained.

Across the same window:

  • Number of queries: unchanged (3,328 → 3,328)
  • Instructions spent in queries: unchanged (102,018,293 → 102,018,293)
  • Memory Size: unchanged (269,882,709 bytes → 269,882,709 bytes)
  • Reserved: 0 in every check, no change to freezing threshold behavior

This isn’t a one-off: the same disproportionate-loss pattern showed up
repeatedly over several hours tonight, at varying magnitudes (from ~150B
cycles across ~30 minutes up to ~2-3T described as “overnight” before we
started precise bracketed measurement).

What we’ve already ruled out, with evidence (please don’t suggest these)

  • Not query trafficdfx canister status’s own query counters are
    byte-for-byte identical across every measured window where cycles still
    dropped.
  • Not memory/storage growthMemory Size identical across every check.
  • Not any code path gated on a real user profile — confirmed via an
    admin-authenticated get_network_stats() call that total_vaults = 0;
    we have never had a real user complete onboarding. Every function in our
    source that could spend meaningful cycles (threshold-key signing calls,
    a DEX-swap fallback chain, a fund-transfer relay) is gated behind an
    existing profile lookup that fails cheaply with zero profiles present —
    verified by reading the source, not inferred.
  • Not threshold signing (vetKD) — we added explicit Debug.print logging
    to every vetkd_public_key/vetkd_encrypted_key call site in our codebase
    (3 total). dfx canister logs shows zero entries from any of them, before
    or after deploying that logging.
  • Not heartbeat misfiring — added an unconditional tick counter
    (incremented on every heartbeat() invocation, before any internal gating)
    plus a query exposing the last-gated-run timestamp. Confirmed the
    intentional once-per-24h gate is holding correctly: tick count climbs at
    IC’s normal per-round cadence, but the gated (expensive) body’s timestamp
    stays frozen between real invocations, exactly as designed.
  • Not an HTTP outcall — the one function in our canister that performs an
    HTTP outcall (a support-ticket notification) is now both logged and rate
    limited; logs confirm it has never fired.
  • Not a WASM install/upgrade tail cost — measurement windows were taken
    well after any deploy completed; no deploy occurred during either measured
    interval.
  • Previously-real bugs, now fixed, confirmed NOT the live cause given zero
    profiles exist
    : (1) a public method with no caller authentication that
    let anyone trigger a real threshold-signing call against a caller-supplied
    target principal, now capped; (2) an HTTP-outcall-triggering method
    reachable by any non-anonymous principal with no rate limit, now capped;
    (3) a fund-relay method that moved the canister’s own ledger holdings to a
    caller-specified destination with only an “isn’t anonymous” check, now
    admin-gated. All three are fixed and deployed; the drain in the
    precisely-measured window above happened on the fully-patched build.

What we’re asking

  1. Is there a known subnet-level phenomenon — neighboring canister burn
    spikes, replicated-execution surcharges, post-upgrade compute/storage
    reservation recalculation — that could produce sustained multi-billion
    cycle losses with zero corresponding query/update counters on the
    affected canister itself?

  2. dfx canister status only exposes query-call statistics, not update-call
    counts or their individual costs. Is there any tooling or replica-level
    diagnostic (subnet dashboard, extended canister_status fields, anything)
    that would show us actual per-message cycle accounting for update calls
    and heartbeat executions, beyond what dfx canister logs captures?

  3. Are there known dfx 0.32.0 / replica-side issues around cycle-balance
    reporting that could produce a “phantom” drop not corresponding to real
    consumption?

  4. Would a DFINITY engineer be able to pull replicated execution history for
    this specific canister ID for the timestamps above?

    Happy to provide additional logs, re-enable it for live
    observation, or share more of our Motoko source if useful.

You are using a heartbeat. You pay for the replica loading your canister every round. Using heartbeat basically cost upwards of hundreds to thousands a month. Don’t use heartbeat. Use a timer and fire it far less often. You are basically reserving a fraction of one of 4 cores on a $20k/ month subnet when you use heartbeat,

https://mops.one/timer-tool

This will preserve timers Across upgrades if configured properly. Set it to fire once every 24 hours and you’ll save Ts of cycles.

It did fix the insane burn. Using timers now . Thanks and appreciate your help