docs: data persistence guide#18
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a comprehensive “Data Persistence” guide explaining durable canister state patterns across Motoko (persistent actors) and Rust (ic-stable-structures), plus upgrade-safety pitfalls and idempotency techniques.
Changes:
- Documented Motoko
persistent actorpersistence rules, transient state, and schema evolution do/don’ts. - Documented Rust stable structures usage with
MemoryManagerpartitioning and customStorableimplementations (CBOR viaciborium). - Added guidance on avoiding
pre_upgradeheap-serialization and introduced idempotency patterns + a CLI upgrade verification sequence.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Review: Data PersistenceMust fix1. Intro misrepresents Motoko's heap behavior 2. "data is unrecoverable" overstated for Motoko schema evolution
A trapped Motoko schema upgrade leaves the canister running on the old Wasm — data is intact and you can recover by deploying a compatible type. "Unrecoverable" is wrong. Rephrase to: "the upgrade traps; the canister continues running on the old code with data intact, but cannot be upgraded until the type conflict is resolved." 3.
This is wrong. 4. "no way to recover" from trapped 5. "Multiple stable structures" snippet is not self-contained 6. CLI persistence test uses Motoko method names against a Rust canister 7. Idempotency snippets missing imports
Both snippets need full imports or an explicit note that they must be merged into the persistent actor from the Motoko section. Verified
|
- Rephrase intro to correctly distinguish heap behavior: wiped on upgrade in Rust, automatically preserved in Motoko persistent actor - Fix schema evolution wording: upgrade traps leave canister on old Wasm with data intact; not "unrecoverable" - Fix Bounded vs Unbounded comment: exceeding max_size traps writes, does not break deserialization of existing data - Mention skip_pre_upgrade as emergency recovery option for trapped pre_upgrade hooks - Make "Multiple stable structures" snippet self-contained with full imports, Memory alias, and Post struct definition - Split CLI persistence test into Motoko (camelCase) and Rust (snake_case) variants to match each backend's exported method names - Add missing imports to both idempotency snippets (Map, Principal, Nat for sequence numbers; Map, Text for ID deduplication)
|
Feedback addressed:
|
Summary
persistent actorpattern: auto-persistedlet/var,transient var, schema evolution rulesStableBTreeMap,StableCell,StableLog,MemoryManager,MemoryIdpartitioning,Storableimpl with CBOR via ciboriumpre_upgradeheap serialization anti-pattern (instruction limit → trapped upgrade → bricked canister)Sync recommendation
Informed by
dfinity/portaldocs/building-apps/canister-management/storage.mdx,docs/building-apps/best-practices/storage.mdx,docs/building-apps/best-practices/idempotency.mdx— hand-written synthesis across multiple portal sources plus icskills/stable-memory.