> ## Documentation Index
> Fetch the complete documentation index at: https://checklyhq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Heartbeat Monitor Construct

> Learn how to configure heartbeat monitors with the Checkly CLI.

<Tip>
  Learn more about Heartbeat monitors in [the Heartbeat monitor overview](/detect/uptime-monitoring/heartbeat-monitors/overview).
</Tip>

Use Heartbeat Monitors to track passive monitoring scenarios where external services ping Checkly at regular intervals. The examples below show how to configure monitoring for different types of scheduled jobs and services.

<Accordion title="Prerequisites">
  Before creating heartbeat monitors, ensure you have:

  * An initialized Checkly CLI project
  * External services, cron jobs, or scripts that can send HTTP POST requests
  * Understanding of your scheduled job intervals and expected timing
  * Network access from your services to Checkly's ping endpoints

  For additional setup information, see [CLI overview](/cli/overview).
</Accordion>

<CodeGroup>
  ```ts Basic Example theme={null}
  import { HeartbeatMonitor } from "checkly/constructs"

  new HeartbeatMonitor("daily-backup-heartbeat", {
    name: "Daily Backup Job",
    description: "Expects a ping every **24h** from the nightly DB backup cron.",
    period: 1,
    periodUnit: "days",
    grace: 2,
    graceUnit: "hours",
  })
  ```

  ```ts Advanced Example theme={null}
  import { HeartbeatMonitor } from "checkly/constructs"

  new HeartbeatMonitor("newsletter-heartbeat", {
    name: "Weekly Newsletter Job",
    description: "Weekly newsletter job completes every 7 days.",
    activated: true,
    muted: false,
    period: 7,
    periodUnit: "days",
    grace: 4,
    graceUnit: "hours",
    tags: ["newsletter", "marketing", "weekly"],
    alertChannels: [emailChannel, slackChannel],
  })
  ```
</CodeGroup>

## Configuration

The Heartbeat Monitoring configuration consists of specific heartbeat monitoring options and inherited general monitoring options.

<Tabs>
  <Tab title="Heartbeat Monitor">
    | Parameter    | Type     | Required | Default | Description                                                          |
    | ------------ | -------- | -------- | ------- | -------------------------------------------------------------------- |
    | `period`     | `number` | ✅        | -       | The expected period between pings (30 seconds to 365 days)           |
    | `periodUnit` | `string` | ✅        | -       | Time unit: `'seconds'` \| `'minutes'` \| `'hours'` \| `'days'`       |
    | `grace`      | `number` | ✅        | -       | Grace period before alerting (0 seconds to 365 days)                 |
    | `graceUnit`  | `string` | ✅        | -       | Grace time unit: `'seconds'` \| `'minutes'` \| `'hours'` \| `'days'` |
  </Tab>

  <Tab title="General Monitor">
    | Property        | Type             | Required | Default | Description                                                         |
    | --------------- | ---------------- | -------- | ------- | ------------------------------------------------------------------- |
    | `name`          | `string`         | ✅        | -       | Friendly name for your monitor                                      |
    | `description`   | `string`         | ❌        | `null`  | A description of the monitor. Supports markdown. Max 500 characters |
    | `activated`     | `boolean`        | ❌        | `true`  | Whether the monitor is enabled                                      |
    | `muted`         | `boolean`        | ❌        | `false` | Whether alert notifications are muted                               |
    | `alertChannels` | `AlertChannel[]` | ❌        | `[]`    | Array of AlertChannel objects for notifications                     |
    | `tags`          | `string[]`       | ❌        | `[]`    | Array of tags to organize monitors                                  |
  </Tab>
</Tabs>

### `HeartbeatMonitor` Options

<ResponseField name="period" type="number" required>
  The expected period between pings from your external service. This defines how often your job or service should check in.

  **Usage:**

  ```ts highlight={3} theme={null}
  new HeartbeatMonitor('my-heartbeat', {
    name: "My heartbeat",
    period: 1,
    periodUnit: 'days' // Daily check-in expected
    /* More options ... */
  })
  ```

  **Examples:**

  <Tabs>
    <Tab title="Daily Jobs">
      ```ts theme={null}
      // Daily backup job
      new HeartbeatMonitor("backup-job", {
        name: "Daily Database Backup",
        period: 1,
        periodUnit: "days",
        grace: 2,
        graceUnit: "hours",
      })
      ```
    </Tab>

    <Tab title="Hourly Tasks">
      ```ts theme={null}
      // Hourly data sync
      new HeartbeatMonitor("data-sync", {
        name: "Hourly Data Sync",
        period: 1,
        periodUnit: "hours",
        grace: 15,
        graceUnit: "minutes",
      })
      ```
    </Tab>

    <Tab title="Frequent Checks">
      ```ts theme={null}
      // Every 5 minutes
      new HeartbeatMonitor("frequent-task", {
        name: "Frequent Health Check",
        period: 5,
        periodUnit: "minutes",
        grace: 2,
        graceUnit: "minutes",
      })
      ```
    </Tab>
  </Tabs>

  **Range**: 30 seconds to 365 days
</ResponseField>

<ResponseField name="periodUnit" type="string" required>
  The time unit for the period. Defines whether the period is in seconds, minutes, hours, or days.

  **Usage:**

  ```ts highlight={4} theme={null}
  new HeartbeatMonitor("my-heartbeat", {
    name: "My heartbeat",
    period: 2,
    periodUnit: "hours" // Every 2 hours
    /* More options ... */
  })
  ```

  **Available units**: `'seconds'`, `'minutes'`, `'hours'`, `'days'`
</ResponseField>

<ResponseField name="grace" type="number" required>
  The grace period to wait before alerting after the expected ping time has passed. This allows for slight delays in job execution.

  **Usage:**

  ```ts highlight={4} theme={null}
  new HeartbeatMonitor('my-heartbeat', {
    period: 1,
    periodUnit: 'hours',
    grace: 10,
    graceUnit: 'minutes' // 10 minute grace period
  })
  ```

  **Examples:**

  <Tabs>
    <Tab title="Short Grace Period">
      ```ts theme={null}
      // Strict timing requirements
      new HeartbeatMonitor("critical-task", {
        name: "Critical System Task",
        period: 5,
        periodUnit: "minutes",
        grace: 1, // Only 1 minute grace
        graceUnit: "minutes",
      })
      ```
    </Tab>

    <Tab title="Moderate Grace Period">
      ```ts theme={null}
      // Standard tolerance
      new HeartbeatMonitor("standard-job", {
        name: "Standard Processing Job",
        period: 1,
        periodUnit: "hours",
        grace: 15, // 15 minute grace period
        graceUnit: "minutes",
      })
      ```
    </Tab>

    <Tab title="Long Grace Period">
      ```ts theme={null}
      // Flexible timing for complex jobs
      new HeartbeatMonitor("complex-job", {
        name: "Complex Data Processing",
        period: 1,
        periodUnit: "days",
        grace: 4, // 4 hour grace period
        graceUnit: "hours",
      })
      ```
    </Tab>
  </Tabs>

  **Range**: 0 seconds to 365 days
</ResponseField>

<ResponseField name="graceUnit" type="string" required>
  The time unit for the grace period. Defines whether the grace period is in seconds, minutes, hours, or days.

  **Usage:**

  ```ts highlight={5} theme={null}
  new HeartbeatMonitor('my-heartbeat', {
    period: 6,
    periodUnit: 'hours',
    grace: 30,
    graceUnit: 'minutes' // 30 minute grace period
  })
  ```

  **Available units**: `'seconds'`, `'minutes'`, `'hours'`, `'days'`
</ResponseField>

### General Monitor Options

<ResponseField name="name" type="string" required>
  Friendly name for your heartbeat monitor that will be displayed in the Checkly dashboard and used in notifications.

  **Usage:**

  ```ts highlight={2} theme={null}
  new HeartbeatMonitor('my-heartbeat', {
    name: 'Daily Backup Job Monitor',
    /* More options ... */
  })
  ```
</ResponseField>

## Examples

<Tabs>
  <Tab title="Daily Backup Job">
    ```ts theme={null}
    new HeartbeatMonitor("backup-job-heartbeat", {
      name: "Daily Database Backup",
      period: 1,
      periodUnit: "days",
      grace: 2,
      graceUnit: "hours",
      tags: ["backup", "database", "critical"],
    })

    // Example cron job that would ping this heartbeat:
    // 0 2 * * * /scripts/backup-database.sh && curl -X POST https://ping.checklyhq.com/[heartbeat-id]
    ```
  </Tab>

  <Tab title="Hourly Data Sync">
    ```ts theme={null}
    new HeartbeatMonitor("sync-job-heartbeat", {
      name: "Hourly Data Synchronization",
      period: 1,
      periodUnit: "hours",
      grace: 15,
      graceUnit: "minutes",
      tags: ["sync", "data", "hourly"],
    })

    // Example Node.js job:
    // setInterval(async () => {
    //   try {
    //     await syncData()
    //     await fetch('https://ping.checklyhq.com/[heartbeat-id]', { method: 'POST' })
    //   } catch (error) {
    //     console.error('Sync failed:', error)
    //   }
    // }, 60 * 60 * 1000) // Every hour
    ```
  </Tab>

  <Tab title="CI/CD Pipeline">
    ```ts theme={null}
    new HeartbeatMonitor('deployment-heartbeat', {
      name: 'Production Deployment Pipeline',
      period: 2,
      periodUnit: 'hours',
      grace: 30,
      graceUnit: 'minutes',
      tags: ['deployment', 'ci-cd', 'production']
    })

    // Example GitHub Actions workflow step:
    // - name: Ping Checkly on successful deployment
    //   if: success()
    //   run: |
    //     curl -X POST https://ping.checklyhq.com/${{ secrets.HEARTBEAT_ID }}
    ```
  </Tab>

  <Tab title="Log Processing">
    ```ts theme={null}
    new HeartbeatMonitor('log-processing-heartbeat', {
      name: 'Log Processing Job',
      period: 30,
      periodUnit: 'minutes',
      grace: 10,
      graceUnit: 'minutes',
      tags: ['logs', 'processing', 'monitoring']
    })

    // Example log processing service:
    // const processLogs = async () => {
    //   try {
    //     await processLogFiles()
    //
    //     // Ping heartbeat on successful processing
    //     await fetch(process.env.CHECKLY_HEARTBEAT_URL, {
    //       method: 'POST',
    //       headers: { 'User-Agent': 'LogProcessor/1.0' }
    //     })
    //   } catch (error) {
    //     console.error('Log processing failed:', error)
    //   }
    // }
    //
    // // Run every 30 minutes
    // setInterval(processLogs, 30 * 60 * 1000)
    ```
  </Tab>

  <Tab title="Short Interval Check">
    ```ts theme={null}
    new HeartbeatMonitor('frequent-task-heartbeat', {
      name: 'Every Minute Task',
      period: 60,
      periodUnit: 'seconds',
      grace: 30,
      graceUnit: 'seconds',
      tags: ['frequent', 'monitoring']
    })

    // Example for very frequent tasks:
    // setInterval(async () => {
    //   try {
    //     await performQuickCheck()
    //     await fetch('https://ping.checklyhq.com/[heartbeat-id]', { method: 'POST' })
    //   } catch (error) {
    //     console.error('Quick check failed:', error)
    //   }
    // }, 60000) // Every minute
    ```
  </Tab>
</Tabs>

## Getting the heartbeat Ping URL

After deploying your heartbeat monitor, you can obtain the ping URL in several ways:

<Tabs>
  <Tab title="CLI Output">
    ```bash theme={null}
    npx checkly deploy

    # Output will include:
    # Ping URL of heartbeat check "[YOUR_HEARTBEAT_MONITOR_NAME]" is https://ping.checklyhq.com/...
    ```
  </Tab>

  <Tab title="Web UI">
    Navigate to your heartbeat monitor in the [Checkly web UI](https://app.checklyhq.com/heartbeats) to copy the ping URL.
  </Tab>
</Tabs>

<Info>
  The ping URL is unique for each heartbeat monitor and should be kept secure. Anyone with access to this URL can send pings to your monitor.
</Info>

<Warning>
  Heartbeat monitors are passive - they wait for your external services to ping them. Make sure your jobs and services are configured to send HTTP POST requests to the ping URL on successful completion.
</Warning>
