Cron Jobs Configuration Guide
Overviewβ
This template supports three scheduling mechanisms for background jobs:
- Local -
LocalJobManagerusingsetInterval(development) - Vercel Crons - Vercel's built-in cron system (production on Vercel)
- Trigger.dev - Third-party service (optional, for large-scale directories)
Priority Order (Auto-detection)β
The system automatically selects the scheduling mode based on environment:
// From lib/background-jobs/config.ts
export function getSchedulingMode(): SchedulingMode {
// 1. Check if disabled
if (DISABLE_AUTO_SYNC === 'true') return 'disabled';
// 2. Trigger.dev (if fully configured in production)
if (shouldUseTriggerDev()) return 'trigger-dev';
// 3. Vercel (if VERCEL=1)
if (isVercelEnvironment()) return 'vercel';
// 4. Local (fallback)
return 'local';
}
π Registered Background Jobsβ
1. Repository Synchronizationβ
Job ID: repository-sync
Schedule: Every 5 minutes (*/5 * * * *)
Description: Syncs content from the Git-based CMS repository
- Vercel Endpoint:
/api/cron/sync - Local Interval:
5 * 60 * 1000ms (5 minutes) - Function:
syncManager.performSync()
2. Subscription Renewal Remindersβ
Job ID: subscription-renewal-reminder
Schedule: Daily at 9:00 AM (0 9 * * *)
Description: Sends email reminders to users with subscriptions expiring in 7 days
- Vercel Endpoint:
/api/cron/subscription-reminders - Local Cron:
0 9 * * * - Function:
subscriptionRenewalReminderJob()
3. Subscription Expiration Cleanupβ
Job ID: subscription-expired-cleanup
Schedule: Daily at midnight (0 0 * * *)
Description: Processes expired subscriptions and sends expiration notifications
- Vercel Endpoint:
/api/cron/subscription-expiration - Local Cron:
0 0 * * * - Function:
subscriptionService.processExpiredSubscriptions()
π Vercel Deployment Configurationβ
vercel.jsonβ
{
"crons": [
{
"path": "/api/cron/sync",
"schedule": "*/5 * * * *"
},
{
"path": "/api/cron/subscription-reminders",
"schedule": "0 9 * * *"
},
{
"path": "/api/cron/subscription-expiration",
"schedule": "0 0 * * *"
}
]
}
Environment Variablesβ
Required for Vercel Crons:
CRON_SECRET=your-secure-random-secret-here
Vercel automatically sends this in the Authorization: Bearer <CRON_SECRET> header when calling cron endpoints.
Optional (to disable Trigger.dev):
# Do NOT set these if you want to use Vercel Crons:
# TRIGGER_SECRET_KEY=
# TRIGGER_API_KEY=
# TRIGGER_API_URL=
β How to Verify Cron Jobs on Vercelβ
1. Check Vercel Dashboardβ
Navigate to:
https://vercel.com/<team>/<project>/settings/cron-jobs
Example:
https://vercel.com/ever-works/awesome-time-tracking-website/settings/cron-jobs
What to Look For:
- β All 3 cron jobs should be listed
- β Correct schedules (every 5 min, daily at 9am, daily at midnight)
- β Status should be "Active"
2. Check Logsβ
Navigate to:
https://vercel.com/<team>/<project>/logs
Filter by Request Path:
/api/cron/sync/api/cron/subscription-reminders/api/cron/subscription-expiration
Example:
https://vercel.com/ever-works/awesome-time-tracking-website/logs?requestPaths=%2Fapi%2Fcron%2Fsync
What to Look For:
- β Regular execution timestamps
- β 200 status codes (success)
- β No 401 errors (authentication failures)
- β No 500 errors (internal errors)
3. Check Application Logsβ
Search for these log messages:
# Initialization
[BACKGROUND_JOBS] All background jobs registered with BackgroundJobManager
# Sync job
[CRON_SYNC] Vercel cron sync triggered
[CRON_SYNC] Completed in XXXms: ...
# Renewal reminders
[Cron] Subscription reminders job completed
# Expiration cleanup
[SubscriptionExpiration] Starting expired subscription processing...
[SubscriptionExpiration] Completed: X subscriptions expired
4. Test Manually (Development)β
Test endpoints locally with curl:
# Set your CRON_SECRET
export CRON_SECRET="your-secret"
# Test sync endpoint
curl -X GET http://localhost:3000/api/cron/sync \
-H "Authorization: Bearer $CRON_SECRET"
# Test subscription reminders
curl -X GET http://localhost:3000/api/cron/subscription-reminders \
-H "Authorization: Bearer $CRON_SECRET"
# Test subscription expiration
curl -X GET http://localhost:3000/api/cron/subscription-expiration \
-H "Authorization: Bearer $CRON_SECRET"
Expected Response:
{
"success": true,
"timestamp": "2026-01-06T...",
"message": "...",
"duration": 123
}
π§ Troubleshootingβ
Cron Jobs Not Runningβ
Check 1: Environment Variables
# Verify CRON_SECRET is set in Vercel
vercel env ls
# Should show:
# CRON_SECRET (Production, Preview, Development)
Check 2: Deployment
# Ensure vercel.json is deployed
git status
git log --oneline -1 -- vercel.json
# Verify last deployment includes vercel.json changes
Check 3: Logs
# Check for errors in Vercel logs
vercel logs --follow
401 Unauthorized Errorsβ
Problem: CRON_SECRET mismatch
Solution:
- Verify
CRON_SECRETin Vercel environment variables - Redeploy the project after updating env vars
- Check that the secret doesn't have trailing spaces
Jobs Running Too Frequentlyβ
Problem: Using Local mode instead of Vercel mode
Check:
// Should log "vercel" in production on Vercel
console.log(getSchedulingMode());
Solution:
- Ensure
VERCEL=1is set (Vercel does this automatically) - Check that Trigger.dev env vars are NOT set
π Migration Guideβ
From Local to Vercelβ
- Add cron jobs to
vercel.json(already done) - Set
CRON_SECRETin Vercel dashboard - Deploy to Vercel
- Verify in logs
From Vercel to Trigger.devβ
- Create Trigger.dev account at https://trigger.dev
- Set environment variables:
TRIGGER_SECRET_KEY=tr_prod_...
TRIGGER_API_KEY=...
TRIGGER_API_URL=https://api.trigger.dev
TRIGGER_ENABLED=true - Redeploy
- System automatically switches to Trigger.dev mode
From Trigger.dev Back to Vercelβ
- Remove Trigger.dev environment variables:
vercel env rm TRIGGER_SECRET_KEY production
vercel env rm TRIGGER_API_KEY production
vercel env rm TRIGGER_API_URL production
vercel env rm TRIGGER_ENABLED production - Redeploy
- System automatically falls back to Vercel mode
π Monitoring & Analyticsβ
Key Metrics to Trackβ
-
Execution Frequency
- Sync: Should run every 5 minutes (288 times/day)
- Reminders: Should run once per day at 9:00 AM
- Expiration: Should run once per day at midnight
-
Success Rate
- Target: > 99% success rate
- Monitor 401 errors (auth issues)
- Monitor 500 errors (application issues)
-
Duration
- Sync: < 30 seconds typical
- Reminders: Depends on user count
- Expiration: Depends on subscription count
Setting Up Alertsβ
Vercel Monitoring:
- Go to Project β Monitoring
- Set up alerts for:
- Error rate > 5%
- Duration > 30s (for sync)
- 4XX/5XX responses
π Related Filesβ
vercel.json- Vercel cron configurationlib/background-jobs/config.ts- Scheduling mode detectionlib/background-jobs/initialize-jobs.ts- Job registrationlib/background-jobs/local-job-manager.ts- Local schedulinglib/background-jobs/trigger-dev-job-manager.ts- Trigger.dev integrationapp/api/cron/*/route.ts- Cron endpoint implementations
π€ Supportβ
For issues or questions:
- Check logs in Vercel dashboard
- Review this documentation
- Contact the development team
- Open an issue in the repository
Last Updated: January 6, 2026
Version: 1.0.0