The Serverless Scheduling Problem
You've built a serverless application. It's elegant, scalable, and cost-effective. But now you need to run something on a schedule — a daily report, an hourly data sync, a price check every 5 minutes.
In traditional server environments, you'd use cron:
*/5 * * * * /usr/bin/curl https://my-app.com/task
But serverless doesn't have cron. There's no persistent server to run it on.
This page explains your options and why CronSynth is the best solution for serious scheduled workloads.
---Option 1: Platform-Native Scheduling
Most serverless platforms offer some form of scheduling:
Vercel Cron Jobs- Configured in
vercel.json - Minimum interval: 1 minute (Pro plan) or 1 day (Hobby)
- No signature verification
- No retry logic
- No external visibility
- Schedules Lambda functions
- Supports cron and rate expressions
- AWS-only, requires IAM configuration
- No webhook signing
- Schedules Workers
- Minimum interval: 1 minute
- Cloudflare-only
- No external verification
- Triggers Cloud Functions or HTTP endpoints
- Supports cron expressions
- Requires GCP setup
Platform-native schedulers work for simple cases, but they share common limitations:
1. No cryptographic verification — You can't prove the trigger came from the scheduler
2. No built-in retries — Failed executions are often just dropped
3. Platform lock-in — Each platform has its own configuration format
4. Limited observability — Hard to see execution history
5. No on-chain proof — Can't verify execution externally
For basic tasks like "clear cache daily," platform schedulers are fine. For agent workloads where reliability and verification matter, they fall short.
---Option 2: External Cron Services
Services like cron-job.org, EasyCron, or Cronitor offer web-based scheduling:
Pros:- Platform-independent
- Web dashboard for management
- Some offer basic monitoring
- Designed for humans, not machines
- API key authentication (not wallet-based)
- No cryptographic webhook signing
- No on-chain attestation
- Monthly subscription pricing
These services bridge the gap but weren't designed for autonomous agents or machine-to-machine communication.
---Option 3: CronSynth
CronSynth is purpose-built for serverless scheduled workloads, especially autonomous AI agents.
How It Works:1. Register your webhook URL and cron expression via API
2. CronSynth calls your webhook on schedule
3. Every call is HMAC-signed for verification
4. Failed calls are retried automatically
5. Executions can be attested on-chain
Why It's Better for Serverless: Cryptographic VerificationEvery webhook includes an HMAC-SHA256 signature. Your serverless function can verify the request actually came from CronSynth, not an attacker:
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
Automatic Retries
Network hiccups happen. CronSynth retries failed webhooks with exponential backoff (1s, 4s, 16s). Your scheduled task doesn't silently fail because of a momentary network issue.
Platform IndependentCronSynth triggers any HTTPS endpoint. Works with Vercel, Lambda, Workers, Cloud Functions, or any other platform. Switch providers without changing your scheduling setup.
Wallet-Based AuthenticationNo API keys to manage. Authentication happens through x402 payment sessions. Your wallet is your identity.
On-Chain AttestationEvery trigger can be logged to Base L2. Prove your scheduled tasks actually ran. Build reputation. Create audit trails.
Pay-Per-Trigger PricingFree tier for testing. $0.001 per trigger when you scale. No monthly minimums for unused capacity.
---Integration Example: Vercel
Here's how to add CronSynth-scheduled execution to a Vercel serverless function:
1. Create the Webhook Endpoint// api/scheduled-task.ts
import { createHmac, timingSafeEqual } from 'crypto';
export default async function handler(req, res) {
// Verify signature
const signature = req.headers['x-cronsynth-signature'];
const secret = process.env.CRONSYNTH_WEBHOOK_SECRET;
const payload = JSON.stringify(req.body);
const expected = createHmac('sha256', secret)
.update(payload)
.digest('hex');
const valid = timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(signature, 'hex')
);
if (!valid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Do your scheduled work
await performScheduledTask();
return res.status(200).json({ ok: true });
}
2. Register with CronSynth
curl -X POST https://cronsynth.xyz/api/schedule \
-H "Content-Type: application/json" \
-H "X-402-Session: your-session-token" \
-d '{
"webhookUrl": "https://your-app.vercel.app/api/scheduled-task",
"cron": "*/5 * * * *",
"label": "my-scheduled-task"
}'
3. Save the Webhook Secret
Add CRONSYNTH_WEBHOOK_SECRET to your Vercel environment variables.
Your function will now be called every 5 minutes with cryptographic verification.
---Integration Example: AWS Lambda
1. Create the Lambda Functionconst crypto = require('crypto');
exports.handler = async (event) => {
const body = event.body;
const signature = event.headers['x-cronsynth-signature'];
const secret = process.env.CRONSYNTH_WEBHOOK_SECRET;
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
if (signature !== expected) {
return { statusCode: 401, body: 'Invalid signature' };
}
// Do your scheduled work
await performScheduledTask();
return { statusCode: 200, body: JSON.stringify({ ok: true }) };
};
2. Expose via API Gateway
Create an API Gateway HTTP endpoint pointing to your Lambda.
3. Register with CronSynthcurl -X POST https://cronsynth.xyz/api/schedule \
-H "Content-Type: application/json" \
-H "X-402-Session: your-session-token" \
-d '{
"webhookUrl": "https://your-api-id.execute-api.region.amazonaws.com/prod/task",
"cron": "0 * * * *",
"label": "hourly-lambda-task"
}'
---
Integration Example: Cloudflare Workers
1. Create the Workerexport default {
async fetch(request, env) {
const body = await request.text();
const signature = request.headers.get('x-cronsynth-signature');
const encoder = new TextEncoder();
const key = await crypto.subtle.importKey(
'raw',
encoder.encode(env.CRONSYNTH_WEBHOOK_SECRET),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(body));
const expected = Array.from(new Uint8Array(sig))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
if (signature !== expected) {
return new Response('Invalid signature', { status: 401 });
}
// Do your scheduled work
await performScheduledTask();
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' }
});
}
};
2. Deploy and Register
Deploy the Worker, then register its URL with CronSynth.
---Comparison Table
| Feature | Vercel Cron | CloudWatch | CronSynth | |---------|-------------|------------|-----------| | Min interval | 1 min (Pro) | 1 min | 1 min | | HMAC signing | ❌ | ❌ | ✅ | | Auto retry | ❌ | Limited | ✅ | | On-chain proof | ❌ | ❌ | ✅ | | Platform independent | ❌ | ❌ | ✅ | | API-first | ❌ | ✅ | ✅ | | Wallet auth | ❌ | ❌ | ✅ | | Free tier | Limited | Limited | ✅ | ---When to Use What
Use platform-native cron when:- Simple, non-critical tasks (cache clearing, log rotation)
- You don't need verification or retries
- You're committed to a single platform
- Building autonomous agents
- Reliability and verification matter
- You want platform independence
- You need on-chain attestation
- You're building machine-to-machine systems