Pattern: Lambda Health Check

A reliable way to catch out-of-date Lambdas and configuration issues before they become real problems.

Dec 12, 2025

Out-of-date or misconfigured Lambdas are one of the most common and annoying failure modes in serverless apps. Common causes include:

  • CDK skips deployments (“no changes”) even when your code has changed, which is particularly common in mono repos where package changes are not considered when diffing.

  • The lambda is lacking the configuration or permissions required to operate.

The Solution

The following describes a simple, repeatable pattern that gives you confidence every Lambda is running the version you expect and talking to what it needs to:

  • Shared version map: Track a version number for every Lambda in a map and ensure this is accessible across the codebase. I typically use mono-repos, so this would be kept in a shared package.

  • All lambdas support standard health check message: Each Lambda accepts a health message and reports its name, version and optional resource checks.

  • System health orchestrator: A single Lambda or service (with permission to access the other lambdas) queries all others and aggregates their status. This allow the individual lambdas to remain private.

  • Frontend comparison: Your dashboard imports the same version map and highlights mismatches immediately.

Implementation Specifics

Version map

// shared/lambdaVersions.ts
export const LambdaVersions = {
  CreateRequest: 3,
  ProcessGeneration: 12,
  GetStatus: 4,
} as const;

Health Check Handler

As used inside each lambda

import { LambdaVersions } from '../shared/lambdaVersions';

const LAMBDA_NAME = 'ProcessGeneration';

export const handler = async (event) => {
  if (event.action === 'health') {
    // Perform any resource checks, e.g. connecting to a DB or pinging another service
    return {
      statusCode: 200,
      body: JSON.stringify({
        lambdaName: LAMBDA_NAME,
        version: LambdaVersions[LAMBDA_NAME],
        isHealthy: true,
      }),
    };
  }

  // normal Lambda logic...
};

Central Check

As provided by an health-check lambda or your main services:

import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
import { LambdaVersions } from '@myMono/shared/lambdaVersions';

const lambda = new LambdaClient({});
const lambdaNames = Object.keys(LambdaVersions);

async function check(functionName) {
  const res = await lambda.send(new InvokeCommand({
    FunctionName: functionName,
    Payload: JSON.stringify({ action: 'health' })
  }));

  return JSON.parse(new TextDecoder().decode(res.Payload)).body;
}

export const handler = async () => {
  const results = await Promise.all(lambdaNames.map(check));

  return {
    statusCode: 200,
    body: JSON.stringify({ lambdas: results }),
  };
};

Frontend Visualisation

As located in an admin app

import { LambdaVersions } from '@myMono/shared/lambdaVersions';

function VersionRow({ name, reported }) {
  const expected = LambdaVersions[name];
  const mismatch = expected !== reported;

  return (
    <div className={mismatch ? "warning" : "ok"}>
      {name}: {reported} {mismatch && `(expected ${expected})`}
    </div>
  );
}