GitHub Actions Monitoring: How to Get Alerts When Cron Jobs Fail
Monitor your scheduled GitHub Actions workflows with QuietPulse heartbeat. Get instant alerts through Telegram or webhooks when a cron job misses its run or fails silently.
Why Monitor GitHub Actions Cron Jobs?
GitHub Actions is a powerful CI/CD platform, but its built-in monitoring has a critical gap: it only alerts on workflow failures, not on missed runs.
Consider these scenarios:
- Cron syntax error โ workflow never triggers, no error reported
- Runner unavailable โ scheduled time passes, job doesn't start
- Silent exceptions โ job starts but crashes before actual work
These silent failures can break deployments, miss backups, or stall data pipelines โ and you won't know until it's too late.
Solution: Heartbeat monitoring for GitHub Actions. A simple HTTP ping after each successful run ensures you're notified the moment a scheduled task goes silent.
How Heartbeat Monitoring Works
The pattern is elegantly simple:
- Each scheduled workflow sends a GET request to a unique QuietPulse endpoint after successful completion
- QuietPulse expects these pings at your configured interval (matching the cron schedule)
- If a ping is missed โ QuietPulse sends an alert through your configured channels
It's a dead man's switch for your cron jobs.
+-------------------+ +--------------------+ +---------------------+
| GitHub Actions | --> | QuietPulse | --> | Alert on Miss |
| (cron job) | | /ping/:token | | (Telegram/Webhook) |
+-------------------+ +--------------------+ +---------------------+
Step-by-Step: Add Monitoring to Your GitHub Actions Workflow
1. Create a Heartbeat Job in QuietPulse
- Sign up at quietpulse.xyz
- Click "New Job"
- Configure:
- Name: e.g., "Nightly Backup"
- Expected interval: match your cron schedule (e.g.,
1 hourfor0 * * * *) - Grace period: allow small delays (e.g.,
5 minutes)
- Copy the generated Ping URL (it looks like:
https://quietpulse.xyz/ping/abc...)- The token is the last segment (
abc...)
- The token is the last segment (
2. Add the Ping Step to Your Workflow
Add a step at the end of your job (only on success):
name: Nightly Backup
on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run backup
run: |
# Your backup logic here
pg_dump ...
- name: Send heartbeat to QuietPulse
if: always() # Or success() to only ping on success
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_TOKEN }}
grace_period_minutes: 5
Important: Use if: always() if you want to ping even on failure (to detect if the job didn't complete), or if: success() to only ping when the job succeeded. For true heartbeat monitoring, you typically want only on success โ a missing ping means the job didn't finish.
3. Store Token in GitHub Secrets
- Go to your repository Settings โ Secrets and variables โ Actions
- Click "New repository secret"
- Name:
QUIETPULSE_TOKEN - Value: paste the token from QuietPulse (the last part of the URL)
- Click Add secret
4. Configure Alerts in QuietPulse
In your QuietPulse job settings, configure Telegram notifications, webhooks, or both to receive alerts when the heartbeat is missed.
Complete Examples
Node.js Project with npm Script
name: Deploy Production
on:
schedule:
- cron: '*/30 * * * *' # Every 30 minutes
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Run migrations
run: npm run migrate
- name: Deploy to production
run: npm run deploy
- name: Notify QuietPulse
if: success()
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_DEPLOY_TOKEN }}
Python Cron Job
name: Daily Data Processing
on:
schedule:
- cron: '0 3 * * *' # 3 AM daily
jobs:
process:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Process data
run: python scripts/process.py
- name: Send heartbeat
if: success()
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_PROCESS_TOKEN }}
Laravel / PHP Project
name: Laravel Scheduler
on:
schedule:
- cron: '* * * * *' # Every minute (Laravel handles schedule internally)
jobs:
laravel-schedule:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, pdo_mysql
- name: Install Composer dependencies
run: composer install --no-dev --optimize-autoloader
- name: Run Laravel scheduler
run: php artisan schedule:run
- name: Heartbeat
if: success()
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_LARAVEL_TOKEN }}
Best Practices for GitHub Actions Monitoring
1. Match Intervals Precisely
Set the expected interval in QuietPulse to match your cron schedule exactly:
| Cron Expression | Expected Interval | Grace Period |
|---|---|---|
*/5 * * * * |
5 minutes | 1-2 minutes |
0 * * * * |
1 hour | 5-10 minutes |
0 2 * * * |
1 day | 30 minutes |
2. Only Ping on Success
Use if: success() to send the heartbeat only if all previous steps succeeded. This ensures that a missing ping indicates a real failure.
- name: Heartbeat
if: success() # Critical!
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_TOKEN }}
3. Use Separate Tokens per Job
Don't reuse the same endpoint token across unrelated workflows. Each job gets its own QuietPulse endpoint so you can identify exactly which task failed.
4. Set Appropriate Grace Periods
The grace period accommodates normal variations (GitHub runner queue delays, network latency). Too short โ false alarms; too long โ slow detection.
Recommended:
- Short intervals (5-15 min): 20-30% grace
- Long intervals (daily): 10-30 minutes
5. Monitor the Monitor
QuietPulse itself is monitored, but if you're self-hosting, set up a secondary heartbeat for the QuietPulse service (e.g., ping an external service every minute).
Action Inputs Reference
| Input | Required | Default | Description |
|---|---|---|---|
endpoint_token |
โ Yes | โ | QuietPulse endpoint token (from job settings) |
grace_period_minutes |
โ No | 5 |
Grace period before marking as missed |
timeout_seconds |
โ No | 10 |
HTTP request timeout in seconds |
Outputs
| Output | Description |
|---|---|
status |
Result: success, failed, or error |
http_status |
HTTP response code from QuietPulse |
message |
Success message or error details |
You can use these outputs in subsequent steps:
- name: Check heartbeat result
id: heartbeat
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_TOKEN }}
- name: Fail if heartbeat failed
run: |
if [ "${{ steps.heartbeat.outputs.status }}" != "success" ]; then
echo "โ Heartbeat failed!"
exit 1
fi
Troubleshooting
| Issue | Likely Cause | Fix |
|---|---|---|
404 Not Found |
Invalid token or job doesn't exist | Create the job in QuietPulse, copy token correctly |
403 Forbidden |
Token expired or wrong | Generate a new endpoint token in QuietPulse |
429 Too Many Requests |
Rate limit exceeded | Upgrade QuietPulse plan or reduce ping frequency |
| Action times out | Network issues or QuietPulse down | Increase timeout_seconds, check QuietPulse status |
| Workflow doesn't trigger | Cron syntax error | Validate cron expression at crontab.guru |
| No Telegram alerts | Telegram not connected in QuietPulse | Connect Telegram bot in job settings |
| No webhook alerts | Webhook not configured or receiver failed | Check webhook URL, test delivery, and receiver logs |
Comparing GitHub Actions Monitoring Solutions
| Feature | QuietPulse (this action) | UptimeRobot | GitHub Status API |
|---|---|---|---|
| Monitors cron triggers | โ | โ (only checks URL) | โ |
| Free tier | โ (5 jobs) | โ (50 monitors) | โ (limited) |
| Telegram alerts | โ | โ | โ |
| Webhook notifications | โ | โ | โ |
| No external dependencies | โ | โ | โ |
| Self-hosted option | โ | โ | N/A |
| Easy setup | โ 2-minute config | โ | โ (custom script needed) |
QuietPulse is the only simple solution that actually monitors whether your GitHub Actions cron jobs ran โ not just whether the server is up.
Advanced: Multi-Channel Alerting
QuietPulse supports both direct Telegram alerts and webhook notifications. For example, you can forward failures into Slack through your own webhook-based automation:
- name: Heartbeat
if: failure() # Only on failure
uses: vadyak/quietpulse-actions@v1
with:
endpoint_token: ${{ secrets.QUIETPULSE_TOKEN }}
- name: Alert Slack on failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "โ Cron job failed: ${{ github.workflow }}",
"channel": "#alerts"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
Next Steps
- Install the heartbeat action in your critical workflows
- Set up Telegram alerts, webhooks, or both in QuietPulse dashboard
- Add multiple endpoints for different jobs (separate tokens)
- Explore other integrations: n8n, Slack, custom webhook flows
- Read related guides:
Ready to never miss a cron failure?
Sign up for QuietPulse and protect your scheduled tasks in minutes.