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.

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 Lambda not run reliably?

    EventBridge retries twice on failure and then drops the invocation silently. The FailedInvocations CloudWatch metric records it but isn't alarmed by default. A ping at the end of a successful handler, combined with a LastPing heartbeat monitor, catches all three failure modes without needing to configure CloudWatch alarms.

  • What EventBridge cron syntax should I use?

    EventBridge uses 6-field cron expressions: 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.

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

    Send a /start ping as the very first call in the handler. Set the LastPing grace window to the Lambda timeout plus a few minutes. If AWS kills the function for timeout, the /start arrived but no success follows — 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 and fully hosted with no monitor cap and no paid tier. See vs Healthchecks.io and vs Cronitor.

FREE · FULLY HOSTED · NO PAID TIER

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.