Skip to content
LastPing
GUIDE · AWS LAMBDA · EVENTBRIDGE · FREE

Monitor scheduled AWS Lambda functions: EventBridge cron monitoring

EventBridge fires your Lambda on a schedule and retries twice on failure, then silently drops the invocation. The FailedInvocations CloudWatch metric exists but isn't alarmed by default. Add one HTTP call at the end of your handler: if the Lambda succeeds, the ping arrives; if it errors, times out, or is never invoked, the silence opens an incident. Free, no agent to install.

Your assistant can do this for you

Monitor my Lambda functions with LastPing

On this page
  1. Three failure modes EventBridge won't tell you about
  2. Setup: one ping call, about a minute
  3. What this catches
  4. Questions people ask

Three failure modes EventBridge won't tell you about

EventBridge is asynchronous. Failures after the two built-in retries are silent.

Failure mode 01

Invocation dropped after 2 retries

If the Lambda throws an unhandled exception or runs out of memory, EventBridge retries twice and then drops the invocation. FailedInvocations in CloudWatch records it, but no alarm fires by default.

Failure mode 02

Lambda timeout: silent kill

If the function exceeds its configured timeout (max 15 min), AWS kills it. The invocation is counted as failed. No CloudWatch alarm fires unless you set one up explicitly. The work was never finished.

Failure mode 03

Deleted function or broken IAM

The Lambda ARN was deleted, renamed, or the EventBridge execution role's permission was revoked. EventBridge has no valid target and retries fail immediately, then silence.

Setup: one ping call, about a minute

No layer, no library, no Lambda extension: one HTTP call at the end of the handler.

Create a heartbeat monitor in LastPing

In the console, create a monitor. For the schedule, use the same expression as your EventBridge rule. EventBridge cron times are always UTC. Set the grace window to the Lambda timeout plus a few minutes of buffer.

# EventBridge rule schedule examples:
# rate(1 day)           → every 24 hours
# cron(0 3 * * ? *)     → 03:00 UTC daily
# cron(0 3 ? * MON-FRI *) → 03:00 UTC weekdays

https://ping.lastping.dev/<your-monitor-id>

Python handler: ping on success

Store the monitor ID in a Lambda environment variable (LASTPING_MONITOR_ID) and call the ping only inside the successful path.

import os, urllib.request

PING_URL = f"https://ping.lastping.dev/{os.environ['LASTPING_MONITOR_ID']}"

def handler(event, context):
    # optional: arm overrun detection
    urllib.request.urlopen(f"{PING_URL}/start", timeout=10)

    try:
        do_work()  # your actual logic
        urllib.request.urlopen(PING_URL, timeout=10)
    except Exception as e:
        urllib.request.urlopen(f"{PING_URL}/fail", timeout=10)
        raise

Node.js handler: ping on success

const PING_URL = `https://ping.lastping.dev/${process.env.LASTPING_MONITOR_ID}`;

export const handler = async (event) => {
  await fetch(`${PING_URL}/start`);   // arm overrun detection

  try {
    await doWork();                    // your actual logic
    await fetch(PING_URL);
  } catch (err) {
    await fetch(`${PING_URL}/fail`);
    throw err;
  }
};

Set the environment variable in Lambda

In the AWS console: Lambda → your function → Configuration → Environment variables → add LASTPING_MONITOR_ID with the UUID from step 1. Or via AWS CLI:

aws lambda update-function-configuration \
  --function-name my-nightly-job \
  --environment "Variables={LASTPING_MONITOR_ID=<your-monitor-id>}"

What this catches

  • Handler exception: /fail ping fires immediately; incident opens.
  • Lambda timeout: /start arrived but AWS killed the function before success; overrun opens the incident.
  • Invocation never fired: deleted ARN, broken IAM, EventBridge rule disabled. No signal in the window → incident.
  • Invocation dropped after 2 retries: same as never fired from the monitor's perspective.
  • Recovery: next successful invocation closes the incident. No manual reset.

Running on other cloud platforms? See Google Cloud Scheduler, Azure Functions, Cloudflare Workers, or the full guide index. AI agents can use the LastPing MCP server to report their own heartbeat without HTTP calls.

Questions people ask

Front-loaded answers: the most important fact first.

  • Why does my scheduled AWS Lambda not run reliably?

    EventBridge (formerly CloudWatch Events) delivers invocations asynchronously and retries twice on failure before dropping the invocation silently. The FailedInvocations CloudWatch metric records it but isn't alarmed by default. A function that throws an uncaught exception, exceeds its timeout, or targets a Lambda ARN that was deleted will silently stop running after the two retries are exhausted. Dead-man's-switch monitoring catches all three failure modes without needing to configure CloudWatch alarms: a ping at the end of a successful handler, combined with a LastPing heartbeat monitor, sets the expectation, and silence opens an incident.

  • How do I monitor a scheduled Lambda function?

    Add one HTTP call at the end of the handler function body, inside a try/except that only fires on success. For Python: urllib.request.urlopen('https://ping.lastping.dev/<your-monitor-id>', timeout=10). For Node.js: await fetch('https://ping.lastping.dev/<your-monitor-id>'). Create a LastPing heartbeat monitor with the same schedule as your EventBridge rule and a grace window. If the ping doesn't arrive in the window, an incident opens.

  • What EventBridge cron syntax should I use?

    EventBridge uses two formats: rate expressions (rate(1 day), rate(2 hours)) and 6-field cron expressions where the first field is minutes, not seconds: cron(minutes hours day-of-month month day-of-week year). All times are UTC. Either day-of-month or day-of-week must be ?: you cannot specify both. cron(0 3 * * ? *) = 03:00 UTC daily (note the ? in the day-of-week field).

  • How do I catch a Lambda function that exceeds its timeout?

    Send a /start ping as the very first call in the handler, so it fires even if the function times out in a long-running step. Set the LastPing grace window to the Lambda timeout plus a few minutes of buffer. If the Lambda exceeds its timeout, AWS kills it before the success ping fires: the /start arrived but no success follows within the grace window, so overrun detection opens the incident.

  • Does the ping add meaningful latency?

    The ping is a single HTTPS GET to ping.lastping.dev, typically under 100ms from us-east-1. Set a hard timeout (timeout=10 in Python, an AbortController in Node.js) so a transient network issue can't hold the function open past its timeout.

  • Is this free?

    Yes. LastPing is free for individuals with no monitor cap. See vs Healthchecks.io and vs Cronitor.

FREE FOR INDIVIDUALS · FULLY HOSTED

EventBridge drops invocations silently. LastPing doesn't.

One environment variable and two lines of code. First alert wired up in under a minute, and LastPing monitors itself the same way.