# Idle Lambda Function

> A Lambda function invoked fewer than once a day over 30 days is effectively unused. Lambda bills per invocation, so the function itself costs nothing. Provisioned concurrency does, and that is usually where the recoverable cost sits on an idle function.

Source: https://zop.dev/integrations/aws/recommendations/idle-lambda-function
Updated: 2026-08-19

---

## Lambda is free when idle, with one exception

Lambda [charges per request and per GB-second of execution](https://aws.amazon.com/lambda/pricing/). A function nobody calls generates
neither, so an idle function is genuinely free to keep.

The exception is **provisioned concurrency**. That reserves warm execution environments and bills
hourly whether or not anything invokes the function, the same shape of cost as an idle NAT
Gateway. An idle function with provisioned concurrency configured is paying for readiness nobody
uses, and that is the real finding here.

## The threshold

Below one invocation per day, averaged over 30 days of [the Invocations count Lambda reports to CloudWatch](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-metrics.html). That is deliberately not zero: a function
invoked by a weekly job or a rarely-hit error path is used, just infrequently, and a hard
zero-test would leave it out while catching nothing extra.

## What else it usually points at

An unused function often comes with things that are not free:

- **Provisioned concurrency**, as above
- **An EventBridge rule or SQS trigger** still active and pointed at it
- **A CloudWatch log group** with no retention policy, keeping every log line since creation
- **An IAM execution role** with whatever permissions the function once needed

The log group is the one that quietly accumulates. Functions get deleted; their log groups
usually do not.

## Summing Invocations for the function

```bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/Lambda --metric-name Invocations \
  --dimensions Name=FunctionName,Value=my-function \
  --start-time "$(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --period 86400 --statistics Sum
```

## Before deleting

Archive the code to S3 first. `aws lambda get-function` returns a download URL for the
deployment package. Then remove provisioned concurrency, detach the triggers, and delete the
function, its log group and its role.
