Serverless functions are powerful but harder to monitor than traditional servers. AWS Lambda, Cloudflare Workers, and Vercel Edge Functions do not have persistent processes to watch — they spin up, handle a request, and disappear.
This guide covers how to add uptime monitoring to serverless functions with Vigilmon.
Why Serverless Monitoring Is Different
With a traditional server, you check if the process is running. With serverless:
- There is no process — functions are ephemeral
- Cold starts can cause timeouts on the first request
- Functions can fail silently (invocation succeeds but returns an error body)
- Invocation limits and concurrency throttling cause 429 errors
- IAM permissions can change and break functions without warning
The only reliable way to know your serverless functions are working correctly is to call them from outside and verify the response.
Monitoring AWS Lambda Functions
Step 1: Create a Health Lambda
If you have multiple Lambda functions, create a dedicated health check Lambda that calls your critical functions internally:
import json
import boto3
lambda_client = boto3.client("lambda")
def handler(event, context):
results = {}
# Test your critical functions
functions_to_check = [
"my-app-api-handler",
"my-app-background-processor",
]
for fn_name in functions_to_check:
try:
response = lambda_client.invoke(
FunctionName=fn_name,
InvocationType="RequestResponse",
Payload=json.dumps({"_health_check": True})
)
payload = json.loads(response["Payload"].read())
results[fn_name] = "ok" if response["StatusCode"] == 200 else "error"
except Exception as e:
results[fn_name] = f"error: {str(e)}"
is_healthy = all(v == "ok" for v in results.values())
return {
"statusCode": 200 if is_healthy else 503,
"body": json.dumps({"status": "ok" if is_healthy else "degraded", "checks": results})
}
Step 2: Expose Via API Gateway
Add an API Gateway trigger to your health Lambda with a public URL:
GET https://abc123.execute-api.us-east-1.amazonaws.com/prod/health
Step 3: Handle Health Check Requests in Your Functions
Add health check handling to your individual Lambda functions:
def handler(event, context):
# Skip business logic for health checks
if event.get("_health_check"):
return {"statusCode": 200, "body": json.dumps({"status": "ok"})}
# Normal processing
return process_request(event, context)
Monitoring Cloudflare Workers
Cloudflare Workers are even simpler to monitor — each Worker has a URL. Add a health path:
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/health") {
// Optionally test your D1 database, KV, or R2 connections
try {
const result = await env.DB.prepare("SELECT 1").run();
return new Response(JSON.stringify({ status: "ok" }), {
headers: { "Content-Type": "application/json" }
});
} catch (e) {
return new Response(JSON.stringify({ status: "error", detail: e.message }), {
status: 503,
headers: { "Content-Type": "application/json" }
});
}
}
// Normal request handling
return handleRequest(request, env);
}
};
Then add https://your-worker.your-subdomain.workers.dev/health to Vigilmon.
Monitoring Vercel Functions
For Next.js on Vercel, create an edge-runtime health route:
// app/api/health/edge/route.ts
export const runtime = "edge";
export async function GET() {
return Response.json({ status: "ok", runtime: "edge", region: process.env.VERCEL_REGION });
}
And a Node.js runtime health route separately:
// app/api/health/route.ts
export async function GET() {
return Response.json({ status: "ok", runtime: "nodejs" });
}
Monitor both endpoints — edge and Node failures are independent.
Setting Up Vigilmon for Serverless
- Sign up at vigilmon.online — free for 50 monitors
- Add your serverless health endpoint URL
- Set check interval to 1 minute
- Set timeout to 10 seconds (accounts for cold starts)
- Alert after 1 failure for production
Cold start consideration: Lambda cold starts can take 2-10 seconds. Set your timeout in Vigilmon to at least 15 seconds to avoid false positives. If your function consistently cold-starts slowly, use provisioned concurrency to eliminate it.
What Serverless Monitoring Catches
External uptime monitoring for serverless functions catches:
- IAM permission changes that break function execution
- Environment variable misconfiguration after a deploy
- Dependency failures (RDS, DynamoDB, external APIs) that cascade
- Concurrency throttling causing 429 responses
- Dead letter queue failures in async functions
- Function timeout increases that indicate a performance regression
Heartbeat Monitoring for Scheduled Functions
If you have Lambda functions triggered by EventBridge or cron, add a heartbeat ping at the end:
import urllib.request
def handler(event, context):
# Do your work
process_scheduled_job()
# Ping Vigilmon heartbeat URL when done
heartbeat_url = os.environ.get("VIGILMON_HEARTBEAT_URL")
if heartbeat_url:
urllib.request.urlopen(heartbeat_url)
return {"statusCode": 200}
In Vigilmon, set up a heartbeat monitor that expects a ping every N minutes. If the ping does not arrive, Vigilmon alerts you that your scheduled function stopped running.
Summary
Serverless functions need external monitoring more than traditional servers do, not less. They fail silently, have cold start variability, and do not have persistent processes to watch.
Add a health endpoint to your critical serverless functions, expose them via URL, and monitor them with Vigilmon — free, 1-minute checks from multiple regions.
Start monitoring your serverless functions at vigilmon.online
Top comments (0)