avoid-feature-creep
Prevent feature creep when building software, apps, and AI-powered products. Use this skill when planning features, reviewing scope, building MVPs, managing…
Scheduled function patterns for background tasks including interval scheduling, cron expressions, job monitoring, retry strategies, and best practices for long-running tasks
$ npx -y skills add waynesutton/convexskills --skill convex-cron-jobs --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/convex-cron-jobsContext preview
The summary Claude sees to decide when to auto-load this skill.
Scheduled function patterns for background tasks including interval scheduling, cron expressions, job monitoring, retry strategies, and best practices for long-running tasks
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]
Schedule recurring functions for background tasks, cleanup jobs, data syncing, and automated workflows in Convex applications.
Before implementing, do not assume; fetch the latest documentation:
Convex cron jobs allow you to schedule functions to run at regular intervals or specific times. Key features:
// 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;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;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;┌───────────── minute (0-59) │ ┌───────────── hour (0-23) │ │ ┌───────────── day of month (1-31) │ │ │ ┌───────────── month (1-12) │ │ │ │ ┌───────────── day of week (0-6, Sunday=0) │ │ │ │ │ * * * * *
Common patterns:
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;
},
});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)Official Convex plugins for AI coding agents, providing development tools for building reactive backends with TypeScript.
Repo: waynesutton/convexskills
Prevent feature creep when building software, apps, and AI-powered products. Use this skill when planning features, reviewing scope, building MVPs, managing…
Building AI agents with the Convex Agent component including thread management, tool integration, streaming responses, RAG patterns, and workflow orchestration
Guidelines for building production-ready Convex apps covering function organization, query patterns, validation, TypeScript usage, error handling, and the Zen…
How to create, structure, and publish self-contained Convex components with proper isolation, exports, and dependency management
Complete file handling including upload flows, serving files via URL, storing generated files from actions, deletion, and accessing file metadata from system…
Writing queries, mutations, actions, and HTTP actions with proper argument validation, error handling, internal functions, and runtime considerations