How to Set Up Cron Jobs with AWS Lambda & EventBridge
Learn how to schedule AWS Lambda functions using EventBridge (CloudWatch Events) cron expressions. Covers console, CLI, CDK, SAM, and monitoring.
Prerequisites
- AWS account
- AWS CLI configured
- Basic Lambda knowledge
In this guide
How AWS Cron Scheduling Works
AWS uses Amazon EventBridge (formerly CloudWatch Events) to trigger Lambda functions on a schedule. You create a rule with a cron expression, and EventBridge invokes your Lambda function at the specified times.
AWS cron expressions use a 6-field format that includes a year field and requires the ? character for either day-of-month or day-of-week.
Quick Start: AWS Console
Step 1: Create a Lambda function in the AWS Console
Step 2: Add an EventBridge trigger:
- Go to your Lambda function → Add trigger → EventBridge
- Select "Create a new rule"
- Rule type: Schedule expression
- Expression:
cron(0 9 ? * MON-FRI *)(weekdays at 9 AM UTC)
Step 3: Save and test
You can also test immediately using the "Test" button in the Lambda console.
AWS CLI Setup
# Create the Lambda function
aws lambda create-function \
--function-name my-scheduled-task \
--runtime nodejs20.x \
--handler index.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::123456789:role/lambda-role
# Create the EventBridge rule
aws events put-rule \
--name my-schedule \
--schedule-expression "cron(0 9 ? * MON-FRI *)"
# Add Lambda as the target
aws events put-targets \
--rule my-schedule \
--targets "Id"="1","Arn"="arn:aws:lambda:us-east-1:123456789:function:my-scheduled-task"
# Grant EventBridge permission to invoke Lambda
aws lambda add-permission \
--function-name my-scheduled-task \
--statement-id my-schedule-permission \
--action lambda:InvokeFunction \
--principal events.amazonaws.com \
--source-arn arn:aws:events:us-east-1:123456789:rule/my-scheduleAWS CDK Setup
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
const fn = new lambda.Function(this, 'ScheduledFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda'),
timeout: cdk.Duration.minutes(5),
});
new events.Rule(this, 'ScheduleRule', {
schedule: events.Schedule.cron({
minute: '0',
hour: '9',
weekDay: 'MON-FRI',
}),
targets: [new targets.LambdaFunction(fn)],
});AWS Cron Expression Syntax
AWS uses a 6-field cron format:
cron(minute hour day-of-month month day-of-week year)Key differences from standard cron:
- 6 fields (includes year)
?(question mark) is required for either day-of-month or day-of-week (you can't specify both)L— last day (e.g.,Lin day-of-month = last day of month)W— nearest weekday (e.g.,15W= nearest weekday to the 15th)#— nth day (e.g.,FRI#2= second Friday)
Examples:
cron(0 9 ? * MON-FRI *)— Weekdays at 9 AM UTCcron(*/5 * ? * * *)— Every 5 minutescron(0 0 1 * ? *)— First day of every monthcron(0 12 ? * 2#1 *)— First Monday at noon
Common AWS Cron Expressions
cron(*/5 * ? * * *)— Every 5 minutescron(0 * ? * * *)— Every hourcron(0 0 ? * * *)— Daily at midnight UTCcron(0 9 ? * MON-FRI *)— Weekdays at 9 AM UTCcron(0 0 1 * ? *)— First day of every monthcron(0 0 ? * SUN *)— Every Sunday at midnightcron(0 0 L * ? *)— Last day of every month
You can also use rate expressions for simple intervals:
rate(5 minutes)rate(1 hour)rate(1 day)
Every weekday at 9:00 AM
Next runs (UTC):
Mon, May 18, 2026 09:00
Tue, May 19, 2026 09:00
Wed, May 20, 2026 09:00
Monitoring with CloudWatch
Lambda metrics to watch:
Invocations— confirms your schedule is triggeringErrors— failed invocationsDuration— execution time (watch for approaching timeout)Throttles— concurrency limit hit
Set up an alarm:
aws cloudwatch put-metric-alarm \
--alarm-name "ScheduledTaskErrors" \
--metric-name Errors \
--namespace AWS/Lambda \
--dimensions Name=FunctionName,Value=my-scheduled-task \
--statistic Sum \
--period 300 \
--threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--evaluation-periods 1 \
--alarm-actions arn:aws:sns:us-east-1:123456789:my-alertsProduction Tips
Timeout: Set your Lambda timeout higher than the expected execution time. The default is 3 seconds — increase it for cron jobs.
Dead letter queue: Configure a DLQ for failed invocations so you don't lose events:
// CDK
fn.addEventSource(new targets.LambdaFunction(fn, {
deadLetterQueue: new sqs.Queue(this, 'DLQ'),
retryAttempts: 2,
}));Cost: EventBridge rules are free. You only pay for Lambda invocations. A function running every 5 minutes with 128MB and 1-second duration costs roughly $0.10/month.
Cold starts: Scheduled Lambda functions may experience cold starts if they run infrequently. Use Provisioned Concurrency for latency-sensitive tasks.