convex-cron-jobs
Scheduled function patterns for background tasks including interval scheduling, cron expressions, job monitoring, retry strategies, and best practices for long-running tasks
DeepseekModel
Curated skill
Quality Excellent · 78
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=waynesutton-convexskills-skills-convex-cron-jobs-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
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 // 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: // 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: // 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: // 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: // convex/crons.ts import { cronJobs } from "convex/server" ; import { internal } from "./_generated/api" ; const crons = cronJobs (); // Different cleanup intervals for different types crons. interval ( "cleanup temp files" , { hours : 1 }, internal. cleanup . cleanupByType , { fileType : "temp" , maxAge : 3600000 } ); crons. interval ( "cleanup cache files" , { hours : 24 }, internal. cleanup . cleanupByType , { fileType : "cache" , maxAge : 86400000 } ); export default crons; // convex/cleanup.ts import { internalMutation } from "./_generated/server" ; import { v } from "convex/values" ; export const cleanupByType = internalMutation ({ args : { fileType : v. string (), maxAge : v. number (), }, returns : v. number (), handler : async (ctx, args) => { const cutoff = Date . now () - args. maxAge ; const oldFiles = await ctx. db . query ( "files" ) . withIndex ( "by_type_and_created" , ( q ) => q. eq ( "type" , args. fileType ). lt ( "createdAt" , cutoff) ) . collect (); for ( const file of oldFiles) { await ctx. storage . delete (file. storageId ); await ctx. db . delete (file. _id ); } return oldFiles. length ; }, }); Monitoring and Logging Add logging to track cron job execution: // convex/tasks.ts import { internalMutation } from "./_generated/server" ; import { v } from "convex/values" ; export const cleanupWithLogging = internalMutation ({ args : {}, returns : v. null (), handler : async (ctx) => { const startTime = Date . now (); let processedCount = 0 ; let errorCount = 0 ; try { const expiredItems = await ctx. db . query ( "items" ) . withIndex ( "by_expiresAt" ) . filter ( ( q ) => q. lt (q. field ( "expiresAt" ), Date . now ())) . collect (); for ( const item of expiredItems) { try { await ctx. db . delete (item. _id ); processedCount++; } catch (error) { errorCount++; console . error ( `Failed to delete item ${item._id} :` , error); } } // Log job completion await ctx. db . insert ( "cronLogs" , { jobName : "cleanup" , startTime, endTime : Date . now (), duration : Date . now () - startTime, processedCount, errorCount, status : errorCount === 0 ? "success" : "partial" , }); } catch (error) { // Log job failure await ctx. db . insert ( "cronLogs" , { jobName : "cleanup" , startTime, endTime : Date . now (), duration : Date . now () - startTime, processedCount, errorCount, status : "failed" , error : String (error), }); throw error; } return null ; }, }); Batching for Large Datasets Handle large datasets in batches to avoid timeouts: // convex/tasks.ts import { internalMutation } from "./_generated/server" ; import { internal } from "./_generated/api" ; import { v } from "convex/values" ; const BATCH_SIZE = 100 ; export const processBatch = internalMutation ({ args : { cursor : v. optional (v. string ()), }, returns : v. null (), handler : async (ctx, args) => { const result = await ctx. db . query ( "items" ) . withIndex ( "by_status" , ( q ) => q. eq ( "status" , "pending" )) . paginate ({ numItems : BATCH_SIZE , cursor : args. cursor ?? null }); for ( const item of result. page ) { await ctx. db . patch (item. _id , { status : "processed" , processedAt : Date . now (), }); } // Schedule next batch if there are more items if (!result. isDone ) { await ctx. scheduler . runAfter ( 0 , internal. tasks . processBatch , { cursor : result. continueCursor , }); } return null ; }, }); External API Calls in Crons Use actions for external API calls: // convex/sync.ts "use node" ; import { internalAction } from "./_generated/server" ; import { internal } from "./_generated/api" ; import { v } from "convex/values" ; export const syncExternalData = internalAction ({ args : {}, returns : v. null (), handler : async (ctx) => { // Fetch from external API const response = await fetch ( "https://api.example.com/data" , { headers : { Authorization : `Bearer ${process.env.API_KEY} ` , }, }); if (!response. ok ) { throw new Error ( `API request failed: ${response.status} ` ); } const data = await response. json (); // Store the data using a mutation await ctx. runMutation (internal. sync . storeExternalData , { data, syncedAt : Date . now (), }); return null ; }, }); export const storeExternalData = internalMutation ({ args : { data : v. any (), syncedAt : v. number (), }, returns : v. null (), handler : async (ctx, args) => { await ctx. db . insert ( "externalData" , { data : args. data , syncedAt : args. syncedAt , }); return null ; }, }); // convex/crons.ts import { cronJobs } from "convex/server" ; import { internal } from "./_generated/api" ; const crons = cronJobs (); crons. interval ( "sync external data" , { minutes : 15 }, internal. sync . syncExternalData , {} ); export default crons; Examples Schema for Cron Job Logging // convex/schema.ts import { defineSchema, defineTable } from "convex/server" ; import { v } from "convex/values" ; export default defineSchema ({ cronLogs : defineTable ({ jobName : v. string (), startTime : v. number (), endTime : v. number (), duration : v. number (), processedCount : v. number (), errorCount : v. number (), status : v. union ( v. literal ( "success" ), v. literal ( "partial" ), v. literal ( "failed" ) ),
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.