The Master Scheduler for Cloudflare Workers

Cron-icles is an independent, stateless Cloudflare Worker designed to manage scheduled jobs across an entire ecosystem of microservices, bypassing platform limits on Cron Triggers.


The Problem & Solution

Cloudflare places strict limits on the number of Workers that can run scheduled jobs (Cron Triggers) within a single account. As a microservice ecosystem grows, hitting this limit prevents new services from executing time-based or recurring background tasks.

Cron-icles solves this by abstracting the scheduling layer into a single, highly reliable independent service. It acts as the definitive master clock. Instead of configuring Cron Triggers on individual workers, workers register themselves with Cron-icles and dynamically schedule tasks through its HTTP API.

Core Features

Centralized Scheduling

Manage infinite scheduled jobs across unlimited workers from one central hub, freeing up account limits.

Strict Security

Registration requires an Admin Secret. Job dispatching is cryptographically verified via a shared Worker Secret.

Idempotency Guaranteed

Robust task creation ensures no job is saved twice, preventing duplicate executions at the source.

Guaranteed Dispatch

Utilizes Cloudflare Queues with exponential backoff retries to gracefully handle traffic spikes and network failures.

Architecture

Cron-icles operates entirely on Cloudflare's serverless infrastructure:

  • Framework: Hono (Ultra-fast web framework).
  • Database (D1): Stores the Worker Registry and pending tasks. Used for rapid, SQL-based maturity querying and idempotency checks.
  • Queueing (Cloudflare Queues): When the Cron Trigger fires every minute, mature tasks are offloaded to a Queue for asynchronous, backpressure-managed HTTP dispatching.

Operator Guide: Deployment Setup

Cron-icles is built to be deployed instantly into your own Cloudflare account. It serves as an infrastructure primitive for your organization.

1. Prerequisites

  • Node.js (v18+)
  • Cloudflare Account
  • Wrangler CLI installed globally and authenticated

2. Infrastructure Provisioning

First, clone the repository and create the required D1 database:

bash
npx wrangler d1 create cron-icles-db

Take note of the database_id output by this command. Open apps/worker/wrangler.jsonc and replace the existing ID in the d1_databases section with your actual ID.

Then, apply the database schema migrations to the remote D1 instance:

bash
npx wrangler d1 execute cron-icles-db --remote --file=./migrations/0000_init_cron_icles_schema.sql

3. Security Configuration

You must define an ADMIN_SECRET. This secret is required to register new client workers with Cron-icles. Never commit this to version control.

bash
npx wrangler secret put ADMIN_SECRET

4. Deployment

Deploy the service to your Cloudflare account using Turborepo:

bash
npm run deploy

Developer Guide: Client Integration

Once Cron-icles is running, your other Workers (Clients) can integrate with it.

Step 1: Register a Target Worker

Before a worker can schedule jobs, an Administrator must whitelist it via the API.

POST /api/workers/register
Header: X-Admin-Secret: <YOUR_ADMIN_SECRET>
json
{
  "id": "my-billing-service",
  "name": "Billing Service Worker",
  "webhookUrl": "https://billing.my-app.workers.dev/internal/cron-handler",
  "authSecret": "super-secret-billing-key-123"
}

Note: The authSecret is used by the Client Worker to prove its identity when scheduling, and for Cron-icles to prove its identity when dispatching back.

Step 2: Schedule a Task (Outbound)

Your registered Client Worker can now schedule events.

POST /api/tasks/schedule
Header: X-Worker-Secret: super-secret-billing-key-123
json
{
  "idempotencyKey": "uuid-v4-or-unique-string",
  "targetWorkerId": "my-billing-service",
  "executeAt": "2026-10-31T23:59:00.000Z",
  "payload": {
    "action": "send_invoice",
    "invoiceId": "INV-789"
  }
}

Step 3: Handle the Dispatch (Inbound)

When executeAt matures, Cron-icles will POST back to your worker's webhookUrl.

Your Worker's Responsibility

  • Verify AuthenticityEnsure X-Cron-Icles-Auth matches your secret. If not, return 401.
  • Handle IdempotencyUse X-Idempotency-Key to ensure you don't process the exact same event twice (in case of network retries).
  • Acknowledge ProcessingReturn a 200 OK status. If you return a 5xx or timeout, Cron-icles will automatically retry up to 3 times before failing the job permanently.

Example Hono Implementation:

typescript
app.post('/internal/cron-handler', async (c) => {
  const authHeader = c.req.header('X-Cron-Icles-Auth');
  if (!authHeader || authHeader !== c.env.CRON_ICLES_AUTH_SECRET) {
    return c.json({ error: 'Unauthorized' }, 401);
  }

  const idempotencyKey = c.req.header('X-Idempotency-Key');
  const payload = await c.req.json();

  try {
    await processTaskLogic(payload.action, payload.userId);
    return c.json({ status: 'success' }, 200);
  } catch (error) {
    // Return 500 to trigger Cron-icles automatic retry logic
    return c.json({ error: 'Internal processing error' }, 500);
  }
});