Skip to content

Data Storage and Locations

Version 1.0Last reviewed

Data lives inside the canisters of an engine, replicated in full on every node of that engine. There is no separate database tier and no external storage service holding a copy.

All nodes are located in Switzerland. Node placement is a configuration decision made when the engine is assembled, not a platform constraint, so an engine can be scoped to a single jurisdiction — and Swiss Subnet’s engines are.

  • Network traffic between the nodes of an engine is not today guaranteed to remain within Swiss borders. Nodes communicate over public IPv6 connectivity, and routing between them is not currently constrained to Swiss territory. Keeping that traffic inside the country is planned. The open question is the path it takes, not whether it can be read en route: node-to-node communication is authenticated and encrypted by the protocol’s peer-to-peer layer, with subnet membership held in the registry.
  • Whether a node operator can read the data depends on how the engine is placed. An engine alone on its node has its memory encrypted; an engine sharing a node with others does not yet, and that node’s operator can read canister state. See Trust and Security Model. Data residency and data confidentiality are separate properties.

Encryption of node-to-node traffic and of state on disk is handled by the protocol rather than configured per engine; the mechanisms are documented in the protocol stack overview.

Node providers are legal entities contracted under Swiss law; node machines themselves are required to be in Switzerland.

Every node holds a complete copy. At the minimum engine size of four nodes there are four copies, and correctness survives the loss of one. Replication is synchronous: a state change is not final until agreed by the engine.

The cost side, stated plainly: replication is why storage is expensive relative to conventional hosting, and why write throughput does not improve as nodes are added. See Cloud Engine.

When application code deletes data from a canister, it is removed from the engine’s live state. Deletion travels the same path as any other state change: it is submitted as a message, ordered by consensus, and executed on every node. It takes as long to delete data as it took to write it, and once the message has executed no replica serves the deleted value again.

Two mechanisms can still hold a copy afterwards, and they have different owners:

Mechanism Held by Created by
Canister snapshots The engine The canister’s controllers, on demand
Replica checkpoints Each node The protocol, periodically

Canister snapshots are the client’s own doing: a snapshot taken before a deletion still contains the deleted data until the client removes it. Up to 10 are held per canister — see Data export.

Replica checkpoints are written by the protocol as part of normal operation, and a checkpoint predating a deletion holds the deleted state until it is superseded. The retention behaviour is a protocol property, not an engine setting, and is documented in the protocol stack overview.

Neither mechanism is a route by which an application can read deleted data back: a checkpoint is not addressable from canister code, and restoring a snapshot reverts the whole canister.

When a client’s engagement ends the engine is sunset and all data on it is deleted. Node providers hold no copies outside the engine — the replicas are the only copies, and they cease to exist with the engine.

Swiss Subnet does not issue deletion confirmations. An engine is owned and controlled by the client operating it, and Swiss Subnet has no read access into canister state, so it can attest neither what an engine holds nor what it no longer holds. Evidence of deletion, where a compliance function requires it, has to come from the application.

Erasure requests under the FADP or the GDPR are the application’s responsibility. An engine is infrastructure: it executes what is deployed to it and offers no record-level erasure facility of its own.

Two routes exist.

Snapshots capture the full state of a canister: its compiled Wasm module, heap memory, stable memory, certified variables and chunk store. Only the canister’s controllers can create or restore one, so the client triggers it without involving Swiss Subnet. A snapshot can be downloaded to a local directory, and uploaded again to restore into a canister. Three constraints come with it:

  • The canister must be stopped to create or restore a snapshot. Export is not free of downtime.
  • Up to 10 snapshots per canister are held at a time, and they count toward the canister’s storage — on an engine that is capacity consumed, not a metered charge.
  • The download is a memory image, not a portable dataset. It comes out as the Wasm module alongside raw memory images, so reading application records from it means knowing how that canister laid its data out in memory. The format is open but only useful next to the canister that wrote it: this is a rollback and recovery mechanism, and a migration route only back onto ICP.

Mechanics and commands are in the canister snapshots documentation.

Application endpoints are the route to a portable export. A canister can expose query or update methods that read its state out in whatever format the application defines, and what those return is a development decision, not a platform one. Anything intended to be read by a system that is not a canister has to be exported this way.