Live prices are currently unavailable — the exchange feed could not be reached and no recent cached reading is held.

Research · Cross-chain

ICP and Solana: canister-centric and program-centric design

A canister owns its state, is upgraded in place and pays for its own resources from a cycles balance. A Solana program owns nothing: it is stateless code that operates on accounts the caller supplies. Both are built for applications rather than for settlement, and the difference in where state lives shapes everything a developer does.

The canister as a stateful actor

The Internet Computer's documentation describes a canister as a WebAssembly module with its own persistent memory, deployed to a subnet and replicated across that subnet's nodes. The canister has an address, a cycles balance and a controller, and it can expose update methods that mutate its state and query methods that read it. Because the memory persists across calls, a canister is closer to a long-running server process than to a function: it accumulates state, it can be called by users and by other canisters, and it can itself call out to other canisters or to external chains through threshold signatures.

The actor framing is not decoration. The documentation's programming model is explicitly an actor model: canisters communicate by asynchronous messages, an update call that calls another canister cannot return a value to its caller in the same round, and the developer composes behaviour out of messages rather than out of nested function calls. That is a real constraint, and it is the price of the isolation that lets each canister hold its own state and be upgraded independently.

Storage is part of the same picture. A canister's memory is charged for continuously, and the documentation describes a stable-memory mechanism that lets a canister keep data across upgrades without serialising it into the heap. The developer therefore makes an explicit decision about what lives in ordinary memory and what lives in stable memory, and that decision is what makes an in-place upgrade safe.

The Solana program as stateless code

Solana inverts the arrangement. The documentation describes a program as executable code that holds no state of its own, and an account as the container that holds data and a lamport balance. A program is invoked with a list of accounts, and it reads and writes those accounts; the state an application accumulates lives in accounts that the program owns or is granted authority over, not inside the program. The program is therefore closer to a pure function over accounts than to a server process.

That separation is what makes the parallel runtime possible. Because every instruction declares the accounts it will touch, the scheduler can run non-overlapping instructions concurrently, and because the program itself holds nothing, there is no per-program state that would have to be locked. The cost is that the developer designs the account layout as part of the program's interface: which accounts exist, who owns them, how their data is laid out and which instruction is allowed to write them are all decisions the program's correctness depends on.

Paying for storage follows from the same model. The documentation describes rent as a lamport balance an account must maintain to stay on chain, with the balance proportional to the space the account occupies. Storage is therefore paid for by whoever funds the account, and an account whose balance falls below the threshold can be purged. That is a different arrangement from a canister's cycles balance, but it answers the same question: who keeps this data alive, and what happens when they stop.

Upgrading an application, and what survives

On the Internet Computer, an upgrade replaces the canister's WebAssembly module while preserving its memory, and the documentation describes pre-upgrade and post-upgrade hooks that let the developer migrate state between layouts. The canister keeps its address and its cycles balance, so users and other canisters do not have to be redirected. The security boundary is the canister's controller list: whoever controls the canister can replace its code, and the platform enforces that rather than the application.

On Solana, a program's code is stored in an account, and the documentation describes a program account as upgradeable when it is marked as such and owned by the upgradeable loader, with an upgrade authority permitted to write a new program buffer into it. A program deployed as final is not upgradeable at all. Because the program holds no state, an upgrade does not have to preserve anything inside it: the accounts the program operates on are untouched, and the new code simply reads and writes them under whatever layout rules it expects. The migration problem moves entirely into the account layout, where a change in how data is encoded is the developer's responsibility.

The two arrangements therefore place the same risk in different spots. A canister upgrade risks the canister's own memory, which is why the hooks exist. A program upgrade risks the account layout, which is why the account schema is effectively part of the program's public interface. Neither platform removes the need to think about how old data meets new code.

The two application models side by side

The table states the structural differences between a canister and a Solana program. Each row is drawn from the platform's own documentation.

Internet Computer canisters and Solana programs compared on state ownership, storage, upgrades and payment.
DimensionICP canisterSolana program
Who owns the stateThe canister itself, in its own memoryAccounts, which the program reads and writes
Where state livesCanister memory, with stable memory for upgrade-safe dataAccount data, laid out by the program's own schema
How storage is paid forCycles, charged continuously for memory and computeRent, a lamport balance proportional to account size
How the code changesThe module is replaced in place, with migration hooksA new program buffer is written by the upgrade authority
What an upgrade risksThe canister's own memory layoutThe account layout the new code expects
How programs interactAsynchronous messages between canistersInstructions that declare the accounts they touch
Who can change the codeThe canister's controllersThe program's upgrade authority, or no one if final

Last reviewed 2026-09-21Source: ICP and Solana developer documentationStructural comparison; no cost or performance figure is asserted.

What the comparison does not settle

The table describes where state lives, not which arrangement is better for a given application. A canister that holds its own state is convenient for a service that accumulates data and is upgraded by its operator; a stateless program over explicit accounts is convenient for a workload that needs to run in parallel and whose state is naturally partitioned. The right answer depends on the application, and the documentation of neither platform claims otherwise.

The comparison is also silent on the questions this cluster covers elsewhere. It does not describe how either network reaches finality, which is the subject of the finality comparison, and it does not describe how either one represents a transaction or grows its state, which the transaction and data model comparison takes up. Read together, the four pages describe the same two networks from four angles.

Finally, both platforms are under active development. The Internet Computer's canister model and Solana's runtime and account rules have both changed since their introductions, and this page describes them as their documentation describes them at the review date. Where a mechanism is proposed rather than deployed, the documentation says so, and this page does not present a proposal as a capability.

Sources and references

Each platform's application model is described from its own documentation. No capability or figure is asserted that the cited source does not state.

  • Canisters, memory and upgrades. ICP Developer Docs, Canisters and code: a canister holds persistent memory and is upgraded in place, with pre- and post-upgrade hooks.
  • The actor model and asynchronous calls. ICP Developer Docs, Actors and canisters: canisters communicate by asynchronous messages, and an update call cannot return a value in the same round.
  • Solana's accounts and programs. Solana Docs, Accounts: programs are stateless, accounts hold data and lamports, and rent is a balance proportional to the space an account occupies.
  • Upgradeable programs. Solana Docs, Programs: a program account is upgradeable when owned by the upgradeable loader, and an upgrade authority may write a new program buffer.