Schedule Lambda Tasks with EventBridge

Learn to use EventBridge to schedule Lambda tasks in this AWS Cloud & DevOps with Python tutorial. Hands-on steps, troubleshooting, and what to study next.

Focus: use eventbridge to schedule lambda tasks

Sponsored

You've built your Lambda functions and maybe even invoked them, but what happens when you need a job to run at 2 AM, every weekday, or on the first day of every month? Manually triggering Lambda functions is fine for testing, but it's a dead end for real-world automation. If you rely on cron jobs on a single EC2 instance, you're asking for a single point of failure. In this lesson, you'll learn how to use EventBridge to schedule Lambda tasks — a fully managed, serverless way to run Python code on a schedule, with no servers to patch and no cron daemon to babysit.

The problem this lesson solves

Scheduled tasks are everywhere in cloud applications: sending daily digest emails, cleaning up stale S3 objects, syncing data from an external API every hour, or generating nightly reports. The naive approach is to run a cron job on an EC2 instance. That works until the instance dies, you forget to update the cron line, or you need to scale to multiple environments. Another tempting shortcut is to keep a Python script running in a while True: loop with time.sleep(). That eats compute, complicates deployment, and still breaks on reboots.

None of these approaches give you observability, retry logic, or permission boundaries out of the box. You end up hand-rolling all of that. The better answer is to schedule Lambda tasks with Amazon EventBridge — a fully managed event bus service. You define a rule with a schedule expression, attach your Lambda function as a target, and AWS handles the rest. If the invocation fails, CloudWatch Logs captures it, and you can configure retries. You get the reliability of AWS infrastructure with none of the operational overhead.

Core concept / mental model

Think of EventBridge as a post office for events. Your Lambda function is a mailbox that only receives mail when a specific event arrives. A schedule rule is like a standing order: "Deliver this message every hour at minute 5." When the clock matches the rule, EventBridge creates a JSON event and delivers it to your Lambda function. Your function runs, does its work, and finishes — no server stays warm, no process lingers.

Key terms you'll see everywhere:

Term Meaning
EventBridge Rule A named configuration that defines when (schedule or pattern) and where (targets) events are delivered.
Schedule expression Either a rate expression like rate(5 minutes) or a cron expression like cron(0 2 * * ? *).
Target An AWS resource (here, a Lambda function) that receives the event.
Event The JSON payload EventBridge sends to the target.
Event Bus The default bus handles account events; custom buses for your own events.

A mental picture: you set a cron expression on an EC2 machine, and the OS's cron daemon fires your script. Replace that with a rule in EventBridge that fires a JSON event to your Lambda function. The cron syntax is similar, but the execution environment is fully managed and integrated with IAM, CloudWatch, and X-Ray.

How it works step by step

Here's the end-to-end flow — from schedule definition to Lambda execution:

  1. Choose or create a Lambda function — write the Python handler that will do the scheduled work.
  2. Define an EventBridge rule — set the schedule expression (rate or cron) that determines when events are emitted.
  3. Attach the Lambda function as a target — the rule needs to know where to send the event.
  4. Grant permissions — EventBridge needs permission to invoke your Lambda. The AWS console does this automatically when you add the target; with CLI/CDK you'll add a resource-based policy.
  5. Configure error handling — set a dead-letter queue (DLQ) or destination for failed invocations, and decide on retries.
  6. Test and monitor — invoke the rule manually or wait for the next scheduled time, then check CloudWatch Logs for your function's output.

Pro tip: Always set up a dead-letter queue or a Lambda destination to catch failed invocations. Otherwise, silent failures can go unnoticed for days in production.

Hands-on walkthrough

1. Create the Lambda function

Write a simple Python function that simulates a real task, like cleaning up old files. We'll log a message so we can verify the schedule works.

# lambda_function.py
import json
from datetime import datetime
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    """
    Triggered by an EventBridge schedule rule.
    The event contains a `time` field set by EventBridge.
    """
    scheduled_time = event.get("time", datetime.now().isoformat())

    # Fake cleanup: delete files older than 30 days in a bucket
    # In production, you'd call S3 or another service here.
    logger.info(f"Running scheduled cleanup at {scheduled_time}")

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "Cleanup completed",
            "scheduled_time": scheduled_time
        })
    }

Deploy this as a Lambda function (e.g., scheduled-cleanup) using your preferred method — AWS console, aws lambda create-function, or SAM/CDK. Note the function's ARN — you'll need it later.

2. Create an EventBridge rule (via CLI)

Create a rule with a rate expression that fires every 5 minutes for testing.

# Create a rule with a rate expression
aws events put-rule \
    --name "cleanup-schedule" \
    --schedule-expression "rate(5 minutes)" \
    --state ENABLED

Expected output (truncated):

{
    "RuleArn": "arn:aws:events:us-east-1:123456789012:rule/cleanup-schedule"
}

3. Attach the Lambda target and grant permission

Use the rule ARN from the previous step to add your Lambda as a target.

# Add the Lambda function as a target
aws events put-targets \
    --rule "cleanup-schedule" \
    --targets "Id"="1","Arn"="arn:aws:lambda:us-east-1:123456789012:function:scheduled-cleanup"

# Grant EventBridge permission to invoke the Lambda (idempotent)
aws lambda add-permission \
    --function-name "scheduled-cleanup" \
    --statement-id "EventBridgeInvokeScheduledCleanup" \
    --action "lambda:InvokeFunction" \
    --principal "events.amazonaws.com" \
    --source-arn "arn:aws:events:us-east-1:123456789012:rule/cleanup-schedule"

Pro tip: If you use the AWS console when adding a target, it automatically adds the lambda:InvokeFunction permission. With CLI/CDK, you must add it manually — this is a common pitfall.

4. Verify the invocation

Wait 5 minutes, then open CloudWatch Logs for the /aws/lambda/scheduled-cleanup log group. You'll see a log entry like:

INFO Running scheduled cleanup at 2025-04-10T14:30:05Z

5. Update to a cron schedule for production

Once testing works, switch to a cron expression that matches your real need — e.g., daily at 2 AM UTC:

aws events put-rule \
    --name "cleanup-schedule" \
    --schedule-expression "cron(0 2 * * ? *)" \
    --state ENABLED

Compare options / when to choose what

You now have several ways to run scheduled Python code on AWS. Here's how they stack up:

Option Best for Pros Cons
EventBridge + Lambda Short tasks (<15 min), event-driven workflows Serverless, managed retries, integrates with SNS/SQS/DLQ Lambda timeouts, cold start, no state between runs
EC2 + cron Long-running processes, legacy apps Full control, can run any code Managed by you — patching, scaling, failure
ECS/EKS scheduled tasks Containerized apps, long-running batches Uses Docker, exact cron control More complexity, cost of infrastructure
Step Functions Multi-step workflows with checkpoints Built-in retries, state machine Overkill for a single scheduled task

When to choose EventBridge + Lambda: - Recurring jobs that run in under 15 minutes - Need integration with other AWS services (SQS, SNS, DynamoDB) - Want minimal operational overhead and automatic scaling

Choose EC2/ECS when you need heavier processing or existing containers — but you'll own the operational burden.

Troubleshooting & edge cases

Rule exists, but Lambda never fires

This is almost always a permission problem. Double-check the aws lambda add-permission call — the --principal must be events.amazonaws.com, and the --source-arn must match the rule ARN exactly. A stray extra character breaks the trust.

Wrong timezone

Cron expressions in EventBridge are evaluated in UTC by default. cron(0 2 * * ? *) runs at 2 AM UTC, not your local time. Convert carefully using a timezone converter. If you need local timezones, consider computing offsets or using multiple rules.

Cron expression doesn't work — missing question mark

EventBridge uses a six-field cron format (unlike traditional 5-field cron). You must include a ? for the day-of-week field when you set day-of-month. Example: cron(0 12 * * ? *) for daily at noon UTC. Forgetting the ? yields an error like ScheduleExpression is not valid.

Function times out or retry storm

If the Lambda run exceeds its timeout, EventBridge retries by default (up to 185 times over 24 hours) unless you configure retry policies. Set a dead-letter queue to capture events that fail permanently. Also set appropriate ReservedConcurrency to avoid throttling storms.

Rate vs cron: when to use which

  • rate(1 hour) — perfect for simple intervals
  • cron(0 9 * * ? *) — when you need specific time of day (e.g., 9 AM UTC daily)
  • cron(0 0 1 * ? *) — first day of the month at midnight

What you learned & what's next

You now understand how to use EventBridge to schedule Lambda tasks — from creating a rule, attaching your Python function, and granting the right permissions to troubleshooting common issues. You can confidently replace fragile EC2 cron jobs with a serverless, fully managed scheduler that integrates with the rest of AWS.

As a next step, consider exploring infrastructure as code — defining your EventBridge rules and Lambda functions in Terraform or AWS SAM. This makes your scheduling setup versionable and reproducible across environments. In the next lesson in this track, you'll dive into IaC patterns that will make your AWS deployment pipelines even more robust.

Pro tip: Start with rate(1 minute) when testing a new schedule so you don't wait forever to see if it works. Once confirmed, switch to your real cron frequency.

Practice recap

Now try it yourself: create a simple Lambda that writes a timestamp to DynamoDB, then schedule it every 5 minutes using an EventBridge rule. Wait for two intervals and verify the items in DynamoDB. Then change the rule to a cron schedule for your local 10 AM and confirm the correct UTC conversion. This will cement both the permissions and the cron syntax.

Common mistakes

  • Forgetting to add the lambda:InvokeFunction permission when creating the rule via CLI or IaC — the console adds it automatically, but CLI/CDK requires an explicit aws lambda add-permission call.
  • Using a 5-field cron expression like 0 2 * * * — EventBridge requires a 6-field format with a ? in the day-of-week field (e.g., cron(0 2 * * ? *)).
  • Assuming the cron runs in your local timezone — EventBridge cron and rate expressions are evaluated in UTC; you must convert your desired time to UTC explicitly.

Variations

  1. Instead of rate/cron expressions, use EventBridge event patterns to trigger Lambda on specific API calls (e.g., PutObject in S3) — great for event-driven workflows.
  2. Define your schedule and Lambda in AWS SAM or Terraform for infrastructure-as-code reproducibility, rather than using the console or one-off CLI commands.
  3. Use Amazon EventBridge Scheduler (the newer service) for one-time schedules or higher-frequency (up to 1-second) invocations, which the older EventBridge rules don't support.

Real-world use cases

  • Automatically delete old S3 objects (e.g., logs older than 30 days) every night at 2 AM UTC using a scheduled Lambda cleanup function.
  • Send a daily summary email to users by triggering a Lambda function at 8 AM UTC that gathers data from DynamoDB and uses SES to send personalized digests.
  • Pull updated currency exchange rates from an external API every hour and store the results in DynamoDB for a financial dashboard to query.

Key takeaways

  • EventBridge schedule rules replace fragile EC2 cron jobs with fully managed, serverless scheduling for Lambda functions.
  • Always grant the lambda:InvokeFunction permission with principal events.amazonaws.com when creating rules outside the console.
  • EventBridge uses 6-field cron expressions (UTC), not standard 5-field — remember the ? for day-of-week.
  • Monitor scheduled invocations via CloudWatch Logs, and set a DLQ or Lambda destination to catch failures.
  • Use rate(5 minutes) for testing before switching to a cron schedule to avoid long waits.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.