Getting Started with cf-monitor
This guide walks you through installing cf-monitor, deploying the monitor worker, and wrapping your first Cloudflare Worker with automatic monitoring.
This guide walks you through installing cf-monitor, deploying the monitor worker, and wrapping your first Cloudflare Worker with automatic monitoring.
Prerequisites
- Node.js 22+ (also works with Node 20)
- A Cloudflare account (free or paid)
- At least one deployed Worker on the account you want to monitor
- Wrangler CLI installed (
npm install -g wrangler) - A Cloudflare API token with Workers and Analytics Engine permissions
- Optional but recommended: include
Account Settings: Readpermission for automatic plan detection (without it, cf-monitor defaults to Workers Paid plan budgets)
- Optional but recommended: include
Step 1: Install the SDK
npm install @littlebearapps/cf-monitor
This adds cf-monitor as a dependency. It includes both the runtime SDK (the monitor() wrapper) and the CLI (npx cf-monitor).
Step 2: Initialise
npx cf-monitor init --account-id YOUR_ACCOUNT_ID
This provisions two resources on your Cloudflare account:
- KV namespace (
cf-monitor) — stores circuit breaker state, budget counters, error fingerprints - Analytics Engine dataset (
cf-monitor) — stores all metrics (90-day retention, free tier)
It also generates two files:
cf-monitor.yaml— configuration (account, GitHub, Slack, budgets)wrangler.cf-monitor.jsonc— wrangler config for the monitor worker
Optional: add GitHub, Slack, and account name
If you want automatic GitHub issues for errors and Slack alerts for budget warnings:
npx cf-monitor init \
--account-id YOUR_ACCOUNT_ID \
--account-name my-project \
--github-repo owner/repo \
--slack-webhook https://hooks.slack.com/...
The --account-name flag sets a human-readable label used in alerts, error reports, and telemetry. The --github-repo and --slack-webhook values are embedded in the generated wrangler config as CF_MONITOR_CONFIG, so the monitor worker picks them up automatically on deploy.
Step 3: Deploy the monitor worker
npx cf-monitor deploy
This deploys a single worker called cf-monitor on your account. The deploy command re-reads cf-monitor.yaml and re-embeds the config, so any changes you make to the YAML are picked up on the next deploy.
This one worker handles:
- Tail events — captures errors from all tailed workers
- Cron jobs — gap detection, budget enforcement, metrics collection, worker discovery
- API endpoints — status, errors, budgets, workers
Step 4: Wire your workers
npx cf-monitor wire --apply
This scans your directory for wrangler config files and adds:
tail_consumers: [{ "service": "cf-monitor" }]— sends tail events to the monitorCF_MONITOR_KVbinding info in a comment (you add the actual binding)CF_MONITOR_AEbinding info in a comment (you add the actual binding)WORKER_NAMEvariable — set from the wrangler config’snamefield
Run without --apply first to preview changes:
npx cf-monitor wire # Preview only
npx cf-monitor wire --apply # Apply changes
Manual wiring (alternative)
Add these to each worker’s wrangler config:
{
"kv_namespaces": [
{ "binding": "CF_MONITOR_KV", "id": "YOUR_KV_ID" }
],
"analytics_engine_datasets": [
{ "binding": "CF_MONITOR_AE", "dataset": "cf-monitor" }
],
"tail_consumers": [
{ "service": "cf-monitor" }
],
"vars": {
"WORKER_NAME": "my-worker-name"
}
}
Step 5: Wrap your worker
Replace your worker’s default export with the monitor() wrapper:
// Before
export default {
async fetch(request, env, ctx) {
return new Response('Hello');
},
};
// After
import { monitor } from '@littlebearapps/cf-monitor';
export default monitor({
fetch: async (request, env, ctx) => {
return new Response('Hello');
},
});
That’s it. monitor() automatically:
- Detects your worker name, bindings, and feature IDs
- Tracks all D1, KV, R2, AI, Queue, DO, Vectorize, and Workflow operations
- Checks circuit breakers before each invocation
- Writes metrics to Analytics Engine
- Accumulates daily/monthly budget counters in KV
- Adds a health endpoint at
/_monitor/health
Step 6: Verify
After deploying your wrapped worker, verify monitoring is working:
# Check monitor health
npx cf-monitor status
# See which workers are monitored
npx cf-monitor coverage
You can also hit the monitor worker’s API directly:
GET https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/_health
GET https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/status
GET https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/workers
Step 7: Configure alerts (optional)
GitHub Issues
Set the GitHub token as a secret:
npx cf-monitor secret set GITHUB_TOKEN
# Paste your token when prompted
The token needs issues: write permission (fine-grained PAT, recommended) or repo scope (classic PAT). See Security — GitHub PAT minimum scopes for details.
Slack Alerts
npx cf-monitor secret set SLACK_WEBHOOK_URL
# Paste your Slack incoming webhook URL
GitHub Webhooks (bidirectional sync)
To sync issue close/reopen/mute events back to cf-monitor:
- Set the webhook secret:
npx cf-monitor secret set GITHUB_WEBHOOK_SECRET - In your GitHub repo, go to Settings > Webhooks > Add webhook
- Payload URL:
https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/webhooks/github - Content type:
application/json - Secret: the same value you set above
- Events: select “Issues”
Step 8: Secure admin endpoints (recommended)
The cf-monitor worker has admin endpoints for manually triggering crons and controlling circuit breakers. These require an ADMIN_TOKEN secret:
# Generate a random token
openssl rand -hex 32
# Set it on the cf-monitor worker
npx cf-monitor secret set ADMIN_TOKEN
# Paste the token when prompted
Once set, admin requests must include the token:
curl -X POST https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/admin/cron/budget-check \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Without ADMIN_TOKEN, admin endpoints return 401 Unauthorized. See Security — Admin endpoint authentication for full details.
Step 9: Check account usage (optional)
After the first hourly cron runs (~up to 60 minutes after deploy), check your account-wide CF service usage:
npx cf-monitor usage
This shows per-service usage (D1, KV, R2, Workers, AI, etc.) vs your plan’s included allowances, with colour-coded percentage bars. The data comes from Cloudflare’s GraphQL Analytics API — your existing API token already has the permissions needed.
You can also trigger usage collection immediately:
curl -X POST https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/admin/cron/collect-account-usage \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Or query the API:
GET https://cf-monitor.YOUR_SUBDOMAIN.workers.dev/usage
Usage data from the GraphQL API is approximate and should not be used as a measure for billing purposes. It updates hourly with a ~60 second aggregation delay.
Next steps
- Configuration Reference — all cf-monitor.yaml and SDK options
- Error Collection — how fingerprinting and GitHub issues work
- Budgets & Circuit Breakers — per-invocation limits and budget enforcement
- Cost Protection — how cf-monitor prevents billing surprises
- Security — admin auth, secrets, threat model
- Troubleshooting — common issues and solutions