Photo by Kier in Sight Archives on Unsplash
To get the Lambda invocation count for the last 24 hours, list your functions with the Lambda ListFunctions API, then ask CloudWatch for the Invocations metric in the AWS/Lambda namespace with the Sum statistic over that window. GetMetricData fetches up to 500 metrics per call, so one request covers hundreds of functions. The script below does both and ranks the results.
This example is for developers and on-call engineers who want a quick answer to “which functions are busy, which are failing, and which did nothing at all?” without clicking through the Lambda console one function at a time. You’ll get a complete TypeScript script for the AWS SDK for JavaScript v3 that returns the Lambda invocation count for the last 24 hours per function, adds error counts and an error rate, and flags functions with zero traffic.
It’s part of our collection of runnable AWS SDK practical examples. If you’re here because something is failing rather than to count traffic, the step-by-step walkthrough to investigate Lambda errors with CloudWatch metrics and Logs Insights goes deeper on diagnosis.
What does this script do?
The script works in one region at a time and makes two kinds of calls:
- List every functionIt pages through
ListFunctionswithpaginateListFunctions, which returns up to 50 functions per page, and collects the names. - Build metric queriesFor each function it creates two
MetricDataQueryentries:InvocationsandErrors, both with theFunctionNamedimension, a 1-hour period and theSumstatistic. - Fetch in batchesIt sends 250 functions (500 queries) per
GetMetricDatarequest and followsNextTokenwithpaginateGetMetricData. - Sum and rankIt adds up the hourly datapoints, sorts functions by invocations, prints a table with the error rate, and lists functions that had no invocations.
Using hourly datapoints and summing them is deliberate. A single 86,400-second period would also work, but a rolling “last 24 hours” window rarely lines up with day boundaries, and hourly values let you spot when traffic peaked if you print them. Summing the 24 values gives the window total.
Prerequisites
- Node.js 18 or later and npm.
- An AWS profile in
~/.aws/credentialsor~/.aws/config(SSO profiles work afteraws sso login). - The two SDK v3 clients:
@aws-sdk/client-lambdaand@aws-sdk/client-cloudwatch, plustsxto run TypeScript directly.
If you still have older scripts written with the v2 aws-sdk package, you can port them with the free AWS SDK JavaScript v2 to v3 converter and compare the output with this script’s structure.
Which IAM permissions does it need?
Only two read actions. Neither lambda:ListFunctions nor cloudwatch:GetMetricData supports resource-level permissions, so "Resource": "*" is the narrowest scope available for both.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListLambdaFunctions",
"Effect": "Allow",
"Action": "lambda:ListFunctions",
"Resource": "*"
},
{
"Sid": "ReadLambdaMetrics",
"Effect": "Allow",
"Action": "cloudwatch:GetMetricData",
"Resource": "*"
}
]
}
If you’d rather derive a policy from your own variant of the code, paste it into the IAM policy generator for TypeScript AWS code and review the result against the policy above.
The full script to get Lambda invocation counts for the last 24 hours
// lambda-invocations-24h.ts
// Counts invocations (and errors) for every Lambda function in one region
// over the last 24 hours, using CloudWatch GetMetricData in batches.
import { LambdaClient, paginateListFunctions } from "@aws-sdk/client-lambda";
import {
CloudWatchClient,
paginateGetMetricData,
type MetricDataQuery,
} from "@aws-sdk/client-cloudwatch";
const region = process.env.AWS_REGION ?? "us-east-1";
const lambda = new LambdaClient({ region });
const cloudwatch = new CloudWatchClient({ region });
const HOURS = 24;
const BATCH_SIZE = 250; // 2 queries per function; GetMetricData accepts up to 500 per call
type Row = { name: string; invocations: number; errors: number };
async function listFunctionNames(): Promise<string[]> {
const names: string[] = [];
for await (const page of paginateListFunctions({ client: lambda }, {})) {
for (const fn of page.Functions ?? []) {
if (fn.FunctionName) names.push(fn.FunctionName);
}
}
return names;
}
function queriesFor(names: string[]): MetricDataQuery[] {
const metrics = ["Invocations", "Errors"];
return names.flatMap((name, i) =>
metrics.map((metric) => ({
Id: `${metric === "Invocations" ? "inv" : "err"}${i}`, // must start with a lowercase letter
MetricStat: {
Metric: {
Namespace: "AWS/Lambda",
MetricName: metric,
Dimensions: [{ Name: "FunctionName", Value: name }],
},
Period: 3600, // hourly datapoints, summed below
Stat: "Sum",
},
ReturnData: true,
})),
);
}
async function countBatch(names: string[], start: Date, end: Date): Promise<Row[]> {
const totals = new Map<string, number>();
const pages = paginateGetMetricData(
{ client: cloudwatch },
{ MetricDataQueries: queriesFor(names), StartTime: start, EndTime: end },
);
for await (const page of pages) {
for (const result of page.MetricDataResults ?? []) {
if (!result.Id) continue;
const sum = (result.Values ?? []).reduce((a, b) => a + b, 0);
totals.set(result.Id, (totals.get(result.Id) ?? 0) + sum);
}
}
return names.map((name, i) => ({
name,
invocations: totals.get(`inv${i}`) ?? 0,
errors: totals.get(`err${i}`) ?? 0,
}));
}
async function main(): Promise<void> {
const end = new Date();
const start = new Date(end.getTime() - HOURS * 60 * 60 * 1000);
const names = await listFunctionNames();
if (names.length === 0) {
console.log(`No Lambda functions found in ${region}.`);
return;
}
const rows: Row[] = [];
for (let i = 0; i < names.length; i += BATCH_SIZE) {
rows.push(...(await countBatch(names.slice(i, i + BATCH_SIZE), start, end)));
}
rows.sort((a, b) => b.invocations - a.invocations);
const total = rows.reduce((sum, r) => sum + r.invocations, 0);
console.log(`Lambda invocations in ${region}, ${start.toISOString()} to ${end.toISOString()}\n`);
console.table(
rows.map((r) => ({
Function: r.name,
Invocations: r.invocations,
Errors: r.errors,
"Error rate": r.invocations ? `${((r.errors / r.invocations) * 100).toFixed(2)}%` : "-",
})),
);
console.log(`Total: ${total} invocations across ${rows.length} functions`);
const idle = rows.filter((r) => r.invocations === 0).map((r) => r.name);
if (idle.length > 0) {
console.log(`No invocations in the last ${HOURS} hours: ${idle.join(", ")}`);
}
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
The query IDs (inv0, err0, …) matter: CloudWatch requires each Id to start with a lowercase letter and be unique within the request, and the script uses them to map results back to function names. For the full list of Lambda metrics you can swap in, such as Throttles, Duration or ConcurrentExecutions, see the Lambda metric types reference in the AWS documentation.
How do you run it?
npm install @aws-sdk/client-lambda @aws-sdk/client-cloudwatch
npm install --save-dev tsx typescript
# Use a named profile and the region you want to count
AWS_PROFILE=readonly AWS_REGION=eu-west-1 npx tsx lambda-invocations-24h.ts
The script reads one region per run. To count Lambda invocations by region across an account, run it once per region in a shell loop, for example for r in us-east-1 eu-west-1; do AWS_REGION=$r npx tsx lambda-invocations-24h.ts; done.
Sample output
Lambda invocations in eu-west-1, 2026-10-18T09:00:12.004Z to 2026-10-19T09:00:12.004Z
┌─────────┬──────────────────────┬─────────────┬────────┬────────────┐
│ (index) │ Function │ Invocations │ Errors │ Error rate │
├─────────┼──────────────────────┼─────────────┼────────┼────────────┤
│ 0 │ 'orders-api' │ 184213 │ 37 │ '0.02%' │
│ 1 │ 'image-resizer' │ 20411 │ 612 │ '3.00%' │
│ 2 │ 'nightly-report' │ 1 │ 0 │ '0.00%' │
│ 3 │ 'legacy-webhook' │ 0 │ 0 │ '-' │
└─────────┴──────────────────────┴─────────────┴────────┴────────────┘
Total: 204625 invocations across 4 functions
No invocations in the last 24 hours: legacy-webhook
Figures are illustrative. image-resizer is the one to look at: a 3% error rate on 20,000 calls is worth a follow-up in its log group.
Troubleshooting: why is the invocation count 0 or wrong?
- Every count is 0. You’re almost certainly in the wrong region. Metrics live in the region where the function runs; check
AWS_REGIONand the profile’s default region. - The newest minutes are missing. CloudWatch metrics arrive with a short delay, so invocations from the last few minutes may not be counted yet. Rerun later if you need an exact end time.
AccessDeniedonGetMetricData. The profile has Lambda access but no CloudWatch read permission. Add the policy above or AWS’sReadOnlyAccessmanaged policy.- Counts differ from the console per version. The script uses only the
FunctionNamedimension, which aggregates all versions and aliases. Add aResourcedimension such asmy-fn:prodto count one alias. To prune the versions nothing points to, see how to delete old and unused Lambda function versions. Throttling: Rate exceeded. Very large accounts can hit theGetMetricDatarequest rate. LowerBATCH_SIZEor pause between batches.
For a broader method that starts from an alarm and works through logs and configuration, see how to troubleshoot AWS infrastructure from the terminal with an AI CLI.
How do you find Lambda functions with no recent invocations?
The last line of the output already does this for 24 hours. To find unused functions over a longer window, change HOURS to 720 (30 days) and the Period to 86400: hourly data for 30 days would be 720 datapoints per query, which still works but pages more. Functions with zero invocations over 30 days are good candidates for review, not automatic deletion, because some run only monthly or on rare events. The script to find unused Lambda functions with no invocations takes this further: it sums 90 days of invocations and checks each function’s triggers, function URL and resource-based policy before you delete anything.
The same approach answers “which are the most invoked Lambda functions in AWS”: the table is already sorted, so the first rows are your busiest functions. To see the rest of your inventory the same way, you can also list AWS resources with natural-language questions from your terminal. The most invoked functions are also where an architecture change pays off most; the script to find Lambda functions still on x86_64 instead of Graviton estimates the arm64 saving from each function’s duration.
Ask ChatWithCloud instead
If you’d rather not keep a script around, ChatWithCloud answers the same question in plain English. Ask “How many times was each Lambda function invoked in the last 24 hours, and which had errors?” and it writes AWS SDK for JavaScript v2 code, runs it on your machine with your AWS profile, and explains the result; the question-to-SDK-code loop in How it works shows each step. Follow-ups like “show the errors for image-resizer” continue from there, as covered in the guide to ask AI about Lambda errors in your AWS account. Changes run without a confirmation step, so connect ChatWithCloud with a read-only AWS profile for questions like these; the ChatWithCloud security model explains what data leaves your machine.
Frequently asked questions
How do I get the Lambda invocation count for the last 24 hours for one function?
Pass a single name to countBatch, or run aws cloudwatch get-metric-statistics with namespace AWS/Lambda, metric Invocations, dimension FunctionName, statistic Sum and a 24-hour window. The console’s Monitor tab shows the same metric as a graph.
Is the CloudWatch Invocations metric exact?
It counts every invocation attempt, including ones that end in a function error, and it’s the same number the Lambda console graphs. It doesn’t count requests that were throttled before running; those appear in the Throttles metric.
Does calling GetMetricData cost money?
CloudWatch charges GetMetricData per metric requested, so a run over many functions has a small cost. Check the current CloudWatch pricing page for your region before scheduling it frequently. To see what CloudWatch actually costs you, get this month’s CloudWatch cost with Cost Explorer.
Can I count Lambda invocations by region in one run?
Not with a single client: CloudWatch metrics are regional. Loop over regions and create a LambdaClient and CloudWatchClient per region, or run the script once per region as shown above.
Related guides
Ask your AWS account in plain English
Your first 15 runs are free, with no OpenAI key needed.
npx chatwithcloud
