Skip to content

A Polkadot Product has four places to keep data, and choosing the wrong one is a common early mistake — most often, putting bulk data in a contract. Each option trades off cost, persistence, size, and who can read it. This page is a decision guide: match the data to the layer built for it.

LayerBest forPersistenceSizeReadable by
Contract storageEnforced shared state and logicPermanentSmall, structuredAnyone, through contract methods
Cloud storage (Bulletin)Files and content blobs~2 weeks, renewableLargeAnyone with the CID
Statement storeReal-time signalingSeconds (ephemeral)Up to 512 bytesSubscribers to your Product
Local storagePer-device stateUntil clearedSmallOnly this device

Use a smart contract when data is logic that must be enforced for everyone: ownership records, a leaderboard's rules, an escrow's state, a registry. Contract storage is permanent and its rules are trustless, but on-chain storage is expensive per byte and every write is a transaction.

Do not put bulk data in a contract — file contents, images, long text, or anything that grows. Store the bytes in cloud storage and keep only the CID (a short content hash) in the contract if the contract needs to reference them. This keeps the contract small and cheap while the heavy data lives in the layer built for it.

Use cloud storage for content that outlives a session: profile photos, uploads, published posts, snapshots of app state. You upload bytes and get back a CID; anyone with the CID can fetch and verify the bytes.

The key tradeoff is retention. Stored data is kept for about two weeks by default and must be renewed to persist beyond that. Renewal works from a CID. A chunked upload is renewed chunk by chunk, and its manifest CID lists the chunk CIDs. Plan for renewal from the start; see Store Data on Chain for how to renew, and Deploy Your App for keeping a deployed app available.

Use the statement store for real-time state between users: presence, typing indicators, cursors, and announcing where a fresh snapshot lives. Statements are signed, capped at 512 bytes, and expire in seconds. They are signaling, not storage — pair them with cloud storage when the content needs to survive.

Use local storage for state that belongs to one device: preferences, drafts, and cached values. It is private to the device and instant to read, but it is not shared, not durable across devices, and not a source of truth.

Many Products combine layers rather than choosing one:

  • The statement store announces that something changed (a small, live signal).
  • Cloud storage holds the full content, addressed by CID.
  • A contract or the announcement carries the CID so others know where to look.
  • Local storage renders instantly from the device's last known state while the rest loads.

The Shared Todo App tutorial builds exactly this composition end to end.

Last updated: