Convex cron jobs
/SKILLScheduled function patterns for background tasks including interval scheduling, cron expressions, job monitoring, retry strategies, and best practices
--- name: convex-cron-jobs displayName: Convex Cron Jobs description: Scheduled function patterns for background tasks including interval scheduling, cron expressions, job monitoring, retry strategies, and best practices for long-running tasks version: 1.0.0 author: Convex tags: [convex, cron, scheduling, background-jobs, automation] --- # Convex Cron Jobs Schedule recurring functions for background tasks, cleanup jobs, data syncing, and automated workflows in Convex applications. ## Documentation Sources Before implementing, do not assume; fetch the latest documentation: - Primary: https://docs.convex.dev/scheduling/cron-jobs - Scheduling Overview: https://docs.convex.dev/scheduling - Scheduled Functions: https://docs.convex.dev/scheduling/scheduled-functions - For broader context: https://docs.convex.dev/llms.txt ## Instructions ### Cron Jobs Overview Convex cron jobs allow you to schedule functions to run at regular intervals or specific times. Key features: - Run functions on a fixed schedule - Support for interval-based and cron expression scheduling - Automatic retries on failure - Monitoring via the Convex dashboard ### Basic Cron Setup ``typescript // convex/crons.ts import { cronJobs } from "convex/server"; import { internal } from "./_generated/api"; const crons = cronJobs(); // Run every hour crons.interval( "cleanup expired sessions", { hours: 1 }, internal.tasks.cleanupExpiredSessions, {} ); // Run every day at midnight UTC crons.cron( "daily report", "0 0 * * *", internal.reports.generateDailyReport, {} ); export default crons; ` ### Interval-Based Scheduling Use crons.interval for simple recurring tasks: `typescript // convex/crons.ts import { cronJobs } from "convex/server"; import { internal } from "./_generated/api"; const crons = cronJobs(); // Every 5 minutes crons.interval( "sync external data", { minutes: 5 }, internal.sync.fetchExternalData, {} ); // Every 2 hours crons.interval( "cleanup temp files", { hours: 2 }, internal.files.cleanupTempFiles, {} ); // Every 30 seconds (minimum interval) crons.interval( "health check", { seconds: 30 }, internal.monitoring.healthCheck, {} ); export default crons; ` ### Cron Expression Scheduling Use crons.cron for precise scheduling with cron expressions: `typescript // convex/crons.ts import { cronJobs } from "convex/server"; import { internal } from "./_generated/api"; const crons = cronJobs(); // Every day at 9 AM UTC crons.cron( "morning notifications", "0 9 * * *", internal.notifications.sendMorningDigest, {} ); // Every Monday at 8 AM UTC crons.cron( "weekly summary", "0 8 * * 1", internal.reports.generateWeeklySummary, {} ); // First day of every month at midnight crons.cron( "monthly billing", "0 0 1 * *", internal.billing.processMonthlyBilling, {} ); // Every 15 minutes crons.cron( "frequent sync", "*/15 * * * *", internal.sync.syncData, {} ); export default crons; ` ### Cron Expression Reference ` ┌───────────── minute (0-59) │ ┌───────────── hour (0-23) │ │ ┌───────────── day of month (1-31) │ │ │ ┌───────────── month (1-12) │ │ │ │ ┌───────────── day of week (0-6, Sunday=0) │ │ │ │ │ * * * * * ` Common patterns: - * - Every minute - 0 - Every hour - 0 0 * - Every day at midnight - 0 0 0 - Every Sunday at midnight - 0 0 1 - First day of every month - /5 * - Every 5 minutes - 0 9-17 1-5 - Every hour from 9 AM to 5 PM, Monday through Friday ### Internal Functions for Crons Cron jobs should call internal functions for security: `typescript // convex/tasks.ts import { internalMutation, internalQuery } from "./_generated/server"; import { v } from "convex/values"; // Cleanup expired sessions export const cleanupExpiredSessions = internalMutation({ args: {}, returns: v.number(), handler: async (ctx) => { const oneHourAgo = Date.now() - 60 * 60 * 1000; const expiredSessions = await ctx.db .query("sessions") .withIndex("by_lastActive") .filter((q) => q.lt(q.field("lastActive"), oneHourAgo)) .collect(); for (const session of expiredSessions) { await ctx.db.delete(session._id); } return expiredSessions.length; }, }); // Process pending tasks export const processPendingTasks = internalMutation({ args: {}, returns: v.null(), handler: async (ctx) => { const pendingTasks = await ctx.db .query("tasks") .withIndex("by_status", (q) => q.eq("status", "pending")) .take(100); for (const task of pendingTasks) { await ctx.db.patch(task._id, { status: "processing", startedAt: Date.now(), }); // Schedule the actual processing await ctx.scheduler.runAfter(0, internal.tasks.processTask, { taskId: task._id, }); } return null; }, }); ` ### Cron Jobs with Arguments Pass static arguments to cron jobs: ``typescri