Cron Jobs — Scheduled Serverless Task Automation

Schedule any function to run automatically using cron expressions. Monitor execution history, manage job status, and trigger manual runs.

// Database Cleanup (Daily at Midnight)

Attach the db-pool layer. Schedule with 0 0 * * *.

db-cleanup.jstypescript
// Requires layer: db-pool
const db = require('db-pool');

export const handler = async (event) => {
  const thirtyDaysAgo = new Date();
  thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
  const cutoff = thirtyDaysAgo.toISOString();

  // Purge expired sessions
  const sessions = await db.query(
    'DELETE FROM sessions WHERE expires_at < $1 RETURNING id', [cutoff]
  );

  // Clean temp uploads
  const uploads = await db.query(
    'DELETE FROM temp_uploads WHERE created_at < $1 RETURNING id', [cutoff]
  );

  // Clean old logs
  const logs = await db.query(
    'DELETE FROM function_logs WHERE created_at < $1 RETURNING id', [cutoff]
  );

  return {
    statusCode: 200,
    body: {
      sessionsDeleted: sessions.rowCount,
      uploadsDeleted: uploads.rowCount,
      logsDeleted: logs.rowCount,
      cutoffDate: cutoff,
      timestamp: new Date().toISOString()
    }
  };
};

// Health Check Monitor (Every 5 Minutes)

Ping external services and log response times. Schedule with */5 * * * *.

health-check.jstypescript
export const handler = async (event) => {
  const endpoints = [
    { name: 'Main API',    url: 'https://api.yourapp.com/health' },
    { name: 'Auth Service', url: 'https://auth.yourapp.com/ping' },
    { name: 'Payment API',  url: 'https://pay.yourapp.com/status' },
  ];

  const results = await Promise.all(
    endpoints.map(async (ep) => {
      const start = Date.now();
      try {
        const res = await fetch(ep.url, { signal: AbortSignal.timeout(5000) });
        return {
          name: ep.name,
          status: res.status,
          ok: res.ok,
          latency_ms: Date.now() - start
        };
      } catch (err) {
        return {
          name: ep.name,
          status: 0,
          ok: false,
          latency_ms: Date.now() - start,
          error: err.message
        };
      }
    })
  );

  const allHealthy = results.every(r => r.ok);

  // If any service is down, you could fire a webhook or send an alert
  if (!allHealthy) {
    const failed = results.filter(r => !r.ok);
    console.error('UNHEALTHY SERVICES:', JSON.stringify(failed));
  }

  return {
    statusCode: allHealthy ? 200 : 503,
    body: {
      healthy: allHealthy,
      checked_at: new Date().toISOString(),
      services: results
    }
  };
};

// Data Sync Pipeline (Hourly)

Pull from an external API and push into your database. Schedule with 0 * * * *.

data-sync.jstypescript
// Requires layer: db-pool
const db = require('db-pool');

export const handler = async (event) => {
  // Fetch latest data from external API
  const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=10');
  if (!res.ok) {
    return { statusCode: 502, body: { error: 'Failed to fetch source data' } };
  }
  const posts = await res.json();

  let created = 0;
  let updated = 0;
  let errors = 0;

  for (const post of posts) {
    try {
      const existing = await db.getOne(
        'SELECT id FROM synced_posts WHERE external_id = $1', [post.id]
      );

      if (existing) {
        await db.query(
          'UPDATE synced_posts SET title = $1, body = $2, synced_at = NOW() WHERE external_id = $3',
          [post.title, post.body, post.id]
        );
        updated++;
      } else {
        await db.insert('synced_posts', {
          external_id: post.id,
          title: post.title,
          body: post.body,
          user_id: post.userId,
          synced_at: new Date().toISOString()
        });
        created++;
      }
    } catch (err) {
      errors++;
      console.error('Sync error for post ' + post.id + ':', err.message);
    }
  }

  return {
    statusCode: 200,
    body: { created, updated, errors, total: posts.length, synced_at: new Date().toISOString() }
  };
};

// Daily Report Email (Weekdays 9 AM)

Attach db-pool + email-sender layers. Schedule with 0 9 * * 1-5.

daily-report.jstypescript
// Requires layers: db-pool, email-sender
const db = require('db-pool');
const mailer = require('email-sender');

export const handler = async (event) => {
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  const date = yesterday.toISOString().split('T')[0];

  // Aggregate yesterday's stats
  const stats = await db.getOne(
    'SELECT COUNT(*) as orders, COALESCE(SUM(total), 0) as revenue FROM orders WHERE created_at::date = $1',
    [date]
  );

  const newUsers = await db.getOne(
    'SELECT COUNT(*) as count FROM users WHERE created_at::date = $1', [date]
  );

  const html = '<h2>Daily Report — ' + date + '</h2>'
    + '<table style="border-collapse:collapse">'
    + '<tr><td style="padding:8px;border:1px solid #ddd"><b>Orders</b></td><td style="padding:8px;border:1px solid #ddd">' + stats.orders + '</td></tr>'
    + '<tr><td style="padding:8px;border:1px solid #ddd"><b>Revenue</b></td><td style="padding:8px;border:1px solid #ddd">$' + Number(stats.revenue).toFixed(2) + '</td></tr>'
    + '<tr><td style="padding:8px;border:1px solid #ddd"><b>New Users</b></td><td style="padding:8px;border:1px solid #ddd">' + newUsers.count + '</td></tr>'
    + '</table>';

  await mailer.send({
    to: 'team@yourcompany.com',
    subject: 'Daily Report — ' + date,
    html
  });

  return {
    statusCode: 200,
    body: { sent: true, date, orders: stats.orders, revenue: stats.revenue }
  };
};

// Cron Expression Reference

┌──── minute (0-59)
│ ┌──── hour (0-23)
│ │ ┌──── day of month (1-31)
│ │ │ ┌──── month (1-12)
│ │ │ │ ┌──── day of week (0-7)
│ │ │ │ │
* * * * *
* * * * *Every minuteHealth check pings
*/5 * * * *Every 5 minutesStatus monitoring
0 * * * *Every hourData sync pipelines
0 0 * * *Daily at midnightDatabase cleanup
0 9 * * 1-5Weekdays at 9 AMDaily reports
0 0 * * 0Sunday midnightWeekly aggregation
0 0 1 * *First of monthMonthly billing

// API Reference

GET/api/cronList all cron jobs
POST/api/cronCreate cron job
PATCH/api/cron/:idUpdate cron job
POST/api/webhooks/cron/runManually trigger a cron job