Skip to main content

Persistent storage


The example dapp shows how to build a simple dapp in Motoko, which will have persistent storage. The dapp is a simple counter, which will increment a counter, retrieve the counter value and reset the counter value by calling backend functions. The functions are exposed through a Candid interface.

The purpose of this example dapp is to build a simple counter dapp, where the counter value will persist even after the dapp has changed and been re-deployed.

This example covers:

  • Create new canister smart contract using Motoko.
  • Add backend functions for a counter (increment, get count and reset count).
  • Deploy the canister smart contract locally.
  • Test backend with Candid UI and command line using dfx .


This example project can be cloned, installed and deployed locally, for learning and testing purposes. The instructions are based on running the example on either macOS or Linux, but when using WSL2 on Windows, the instructions will be the same.


This example requires an installation of:

Begin by opening a terminal window.

Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command:

cd examples/motoko/persistent-storage
dfx start --background

Step 2: Build and deploy the canister:

dfx deploy

Step 3: Command usage: dfx canister call <project> <function>

dfx canister call persistent_storage increment


(1 : Nat)
dfx canister call persistent_storage get


(1 : Nat)
dfx canister call persistent_storage reset


(0 : Nat)

The persistence of the stored value can be tested by calling the increment function again and making sure the value is larger than zero. Then make a change in the Motoko code, any minor change like changing the function name get to getCount, and then re-deploy the project and call the getCount function to verify that the counter value did not change back to the initial value (0).

$ dfx canister call persistent_storage increment
(1 : Nat)
// Make code change
$ dfx deploy
$ dfx canister call persistent_storage getCount
(1 : Nat)


The two main parts of the example dapp are the backend and the Candid interface. This example project does not have a frontend.

Motoko backend

The backend functions are located in the src/persistent_storage/ Motoko file. The backend stores the counter value, and has functions to get, increment and reset the counter value. Furthermore the backend insures the counter value persists upgrades of the dapp.

Counter variable

The current counter value is stored as a number in the actor.

actor {
stable var counter : Nat = 0;


The increment() function increments the counter variable.

public func increment() : async Nat {
counter += 1;
return counter;

The function is returning the incremented counter variable.


The get() function returns the current counter value.

public query func get() : async Nat {
return counter;


The reset() function resets the counter value to 0 and returns the value.

public func reset() : async Nat {
counter := 0;
return counter;

Candid interface

The Candid UI provides an easy, user friendly interface for testing the backend. The UI is automatically generated, and the canister ID can be found by using the dfx canister id <canister_name> command:

$ dfx canister id __Candid_UI
$ dfx canister id persistent_storage