How to Schedule Recurring Tasks with Cron Expressions
Need to run a task every hour, daily at midnight, or every Monday at 9 AM? AsyncQueue handles recurring background job scheduling without cron servers, systemd timers, or AWS CloudWatch Events.
Why Not Traditional Cron?
Traditional cron jobs run on a single server:
- If the server goes down, scheduled tasks stop silently
- No retry logic — if a job fails, the result is lost
- No logs or dashboard to inspect execution history
- No way to scale across multiple machines
AsyncQueue solves all four problems.
Step 1: Choose a cron schedule
Cron expressions follow the standard 5-field format:
┌───────── minute (0-59)
│ ┌───────── hour (0-23)
│ │ ┌───────── day of month (1-31)
│ │ │ ┌───────── month (1-12)
│ │ │ │ ┌───────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *
Common examples:
| Expression | Schedule |
|---|---|
*/5 * * * * | Every 5 minutes |
0 * * * * | Every hour |
0 9 * * * | Daily at 9:00 AM |
0 0 * * 1 | Every Monday at midnight |
0 0 1 * * | First of every month |
Step 2: Create a scheduled task via the API
import { AsyncQueue } from 'asyncqueue-js';
const aq = new AsyncQueue({ apiKey: process.env.ASYNCQUEUE_API_KEY });
const task = await aq.tasks.create({
callbackUrl: 'https://your-app.com/api/daily-report',
schedule: '0 9 * * *', // Every day at 9 AM
payload: { reportType: 'daily-summary' },
retries: 3,
});
console.log(`Scheduled task: ${task.id}`);
Step 3: Build your task handler endpoint
Create the endpoint that AsyncQueue invokes on each scheduled run:
app.post('/api/daily-report', async (req, res) => {
const { reportType } = req.body;
const report = await generateReport(reportType);
await sendReportEmail(report);
res.status(200).json({ success: true, reportId: report.id });
});
Step 4: Add retry configuration
If a scheduled execution fails (e.g., your database is briefly offline), retries with exponential backoff ensure the job still completes:
const task = await aq.tasks.create({
callbackUrl: 'https://your-app.com/api/daily-report',
schedule: '0 9 * * *',
payload: { reportType: 'daily-summary' },
retries: 3,
backoff: 'exponential',
backoffDelay: 5000, // 5 second initial delay
});
Retries complete before the next scheduled window, so runs never overlap.
Step 5: Monitor scheduled executions
The AsyncQueue dashboard shows:
- Next scheduled run for each recurring task
- Execution history with status, duration, and response data
- Failure alerts when a scheduled task fails all retry attempts
- Pause/resume controls to temporarily stop a schedule
Managing Scheduled Tasks
// List all scheduled tasks
const tasks = await aq.tasks.list({ type: 'scheduled' });
// Pause a schedule
await aq.tasks.pause('task_abc123');
// Resume a schedule
await aq.tasks.resume('task_abc123');
// Delete a scheduled task
await aq.tasks.delete('task_abc123');