Lambda memory cost is the memory a function reserves per invocation multiplied by its running time; over-provisioned serverless is the same mistake in every form: too much memory per function, minimum instances idling through the night, always-ready instances for an endpoint with three calls an hour. The saving comes from serverless billing per second and per reserved unit, so every unit nobody needs drops out of the bill at once. The fix belongs to the team that runs the function or service, because only a load test says which setting is enough.

Symptom

The bill shows GB-seconds and instance hours that do not match the number of requests. On AWS these are lines with lineItem/UsageType EUC1-Lambda-GB-Second or EUC1-Lambda-GB-Second-ARM beside EUC1-Request, whose ratio gives the mean GB-seconds per invocation, and Lambda-Provisioned-Concurrency lines running around the clock. On Azure the Flex Consumption meters for execution time and for always-ready instances sit under MeterCategory Functions, and for Container Apps the vCPU and memory meters with their idle share. On Google Cloud Cloud Run carries the SKUs for CPU and memory allocation time, under instance-based billing for the instance's whole lifetime. What a serverless service charges in principle is in serverless functions; this page covers the three settings that multiply the amount without a benefit.

Requests: EUC1-RequestGB-seconds per invocation:Lambda-GB-Second dividedby the requestsLines that run around theclock: ProvisionedConcurrency, always-readyinstances, instance-basedCloud Run billingSThree settings multiplythe amount withouta benefit
Over-provisioning shows as GB-seconds per invocation and reserved capacity lines that do not follow the request count

How to detect it

AWS

Lambda reserves 128 MB to 10,240 MB per function in 1 MB steps, and CPU grows with memory; a function with too little memory runs longer, one with too much pays for capacity it does not use (read on 2026-10-21). The functions with their settings:

aws lambda list-functions --query 'Functions[].[FunctionName,MemorySize,Timeout,Architectures[0],PackageType]' --output table

The reserved capacity that runs regardless of invocations: aws lambda list-provisioned-concurrency-configs --function-name <fn>. The memory size recommendations of Compute Optimizer, from 14 days of invocations:

aws compute-optimizer get-lambda-function-recommendations \
  --query 'lambdaFunctionRecommendations[].[functionArn,currentMemorySize,finding,memorySizeRecommendationOptions[0].memorySize]' --output table

Trusted Advisor also runs the checks "AWS Lambda over-provisioned functions for memory size" and "AWS Lambda functions with excessive timeouts", which flag functions where more than 10 percent of invocations end in a timeout on any day of the last seven; every timeout is the full duration at the full memory. The actual curve is measured by AWS Lambda Power Tuning, a Step Functions state machine under the Apache-2.0 licence that invokes a function at several memory sizes and recommends the setting for cost, speed or both. In billing data the GB-seconds per function are visible through lineItem/ResourceId (AWS Cost and Usage Report).

Azure

In the Flex Consumption plan of Azure Functions, always-ready instances are the line that runs without invocations: their baseline is billed in GB-seconds over the whole time, without the free grants of on-demand mode, at instance sizes of 512, 2,048 and 4,096 MB (Flex Consumption). The setting per app:

az functionapp list --query "[].{name:name, rg:resourceGroup, plan:appServicePlanId}" -o table
az functionapp scale config show --name <app> --resource-group <rg>

On Container Apps a revision with minimum replicas above zero runs without requests too; a replica counts as idle only when it processes no HTTP requests, stays below 0.01 vCPU cores and receives less than 1,000 bytes per second, and is then billed at the reduced rate (Container Apps billing):

az containerapp list --query "[].{name:name, rg:resourceGroup, min:properties.template.scale.minReplicas, max:properties.template.scale.maxReplicas, cpu:properties.template.containers[0].resources.cpu}" -o table

Azure Advisor makes no recommendation on minimum instances for Container Apps or Functions; the Replica Count metric against Requests per app is the evidence. In the cost export the meters sit per ResourceId under MeterCategory Functions or Azure Container Apps (Azure cost exports).

Google Cloud

Cloud Run has two billing models: request-based, where an instance is charged only while it processes requests, starts and shuts down, and instance-based, where the whole lifetime counts and CPU stays allocated; minimum instances are billed in both, at a lower idle rate under request-based billing and at the full rate under instance-based billing (CPU allocation, minimum instances). The services and their settings:

gcloud run services list --format="table(metadata.name,metadata.namespace,status.url)"
gcloud run services describe <service> --region=<region> --format="yaml(spec.template.metadata.annotations)"

The annotations autoscaling.knative.dev/minScale and run.googleapis.com/cpu-throttling carry the two settings. The recommender google.run.service.CostRecommender proposes the CPU allocation that fits the request pattern (Recommenders):

gcloud recommender recommendations list --project=<project-id> --location=<region> \
  --recommender=google.run.service.CostRecommender --format="table(name.basename(),description,stateInfo.state)"

In the billing export the allocation times sit per resource.name under service.description Cloud Run (Google Cloud billing export).

How to fix it

  1. Measure memory instead of guessing: run Power Tuning per Lambda function with the cost strategy and set the recommended size with aws lambda update-function-configuration --function-name <fn> --memory-size 512; lower the timeout to the measured duration plus a margin, so a hanging invocation does not pay the maximum.
  2. Limit reserved capacity to the hours it is needed: provisioned concurrency through Application Auto Scaling on a schedule, always-ready instances on Azure with az functionapp scale config always-ready set --resource-group <rg> --name <app> --settings http=1 on the group that cannot bear the cold start, minimum replicas on Container Apps with az containerapp update --name <app> --resource-group <rg> --min-replicas 0 for environments without a latency requirement.
  3. On Cloud Run choose the billing model to fit the load: gcloud run services update <service> --region=<region> --cpu-throttling for services that work only on requests, --no-cpu-throttling only for services with background work; minimum instances with --min-instances 0 where a cold start is allowed.
  4. Write the settings into the template new functions and services come from, with a default of zero minimum instances and a justified exception per service.

None of these changes has a dry run; the list from the first step and a latency comparison after the change stand in for it. The effect shows in the daily export after the change.

yesnonoyesMeasure memory with PowerTuning, set the size andlower the timeoutCan the servicebear a cold start?Zero minimum instances,no always-ready instancesReserved capacity onlyin the hours it is needed,on a scheduleBackground workbetween requests?Cloud Run: CPU onlyduring requestsCPU allocated for theinstance's whole lifetimeWrite the settings into thetemplate: zero minimuminstances as the default,a justified exceptionper serviceNo dry run: the list and alatency comparison afterthe change stand in
Memory is measured, reserved capacity is held to the hours that need it, and the template makes zero minimum instances the default

Risks and side effects

  • Less memory can cost more: on Lambda CPU falls with memory, a CPU-bound function runs longer, and GB-seconds are memory times time. Power Tuning shows the minimum of the curve, not the smallest number.
  • Zero minimum instances means cold starts; a service with a latency commitment needs the reserve, and the question is then its size and schedule, not its removal.
  • A timeout set too tight cuts off legitimate invocations; the measured distribution of durations, not the mean, sets the value.
  • Instance-based billing on Cloud Run is the right choice for services with background work; switching to request-based stops that work between requests.
  • A Compute Savings Plan covers Lambda duration too; the saving then lowers the covered usage, and the plan's utilisation needs checking (commitment coverage and utilisation).

How to verify the saving

Before: per function or service, the GB-seconds, instance hours or allocation times and the number of requests in the last full month, and from them the amount per thousand requests. After: the same figure in the first full month after the change at an equal or higher request count; the line for reserved capacity has to fall to the planned hours. The proposal from Compute Optimizer, Power Tuning or the recommender is the estimate, the team's consent makes it accepted, the change implemented, and the following month's invoice realises it in the pattern of estimated, accepted, implemented, verified. The service's latency metric belongs beside the amount, so the saving was not paid for with a regression.

Sources

Read on 2026-10-21. AWS Lambda pricing, Compute Optimizer Lambda recommendations, Trusted Advisor cost optimization checks, AWS Lambda Power Tuning, Azure Functions Flex Consumption plan, Manage Flex Consumption apps, Azure Container Apps billing, Cloud Run CPU allocation, Cloud Run minimum instances, Recommenders.