Snapshot metrics in Forge

Building scheduled analytics to track what exists

Why Snapshot Metrics Matter

When building analytics into your Forge app, it's easy to focus only on event tracking — logging what users do in real time. But event tracking doesn't answer one of the most important questions for product teams:

"How many X does this account currently have?"

Snapshot metrics provide this missing piece. They're used to measure the total count of key objects in your system — things like todos, projects, users, settings, etc. These metrics are calculated regularly, not emitted on user action.

Why they're useful:

  • You can't reliably calculate totals from events (e.g., todo_created minus todo_deleted can drift over time).
  • You need a single source of truth for object counts at the account level.
  • They're essential for detecting when an account is approaching a plan or tier limit (e.g., 100 forms on a free plan).
  • Tracking these counts over time allows you to see whether an account is growing, staying flat, or declining.

Examples of Snapshot Metrics

Here are typical metrics you might want to calculate nightly:

{
  totalTodoCount: "42",
  isActive: true,
  isEvaluation: false,
  lastDailySync: "2025-06-13T08:41:00Z",
  name: "a1b2c3d4-cloudId"
}

How to Implement Snapshot Metrics in Forge

📦

Working Example Available

The following code is available in our sample app available on GitHub.

🔗 View the full Forge Analytics Example on GitHub

Step 1: Set Up a Scheduled Trigger

Update your manifest.yml with a daily job:

modules:
  scheduledTrigger:
    - key: daily-analytics-scheduled-trigger
      function: daily-analytics
      interval: day

  function:
    - key: daily-analytics
      handler: analytics/schedule.dailyGroupAnalytics

Step 2: Write Your Metric Functions

In your main resolver (src/index.js), export functions that calculate point-in-time data:

export const getTodoCount = async () => {
  return (await getAll('todo-panel')).length;
}

Step 3: Build the Scheduled Analytics Handler

In src/analytics/schedule.js, create the scheduled job that collects metrics and sends them:

import {handleGroup} from "./dispatcher";
import {groupIdFromContext} from "./utils";
import {getTodoCount} from "../index";

export const dailyGroupAnalytics = async ({ context }) => {
    // Collect instance-level traits from Forge context
    const traits = {
        name: context.cloudId,
        isActive: context?.license?.isActive,
        isEvaluation: context?.license?.isEvaluation,
        lastDailySync: new Date().toISOString(),
        totalTodoCount: `${await getTodoCount()}`,
    };

    const groupId = groupIdFromContext(context);

    // Send group update directly (not through queue since this is already scheduled)
    handleGroup(groupId, traits);
}

Key Components Explained

License Information

Forge provides critical license data in the context:

  • isActive: Whether the app license is currently active
  • isEvaluation: Whether the app is in trial/evaluation mode
  • lastDailySync: Timestamp tracking when metrics were last updated

Direct Dispatch

Note that scheduled jobs call handleGroup() directly rather than going through the queue system — they're already running asynchronously on a schedule.

String Conversion

Numeric values like todo counts are converted to strings (totalTodoCount: "${await getTodoCount()}") for consistent data types across analytics providers.


Best Practices for Snapshot Metrics

  • Use scheduled triggers — snapshots should run at a regular cadence (e.g., nightly).
  • Avoid inferring counts from events — always calculate directly from source of truth.
  • Include license status — track whether accounts are active, in evaluation, or expired.
  • Convert numbers to strings — ensures compatibility across analytics platforms.
  • Skip the queue — scheduled jobs can dispatch directly since they're already async.

Summary

Snapshot metrics are the right tool for tracking what exists — not what happened.

They're especially important when:

  • You want to know how much an account is using your app
  • You need to track license status and evaluation periods
  • You want to monitor growth in object counts or account usage
  • You need metrics that aren't affected by dropped or duplicated events

Build snapshot metrics once, and your product, success, and growth teams will have answers they can rely on.