cloudflare-cron-triggers
Complete knowledge domain for Cloudflare Cron Triggers - scheduled execution of Workers using cron expressions for periodic tasks, maintenance jobs, and automated workflows. Use when: scheduling Workers to run periodically, adding cron triggers to Workers, configuring scheduled tasks, testing cron handlers, combining crons with Workflows, enabling Green Compute, handling multiple schedules, or encountering "scheduled handler not found", "cron expression invalid", "changes not propagating", "handler does not export", "timezone issues" errors. Keywords: cloudflare cron, cron triggers, scheduled workers, scheduled handler, periodic tasks, background jobs, scheduled tasks, cron expression, wrangler crons, scheduled event, green compute, workflow triggers, maintenance tasks, scheduled() handler, ScheduledController, UTC timezone
What this skill does
# Cloudflare Cron Triggers **Status**: Production Ready ✅ **Last Updated**: 2025-10-23 **Dependencies**: cloudflare-worker-base (for Worker setup) **Latest Versions**: [email protected], @cloudflare/[email protected] --- ## Quick Start (5 Minutes) ### 1. Add Scheduled Handler to Your Worker **src/index.ts:** ```typescript export default { async scheduled( controller: ScheduledController, env: Env, ctx: ExecutionContext ): Promise<void> { console.log('Cron job executed at:', new Date(controller.scheduledTime)); console.log('Triggered by cron:', controller.cron); // Your scheduled task logic here await doPeriodicTask(env); }, }; ``` **Why this matters:** - Handler must be named exactly `scheduled` (not `scheduledHandler` or `onScheduled`) - Must be exported in default export object - Must use ES modules format (not Service Worker format) ### 2. Configure Cron Trigger in Wrangler **wrangler.jsonc:** ```jsonc { "name": "my-scheduled-worker", "main": "src/index.ts", "compatibility_date": "2025-10-23", "triggers": { "crons": [ "0 * * * *" // Every hour at minute 0 ] } } ``` **CRITICAL:** - Cron expressions use 5 fields: `minute hour day-of-month month day-of-week` - All times are **UTC only** (no timezone conversion) - Changes take **up to 15 minutes** to propagate globally ### 3. Test Locally ```bash # Enable scheduled testing npx wrangler dev --test-scheduled # In another terminal, trigger the scheduled handler curl "http://localhost:8787/__scheduled?cron=0+*+*+*+*" # View output in wrangler dev terminal ``` **Testing tips:** - `/__scheduled` endpoint is only available with `--test-scheduled` flag - Can pass any cron expression in query parameter - Python Workers use `/cdn-cgi/handler/scheduled` instead ### 4. Deploy ```bash npm run deploy # or npx wrangler deploy ``` **After deployment:** - Changes may take up to 15 minutes to propagate - Check dashboard: Workers & Pages > [Your Worker] > **Cron Triggers** - View past executions in **Logs** tab --- ## Cron Expression Syntax ### Five-Field Format ``` * * * * * │ │ │ │ │ │ │ │ │ └─── Day of Week (0-6, Sunday=0) │ │ │ └───── Month (1-12) │ │ └─────── Day of Month (1-31) │ └───────── Hour (0-23) └─────────── Minute (0-59) ``` ### Special Characters | Character | Meaning | Example | |-----------|---------|---------| | `*` | Every | `* * * * *` = every minute | | `,` | List | `0,30 * * * *` = every hour at :00 and :30 | | `-` | Range | `0 9-17 * * *` = every hour from 9am-5pm | | `/` | Step | `*/15 * * * *` = every 15 minutes | ### Common Patterns ```bash # Every minute * * * * * # Every 5 minutes */5 * * * * # Every 15 minutes */15 * * * * # Every hour at minute 0 0 * * * * # Every hour at minute 30 30 * * * * # Every 6 hours 0 */6 * * * # Every day at midnight (00:00 UTC) 0 0 * * * # Every day at noon (12:00 UTC) 0 12 * * * # Every day at 3:30am UTC 30 3 * * * # Every Monday at 9am UTC 0 9 * * 1 # Every weekday at 9am UTC 0 9 * * 1-5 # Every Sunday at midnight UTC 0 0 * * 0 # First day of every month at midnight UTC 0 0 1 * * # Twice a day (6am and 6pm UTC) 0 6,18 * * * # Every 30 minutes during business hours (9am-5pm UTC, weekdays) */30 9-17 * * 1-5 ``` **CRITICAL: UTC Timezone Only** - All cron triggers execute on **UTC time** - No timezone conversion available - Convert your local time to UTC manually - Example: 9am PST = 5pm UTC (next day during DST) --- ## ScheduledController Interface ```typescript interface ScheduledController { readonly cron: string; // The cron expression that triggered this execution readonly type: string; // Always "scheduled" readonly scheduledTime: number; // Unix timestamp (ms) when scheduled } ``` ### Properties #### `controller.cron` (string) The cron expression that triggered this execution. ```typescript export default { async scheduled(controller: ScheduledController, env: Env): Promise<void> { console.log(`Triggered by: ${controller.cron}`); // Output: "Triggered by: 0 * * * *" }, }; ``` **Use case:** Differentiate between multiple cron schedules (see Multiple Cron Triggers pattern). #### `controller.type` (string) Always returns `"scheduled"` for cron-triggered executions. ```typescript if (controller.type === 'scheduled') { // This is a cron-triggered execution } ``` #### `controller.scheduledTime` (number) Unix timestamp (milliseconds since epoch) when this execution was scheduled to run. ```typescript export default { async scheduled(controller: ScheduledController): Promise<void> { const scheduledDate = new Date(controller.scheduledTime); console.log(`Scheduled for: ${scheduledDate.toISOString()}`); // Output: "Scheduled for: 2025-10-23T15:00:00.000Z" }, }; ``` **Note:** This is the **scheduled** time, not the actual execution time. Due to system load, actual execution may be slightly delayed (usually <1 second). --- ## Execution Context ```typescript export default { async scheduled( controller: ScheduledController, env: Env, ctx: ExecutionContext // ← Execution context ): Promise<void> { // Use ctx.waitUntil() for async operations that should complete ctx.waitUntil(logToAnalytics(env)); }, }; ``` ### `ctx.waitUntil(promise: Promise<any>)` Extends the execution context to wait for async operations to complete after the handler returns. **Use cases:** - Logging to external services - Analytics tracking - Cleanup operations - Non-critical background tasks ```typescript export default { async scheduled(controller: ScheduledController, env: Env, ctx: ExecutionContext): Promise<void> { // Critical task - must complete before handler exits await processData(env); // Non-critical tasks - can complete in background ctx.waitUntil(sendMetrics(env)); ctx.waitUntil(cleanupOldData(env)); ctx.waitUntil(notifySlack({ message: 'Cron completed' })); }, }; ``` **Important:** First `waitUntil()` that fails will be reported as the status in dashboard logs. --- ## Integration Patterns ### 1. Standalone Scheduled Worker **Best for:** Workers that only run on schedule (no HTTP requests) ```typescript // src/index.ts interface Env { DB: D1Database; MY_BUCKET: R2Bucket; } export default { async scheduled( controller: ScheduledController, env: Env, ctx: ExecutionContext ): Promise<void> { console.log('Running scheduled maintenance...'); // Database cleanup await env.DB.prepare('DELETE FROM sessions WHERE expires_at < ?') .bind(Date.now()) .run(); // Generate daily report const report = await generateDailyReport(env.DB); // Upload to R2 await env.MY_BUCKET.put( `reports/${new Date().toISOString().split('T')[0]}.json`, JSON.stringify(report) ); console.log('Maintenance complete'); }, }; ``` --- ### 2. Combined with Hono (Fetch + Scheduled) **Best for:** Workers that handle both HTTP requests and scheduled tasks ```typescript // src/index.ts import { Hono } from 'hono'; interface Env { DB: D1Database; } const app = new Hono<{ Bindings: Env }>(); // Regular HTTP routes app.get('/', (c) => c.text('Worker is running')); app.get('/api/stats', async (c) => { const stats = await c.env.DB.prepare('SELECT COUNT(*) as count FROM users').first(); return c.json(stats); }); // Export both fetch handler and scheduled handler export default { // Handle HTTP requests fetch: app.fetch, // Handle cron triggers async scheduled( controller: ScheduledController, env: Env, ctx: ExecutionContext ): Promise<void> { console.log('Cron triggered:', controller.cron); // Run scheduled task await updateCache(env.DB); // Log completion ctx.waitUntil(logExecution(controller.scheduledTime)); }, }; ``` **Why this pattern:** - One Worker handles both use cases - Share environment bindings - Reduce number of Workers to manage - Low
Related in Cloud & DevOps
appbuilder-action-scaffolder
IncludedCreate, implement, deploy, and debug Adobe Runtime actions with consistent layout, validation, and error handling. Use this skill whenever the user needs to add actions to an App Builder project, understand action structure (params, response format, web/raw actions), configure actions in the manifest, use App Builder SDKs (State, Files, Events, database), deploy and invoke actions via CLI, debug action issues, or implement patterns such as webhook receivers, custom event providers, journaling consumers, large payload redirects, action sequence pipelines, and Asset Compute workers. Also trigger when users mention serverless functions in Adobe context, action logging, IMS authentication for actions, or cron-style scheduled actions.
orchestrating-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. Use this skill when the user needs a multi-step Data Cloud pipeline, cross-phase troubleshooting, or data space and data kit management. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase sf data360 workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching phase-specific skill), the task is STDM/session tracing/parquet telemetry (use observing-agentforce), standard CRM SOQL (use querying-soql), or Apex implementation (use generating-apex).
github-project-automation
IncludedAutomate GitHub repository setup with CI/CD workflows, issue templates, Dependabot, and CodeQL security scanning. Includes 12 production-tested workflows and prevents 18 errors: YAML syntax, action pinning, and configuration. Use when: setting up GitHub Actions CI/CD, creating issue/PR templates, enabling Dependabot or CodeQL scanning, deploying to Cloudflare Workers, implementing matrix testing, or troubleshooting YAML indentation, action version pinning, secrets syntax, runner versions, or CodeQL configuration. Keywords: github actions, github workflow, ci/cd, issue templates, pull request templates, dependabot, codeql, security scanning, yaml syntax, github automation, repository setup, workflow templates, github actions matrix, secrets management, branch protection, codeowners, github projects, continuous integration, continuous deployment, workflow syntax error, action version pinning, runner version, github context, yaml indentation error
sf-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase `sf data360` workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching sf-datacloud-* skill), the task is STDM/session tracing/parquet telemetry (use sf-ai-agentforce-observability), standard CRM SOQL (use sf-soql), or Apex implementation (use sf-apex).
fabric-cli
IncludedUse this skill for Fabric.so CLI workflows with the `fabric` terminal command: diagnose/install/login, search or browse a Fabric library, save notes/links/files, create folders, ask the Fabric AI assistant, manage tasks/workspaces, generate shell completion, check subscription usage, produce JSON output, and use Fabric as persistent agent memory. Do not use for Microsoft Fabric/Azure/Power BI `fab`, Daniel Miessler's Fabric framework, Python Fabric SSH, Fabric.js, or textile/fashion fabric.
lark
IncludedLark/Feishu CLI skills: lark-cli operations for docs, markdown, sheets, base, calendar, im, mail, task, okr, drive, wiki, slides, whiteboard, apps, approval, attendance, contact, vc, minutes, event. Use when the user needs to operate Lark/Feishu resources via lark-cli, send messages, manage documents, spreadsheets, calendars, tasks, OKRs, deploy web pages, or any Feishu/Lark workspace operations.