A newer version of this documentation is available.

View Latest

    Timers are asynchronous compute, which offers Eventing Functions the ability to execute in reference to wall-clock events. Timers also measure and track the amount of elapsed time and can be used while archiving of expired documents at a preconfigured time.

    When using timers, it is required that all nodes of the cluster are synchronized at computer startup, and periodically afterwards using a clock synchronization tool like NTP.

    A few important aspects related to timers are listed below:

    • Timers follow the same timeout semantics as their Parent Functions. So, if an Eventing Function has an execution timeout of 60 seconds, each of the timers created from the Eventing Function inherits the same execution timeout value of 60 seconds.

    • Timers may run on a different node than the one on which it was created.

    • One execution of timers is guaranteed despite node failures and cluster rebalances.

    • During Function backlogs, timers get eventually executed.

    • The metadata bucket stores information about timers and its association with an Eventing Function’s handler.

    • Ensure that the metadata bucket is not deleted or flushed, or the keys in metadata bucket get updated.

    • Each active timer an additional amount of space between 832 and 1856 bytes (832 bytes + sizeof(context)) is needed. Where the context can not be larger than 1024 bytes.

    • With an increase in the usage of timers, the metadata bucket’s space assignment must also be increased to accommodate all active timers and any potential backlog. If the use-case mandates large numbers of timers in the system, it is required that the space assigned to the metadata bucket be suitably high as well.

    • Due to runtime or programmatic errors in the function handler code, if triggering of a timer fails, then timer execution may get permanently blocked.

    • Bindings for bucket-aliases can be reused in timers. Bucket-aliases, created during the Eventing Function definition, can be accessed by the timer constructs in the handler code.

    • Timers get deleted when the associated Function is deleted or undeployed.

    The Timer Construct

    The Timers language construct is added to support requirements of Couchbase Eventing Functions.

    To create a timer use the below syntax:

    createTimer(callback, date, reference, context)

    In the createTimer syntax:

    • callback - This function is called when the timer fires. The callback function must be a top-level function that takes a single argument, the context (see below).

    • date - This is a JavaScript Date object representing the time for the timer to fire. The date of a timer must always be in future when the timer is created, otherwise the behavior is unspecified.

    • reference - This is a unique string that must be passed in to help identify the timer that is being created. References are always scoped to the function and callback they are used with and need to be unique only within this scope. You may not reuse the reference if there is an active timer with the same reference within the current scope. The call returns the reference string if timer was created successfully. If the reference parameter is set to JavaScript null value, a unique reference will be generated.

      Note that in release 6.6.0 Eventing Timers can be cancelled using the cancelTimer() function, or by creating a new Timer with the same reference as an existing Timer refer to Timers: Limitations.

    • context - This is any JavaScript object that can be serialized. The context specified when a timer is created is passed to the callback function when the timer fires. The default maximum size for Context objects is 1kB. Larger objects would typically be stored as bucket objects, and document key can be passed as context.

    • return value - If the reference parameter was null, this call returns the generated unique reference. Otherwise, the passed in reference parameter is the return value.

    • Exceptions Thrown - The createTimer() function throws an exception if the timer creation fails for an unexpected reason, such as an error writing to the metadata bucket.

    A sample createTimer language construct is provided for reference.

    createTimer(DocTimerCallback, oneMinuteFromNow, meta.id, context)

    In the sample construct:

    • DocTimerCallback is the name of the function used in the Function handler code.

    • oneMinuteFromNow is a JavaScript Date object.

    • meta.id is a generic reference string that can be used in the Couchbase cluster.

    • context is the JavaScript object that is used in the Function handler code.

    Using the construct above here is a working Eventing Function that creates a timer that is scheduled to be executed 60 seconds from its creation time where the callback will create a document in the alias 'dest_bucket' which must be a 'read and write' bbinding to an existing bucket.

    function DocTimerCallback(context) {
       log('From DocTimerCallback', context);
       // create a new document as per our received context
       dest_bucket[context.docId] = context.random_text; // upsert a portion of the context
    function OnUpdate(doc,meta) {
       // you would typically  filter to mutations of interest perhaps by type and a needed condition
       // if (doc.type != 'type_of_interest' || doc.needed_condition != true) return;
       // create a timestamp 60 seconds from now
       var oneMinuteFromNow = new Date(); //get current time
       oneMinuteFromNow.setSeconds(oneMinuteFromNow.getSeconds() + 60); //add 60 seconds to it
       // create a document to use as out for our context
       var context = {docId : meta.id, random_text : "arbitrary text"};
       createTimer(DocTimerCallback, oneMinuteFromNow, meta.id, context);

    Sharding of Timers

    Timers get automatically sharded across Eventing nodes and therefore are elastically scalable. Triggering of timers at or after a specified time interval is guaranteed. However, triggering of timers may either be on the same node (where the timer was created), or on a different node. Relative ordering between two specific timers cannot be maintained.

    Debugging and Logs

    Timers cannot be debugged using the Visual Debugger. For debugging, Couchbase recommends enclosing of timers in a try-catch block. When logging is enabled, timer related logs get captured as part of the Eventing Function’s application logs.

    Elapsed Timestamps

    During runtime, when a Function handler code contains a timestamp in the past (elapsed timestamp), the system executes the code in the next available time window, as soon as the required resources are available.

    Handling Delays

    During Function backlogs, execution of timers may be delayed. To handle these delays, you need to program additional time window in your code. If your business logic is time-sensitive after this additional time window the code should refrain from its Function execution.

    The following is a sample code snippet, which performs a timestamp check (my_deadline) before code execution.

    func callback(context) {
      //context.my_deadline is the parameter in the timer payload
      if (new Date().getTime() > context.my_deadline) {
         // timestamp is back-dated, do not execute the rest of the timer

    Wall-clock Accuracy

    Timers are not wall-clock accurate events. The timer implementation is designed to handle large numbers of distributed timers (i.e., millions of timers) and only promise to run timers as soon as possible, e.g. no timers lost in a healthy system without crashing nodes.

    Couchbase currently scans for active timers every 7 seconds this creates a maximum delay of 7 seconds + the time it takes too process timers ahead of the given timer on a given thread. Thus, in an Eventing system in a steady state you will typically experience an average timer firing delay of about 3-4 seconds after the scheduled time.

    However, if timer is created and scheduled to close the wall clock of the system Couchbase may delay the actual scheduling by an additional 1 to 2 scan periods (up to a 14 second delay after the scheduled time) to avoid races.

    The additional overall delay is an implementation artifact and may change between releases.


    In the 5.5.x, 6.0.x and 6.5.x releases:

    • Eventing timers once created cannot be overwritten by using the same reference.

    • In addition, a function that is invoked by a timer callback cannot reliably create a fresh timer (a work around can be done via a second cooperative Function).

    In the 6.5.X releases:

    • Creating timers in the future (as in one hour+) in an otherwise idle system can result in a growing number of metadata bucket operations which can eventually block mutations for a given Eventing function. In 6.5.X a user space workaround can be accomplished via a second cooperative Function.

      The severity is governed by:

      • The number of vBuckets holding an active timer. Therefore, if there are only a few timers in the future the issue may not be noticeable or materialize.

      • Whether an Eventing timer has fired recently on a vBucket (which clears the issue for the given vBucket on a per function basis). Therefore systems with lots of near term timer activity will not experience this issue even if timers are scheduled far into the future.

    All of these limitations are planned to be addressed in the next version.


    The Eventing Examples section provides two examples that show the use of Timers. The first example Document Expiry and second example is Document Archive.