Internet Computer: Canister Timers

Introducing Canister Timers — a better way to schedule one-shot and periodic tasks on the Internet Computer.

Andriy Berestovskyy
The Internet Computer Review
4 min readMar 29, 2023

--

Unlike other blockchains, the Internet Computer can automatically execute canister smart contracts after a specified delay or periodically. The Canister Timers functionality has been available for early adopters since December. Just in three months timers made it into many internal and community projects: OpenChat, Bitcoin integration, ckBTC, Azle and many many more…

While it’s still early days for the timers, the usage has been doubled for the past month:

Showcases

Below are a few inspiring patterns where the timers might get handy.

Memoization

Store the results of expensive operations and return the cached result.
For example, a canister can do an expensive HTTP outcall to CoinBase every 15 minutes to update exchange rates, using the cached rates in between the updates.

This pattern is probably the most used one. For example, it’s in the production Bitcoin Integration ckBTC Minter and Rosetta API Total Value Locked canisters.

Limited Time Events

Schedule a one-shot task at the specific date and time.
For example, during the SNS launch events, the governance token sale starts and ends at specific point in time.

Very Long Computations

Split a very long computation into multiple chunks.
With the Deterministic Time Slicing feature, the Internet Computer can execute billions of instructions without blocking the subnet progress. But even billions have their limits, so for even longer executions, the timers might be handy.

For example, consider a canister to generate many assets:

  1. Begin: User starts a process by calling an asset generator canister. The canister creates zero delay Canister Timer to generate the first asset, and then immediately replies to the user: “0% done so far”.
  2. Separation of execution contexts: The actual asset generation is happening in the timer handler. Note, any traps during the generation won’t be affecting the progress reports.
  3. Status report: Once the first asset is generated, the canister schedules the next one using zero delay Canister Timer again. The user tracks the progress time to time, and the canister is immediately reports “n% done so far”.
  4. End: The process repeats until all the assets are generated.

The Timers Story

The canister timers is not all that new functionality. From the genesis of the Internet Computer there were heartbeats — periodic canister invocations with intervals close to the blockchain finalization rate (1s).

The heartbeats worked fine, and continue to work just fine. There are many production solutions built on that. But because the heartbeat interval is quite short and there is no way to adjust the interval or pause, the heartbeats are just too expensive for many use cases.

DFINITY engineers together with the community came up with the following solution:

  1. Keep the current heartbeat functionality as is for backward compatibility. And then, based on the heartbeat experience and real use cases, implement a new functionality — Canister Timers.
  2. Minimalistic protocol level changes. The Internet Computer Protocol supports single on-shot timer per canister via ic0.global_timer_set() system API call and canister_global_timer handler (see the Internet Computer Interface Specification).
  3. Convenient CDK timers library. The library wraps the minimalistic protocol implementation, implementing multiple and periodic timers. Canister developers can enjoy the familiar timers functionality using the CDK timers library for Rust or Motoko.

This approach facilitates the protocol changes and makes it easy to improve the functionality in the CDK library without breaking the existing canisters.

The three main differences between the new timers and the old heartbeats:

  1. Costs. Heartbeats are periodic by design. The only way to disable the heartbeats is to upgrade the canister to a version which does not export the canister_heartbeat method. Timers solve this by allowing to schedule a one-shot tasks, and hence reduce the overall costs.
  2. Flexibility. The heartbeat interval is implementation-defined, and there is no way to adjust it. While timers still does not provide strict scheduling guarantees, yet the minimum delay specified by the canister developer is guaranteed to be respected.
  3. Composability. The heartbeats are global, so it’s impossible to use different libraries with heartbeats in a single project. Timers solve this issue by providing the CDK library supporting multiple timers.

Using Timers in Rust

To use the new functionality in Rust project, just add the library:

cargo add ic-cdk-timers

And it’s ready to use:

use std::time::Duration;

const N: Duration = Duration::from_secs(5);

fn ring() {
ic_cdk::println!("Rust Timer Ring!");
}

#[ic_cdk::init]
fn init() {
let _timer_id = ic_cdk_timers::set_timer_interval(N, ring);
}

#[ic_cdk::post_upgrade]
fn post_upgrade() {
init();
}

For more details, see the Rust Backend Tutorials: Using Timers

Using Timers in Motoko

Motoko is a programming language to seamlessly support the programming model of the Internet Computer and makes it easier to take advantage of the unique features of the blockchain.

Timers in Motoko are also a piece of cake:

import { print } = "mo:base/Debug";
import { recurringTimer } = "mo:base/Timer";

actor Alarm {

let N = 5;

private func ring() : async () {
print("Motoko Timer Ring!");
};

ignore recurringTimer(#seconds N, ring);
};

For more details, see Motoko Developer Guide: Timers

References

  1. Backend Developer Guide: Periodic Tasks and Timers
  2. Rust Backend tutorials: Using Timers
  3. Rust Examples: Periodic Tasks and Timers
    (compares the costs of timers and heartbeats)
  4. Motoko Developer Guide: Timers

If you have questions/suggestions or just want to meet Internet Computer developers and DFINITY engineers, join the forum.dfinity.org.

--

--

Andriy Berestovskyy
The Internet Computer Review

Engineer at DFINITY.org. In love with software performance and distributed systems. Let’s connect on linkedin.com/in/berestovskyy