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.
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 .
Basic Example
Advanced Example
import { HeartbeatMonitor } from "checkly/constructs"
new HeartbeatMonitor ( "daily-backup-heartbeat" , {
name: "Daily Backup Job" ,
period: 1 ,
periodUnit: "days" ,
grace: 2 ,
graceUnit: "hours" ,
})
Configuration
The Heartbeat Monitoring configuration consists of specific heartbeat monitoring options and inherited general monitoring options.
Heartbeat Monitor
General Monitor
Parameter Type Required Default Description periodnumber✅ - The expected period between pings (30 seconds to 365 days) periodUnitstring✅ - Time unit: 'seconds' | 'minutes' | 'hours' | 'days' gracenumber✅ - Grace period before alerting (0 seconds to 365 days) graceUnitstring✅ - Grace time unit: 'seconds' | 'minutes' | 'hours' | 'days'
Property Type Required Default Description namestring✅ - Friendly name for your monitor activatedboolean❌ trueWhether the monitor is enabled mutedboolean❌ falseWhether alert notifications are muted alertChannelsAlertChannel[]❌ []Array of AlertChannel objects for notifications tagsstring[]❌ []Array of tags to organize monitors
HeartbeatMonitor Options
The expected period between pings from your external service. This defines how often your job or service should check in. Usage: new HeartbeatMonitor ( 'my-heartbeat' , {
name: "My heartbeat" ,
period: 1 ,
periodUnit: 'days' // Daily check-in expected
/* More options ... */
})
Examples: Daily Jobs
Hourly Tasks
Frequent Checks
// Daily backup job
new HeartbeatMonitor ( "backup-job" , {
name: "Daily Database Backup" ,
period: 1 ,
periodUnit: "days" ,
grace: 2 ,
graceUnit: "hours" ,
})
// Hourly data sync
new HeartbeatMonitor ( "data-sync" , {
name: "Hourly Data Sync" ,
period: 1 ,
periodUnit: "hours" ,
grace: 15 ,
graceUnit: "minutes" ,
})
// Every 5 minutes
new HeartbeatMonitor ( "frequent-task" , {
name: "Frequent Health Check" ,
period: 5 ,
periodUnit: "minutes" ,
grace: 2 ,
graceUnit: "minutes" ,
})
Range : 30 seconds to 365 days
The time unit for the period. Defines whether the period is in seconds, minutes, hours, or days. Usage: new HeartbeatMonitor ( "my-heartbeat" , {
name: "My heartbeat" ,
period: 2 ,
periodUnit: "hours" // Every 2 hours
/* More options ... */
})
Available units : 'seconds', 'minutes', 'hours', 'days'
The grace period to wait before alerting after the expected ping time has passed. This allows for slight delays in job execution. Usage: new HeartbeatMonitor ( 'my-heartbeat' , {
period: 1 ,
periodUnit: 'hours' ,
grace: 10 ,
graceUnit: 'minutes' // 10 minute grace period
})
Examples: Short Grace Period
Moderate Grace Period
Long Grace Period
// Strict timing requirements
new HeartbeatMonitor ( "critical-task" , {
name: "Critical System Task" ,
period: 5 ,
periodUnit: "minutes" ,
grace: 1 , // Only 1 minute grace
graceUnit: "minutes" ,
})
// Standard tolerance
new HeartbeatMonitor ( "standard-job" , {
name: "Standard Processing Job" ,
period: 1 ,
periodUnit: "hours" ,
grace: 15 , // 15 minute grace period
graceUnit: "minutes" ,
})
// 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" ,
})
Range : 0 seconds to 365 days
The time unit for the grace period. Defines whether the grace period is in seconds, minutes, hours, or days. Usage: new HeartbeatMonitor ( 'my-heartbeat' , {
period: 6 ,
periodUnit: 'hours' ,
grace: 30 ,
graceUnit: 'minutes' // 30 minute grace period
})
Available units : 'seconds', 'minutes', 'hours', 'days'
General Monitor Options
Friendly name for your heartbeat monitor that will be displayed in the Checkly dashboard and used in notifications. Usage: new HeartbeatMonitor ( 'my-heartbeat' , {
name: 'Daily Backup Job Monitor' ,
/* More options ... */
})
Examples
Daily Backup Job
Hourly Data Sync
CI/CD Pipeline
Log Processing
Short Interval Check
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]
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
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 }}
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)
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
Getting the heartbeat Ping URL
After deploying your heartbeat monitor, you can obtain the ping URL in several ways:
npx checkly deploy
# Output will include:
# Ping URL of heartbeat check "[YOUR_HEARTBEAT_MONITOR_NAME]" is https://ping.checklyhq.com/...
Navigate to your heartbeat monitor in the Checkly web UI to copy the ping URL.
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.
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.