The Cron module enables scheduled execution of functions using cron expressions. Perfect for periodic tasks like cleanup jobs, reports, and background processing.
Configuration
Configure the Cron module in config.yaml:
modules :
- class : modules::cron::CronModule
config :
adapter :
class : modules::cron::KvCronAdapter
Available Adapters
KvCronAdapter (Default)
Redis
File-based or in-memory storage: adapter :
class : modules::cron::KvCronAdapter
Distributed cron using Redis: adapter :
class : modules::cron::RedisAdapter
config :
redis_url : redis://localhost:6379
Creating Scheduled Functions
Define cron triggers with standard cron expressions:
export default iii ({
triggers: {
'daily-cleanup' : {
type: 'cron' ,
config: {
expression: '0 0 * * *' , // Every day at midnight
},
},
'hourly-sync' : {
type: 'cron' ,
config: {
expression: '0 * * * *' , // Every hour
},
},
'every-5-minutes' : {
type: 'cron' ,
config: {
expression: '*/5 * * * *' , // Every 5 minutes
},
},
} ,
}) ;
export async function dailyCleanup () {
console . log ( 'Running daily cleanup' );
await cleanupOldData ();
}
export async function hourlySync () {
console . log ( 'Syncing data' );
await syncWithExternalAPI ();
}
export async function every5Minutes () {
console . log ( 'Health check' );
await performHealthCheck ();
}
Cron expressions use the standard 5-field format:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday = 0)
│ │ │ │ │
* * * * *
Common Cron Patterns
Every Minute
Every Hour
Every Day at Midnight
Every Week (Sunday)
Every Month (1st day)
Business Hours (9 AM - 5 PM)
Every 15 Minutes
Every 6 Hours
Cron-triggered functions receive timing information:
export async function scheduledTask ( input : any ) {
console . log ( 'Execution time:' , input . timestamp );
console . log ( 'Cron expression:' , input . expression );
// Your scheduled logic here
}
Input structure:
{
timestamp : number ; // Unix timestamp of execution
expression : string ; // Cron expression that triggered this
}
Conditional Execution
Use conditions to control whether a scheduled task should run:
export default iii ({
triggers: {
'weekday-report' : {
type: 'cron' ,
config: {
expression: '0 9 * * *' , // Every day at 9 AM
},
condition : async ( input ) => {
const day = new Date (). getDay ();
return day >= 1 && day <= 5 ; // Monday-Friday only
},
},
} ,
}) ;
Example Use Cases
Daily Database Cleanup
export default iii ({
triggers: {
'cleanup-old-logs' : {
type: 'cron' ,
config: {
expression: '0 2 * * *' , // 2 AM daily
},
},
} ,
}) ;
export async function cleanupOldLogs () {
const thirtyDaysAgo = Date . now () - 30 * 24 * 60 * 60 * 1000 ;
// Delete logs older than 30 days
const logs = await state . list ({ scope: 'logs' });
for ( const [ key , log ] of Object . entries ( logs )) {
if ( log . timestamp < thirtyDaysAgo ) {
await state . delete ({ scope: 'logs' , key });
}
}
console . log ( 'Old logs cleaned up' );
}
Hourly Data Sync
export default iii ({
triggers: {
'sync-external-data' : {
type: 'cron' ,
config: {
expression: '0 * * * *' , // Every hour
},
},
} ,
}) ;
export async function syncExternalData () {
// Fetch data from external API
const response = await fetch ( 'https://api.example.com/data' );
const data = await response . json ();
// Store in state
await state . set ({
scope: 'cache' ,
key: 'external_data' ,
value: data ,
});
console . log ( 'Data synced successfully' );
}
Weekly Reports
export default iii ({
triggers: {
'weekly-report' : {
type: 'cron' ,
config: {
expression: '0 9 * * 1' , // Every Monday at 9 AM
},
},
} ,
}) ;
export async function weeklyReport () {
// Generate report for last week
const startDate = new Date ();
startDate . setDate ( startDate . getDate () - 7 );
const metrics = await collectMetrics ( startDate );
const report = generateReport ( metrics );
// Send report via email
await queue . enqueue ({
topic: 'emails.send' ,
data: {
to: 'team@example.com' ,
subject: 'Weekly Report' ,
body: report ,
},
});
}
Periodic Health Checks
export default iii ({
triggers: {
'health-check' : {
type: 'cron' ,
config: {
expression: '*/5 * * * *' , // Every 5 minutes
},
},
} ,
}) ;
export async function healthCheck () {
const checks = [
{ name: 'Database' , url: 'http://db:5432/health' },
{ name: 'Redis' , url: 'http://redis:6379/ping' },
{ name: 'API' , url: 'http://api:3000/health' },
];
for ( const check of checks ) {
try {
const response = await fetch ( check . url );
if ( ! response . ok ) {
await queue . enqueue ({
topic: 'alerts' ,
data: { service: check . name , status: 'unhealthy' },
});
}
} catch ( error ) {
console . error ( ` ${ check . name } health check failed:` , error );
}
}
}
Timezone Considerations
Cron expressions run in the server’s timezone. For UTC-based scheduling, ensure your server timezone is set to UTC or convert times accordingly.
Example for timezone-aware scheduling:
export async function scheduledTask () {
const now = new Date ();
const utcHour = now . getUTCHours ();
// Only run during specific UTC hours
if ( utcHour >= 9 && utcHour <= 17 ) {
await performTask ();
}
}
Best Practices
Idempotent Functions : Make sure cron functions can safely run multiple times
Error Handling : Always handle errors gracefully
Monitoring : Log execution times and results
Avoid Overlaps : Ensure tasks complete before next scheduled run
Use Conditions : Filter execution based on business rules
Debugging Cron Jobs
View registered cron jobs in logs:
# Check logs for cron registration
grep "REGISTERED.*cron" logs/iii.log
# Example output:
# [REGISTERED] Cron trigger daily-cleanup (0 0 * * *) → cleanup.run
Source Code Reference
Module: src/modules/cron/cron.rs:29
Trigger registration: src/modules/cron/cron.rs:88
Adapters: src/modules/cron/adapters/