Skip to main content


Internet Computer canisters can set an arbitrary number of single-expiration or recurring timers. See the module in the base library.

A simple, contrived example is a periodic reminder, that logs a new-year's message:

import { print } = "mo:base/Debug";
import { abs } = "mo:base/Int";
import { now } = "mo:base/Time";
import { setTimer; recurringTimer } = "mo:base/Timer";

actor Reminder {

let solarYearSeconds = 356_925_216;

private func remind() : async () {
print("Happy New Year!");

ignore setTimer(#seconds (solarYearSeconds - abs(now() / 1_000_000_000) % solarYearSeconds),
func () : async () {
ignore recurringTimer(#seconds solarYearSeconds, remind);
await remind();

The underlying mechanism is a canister global timer that, by default, is issued with appropriate callbacks from a priority queue maintained by the Motoko runtime.

The timer mechanism can be disabled completely by passing the -no-timer flag to moc.

When lower-level access to the canister global timer is desired, an actor can elect to receive timer expiry messages by declaring a system function, named timer. The function takes one argument (to re-set the global timer), and returns a future of unit type (async ()). If the timer system method is declared, the base library module may not function correctly and should not be used.

The following example of a global timer expiration callback gets called immediately after the canister starts (i.e. after install) and periodically every twenty seconds thereafter:

system func timer(setGlobalTimer : Nat64 -> ()) : async () {
let next = Nat64.fromIntWrap( + 20_000_000_000;
setGlobalTimer(next); // absolute time in nanoseconds