I am trying to understand how temporary heap allocations behave under Motoko’s enhanced orthogonal persistence and incremental garbage collector.
Consider this simplified architecture:
```
import List “mo:core/List”;
import Map “mo:core/Map”;
import Principal “mo:core/Principal”;
persistent actor {
type Record = {
id : Nat;
owner : Principal;
value : Text;
};
type Audit = {
recordId : Nat;
action : Text;
};
// Persistent application state
let records = Map.empty<Nat, Record>();
let recordsByOwner = Map.empty<Principal, List.List>();
let auditsByRecord = Map.empty<Nat, List.List>();
public shared func processRecords() : async Nat {
// A helper or third-party library creates a large temporary
// array/list while processing the persistent maps.
let temporaryWorkingSet =
SomeLibrary.buildWorkingSet(records);
// Only a small result is returned.
let result = SomeLibrary.summarize(temporaryWorkingSet);
result
};
}
```
Assume:
- `processRecords` is an update call.
- It contains no `await`.
- The temporary working set is never assigned to an actor field.
- No map, list, cache or other object retains it.
- The update completes successfully and returns a small result.
- The temporary allocation causes Wasm memory to grow temporarily from 100 MiB to 1 GiB.
- After the response, only 100 MiB of application data remains logically live.
My expected lifecycle is:
```
Before update:
Live data: approximately 100 MiB
Allocated Wasm memory: approximately 100 MiB
During update:
Live data: approximately 100 MiB
Temporary working set: approximately 924 MiB
Allocated Wasm memory: approximately 1 GiB
After response:
Live data: approximately 100 MiB
Unreachable garbage: approximately 924 MiB
After GC:
Live data: approximately 100 MiB
Reclaimed/reusable heap: approximately 924 MiB
```
I would appreciate clarification on the following:
1. After the successful update, is the unreachable 924 MiB initially committed as part of the canister’s Wasm memory until GC processes it?
2. After a complete incremental GC, does `canister_status.memory_size` decrease toward 100 MiB, or does it normally remain near the 1 GiB high-water mark?
3. If `memory_size` remains near 1 GiB, is the canister charged storage cycles for the complete 1 GiB even though only approximately 100 MiB is logically live?
4. Does GC merely make the reclaimed 924 MiB reusable for future allocations, without returning those Wasm pages to the IC?
5. Are the Wasm instructions executed by Motoko’s incremental GC charged to the canister? If GC work is deferred, is that cost assigned to later update calls?
6. Does `__motoko_gc_trigger()` only advance GC and reclaim internal heap blocks, or can it also reduce the charged `memory_size`?
7. Is there any supported way to shrink an EOP canister’s allocated Wasm memory after an accidental temporary spike?
8. If the update traps instead of succeeding, is the memory growth rolled back while the executed instructions are still charged?
9. Would the behaviour be different for a query call, where temporary heap changes are not committed?
10. Which metrics are recommended for distinguishing live data from allocated high-water memory?
```
rts_heap_size
rts_memory_size
rts_total_allocation
rts_reclaimed
rts_max_live_size
canister_status.memory_size
```
My main question is:
> Under EOP, can one successful update that temporarily allocates 1 GiB permanently raise the canister’s storage billing and reported `memory_size`, even after almost all of that allocation becomes unreachable and is reclaimed by GC?
Relevant documentation:
- [Enhanced orthogonal persistence](https://docs.internetcomputer.org/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced/)
- [Motoko garbage collector options](https://docs.internetcomputer.org/guides/canister-management/optimization/#motoko-garbage-collector-options)
- [GC recommendations and `__motoko_gc_trigger()`](https://docs.internetcomputer.org/languages/motoko/reference/changelog/#0104-2024-01-10)
- [ICP cycles and storage charging](https://docs.internetcomputer.org/concepts/cycles/)
- [Cycle-cost table](https://docs.internetcomputer.org/references/cycle-costs/)
- [Collecting Garbage on the Blockchain](https://internetcomputer.org/whitepapers/Collecting%20Garbage%20on%20the%20Blockchain.pdf)