# Lambda Over-Provisioned Memory

> Lambda functions whose peak MaxMemoryUsed stays under 50% of configured memory are over-provisioned. ZopNight targets the next memory tier above peak plus 64 MB headroom and prices savings on the GB-second billing component alone, since the per-request charge never scales with memory. Missing REPORT-line metrics or GB-second cost force an abstention.

Source: https://zop.dev/integrations/aws/recommendations/lambda-over-provisioned-memory
Updated: 2026-08-19

---

## Peak memory from the REPORT log line

- MaxMemoryUsed read by exact name (metric.Maximum = peak MiB, metric.Average = configured MiB), now produced by the aggregator's CloudWatch Logs Insights puller (metrics/aws/logs_insights.go FetchLambdaMaxMemoryUsed, parses the REPORT line's @maxMemoryUsed/@memorySize). Absent => abstain.
- evalCtx.GBSecondCost[uid]: the GB-second cost component, not the total Pricing[uid], produced by the aggregator lambdaUsageFromMetrics → calcLambda "lambda-gb-seconds" component. This rule consumes it; absent/≤0 => abstain.
- PricingAware: total monthly cost for the CurrentCostUSD display.

## Only the GB-second component scales

Concrete rightsizing (user directive 2026-06-27: concrete or abstain, not advisory/$0). Fires when peak \< 50% of configured memory: savings = gbSecCostComponent × (1 − M_new/M_old), where M_old = configured MiB and M_new = nextLambdaMemoryTier(peak + 64 MB headroom). Only the GB-second billing component scales with memory; [the per-request component](https://aws.amazon.com/lambda/pricing/) is unchanged, so the saving is derived from GBSecondCost, not from the mixed total Pricing[uid] (multiplying the total would over-count the request portion, a fabrication). Saving capped at the total cost. Abstains (returns nil) when MaxMemoryUsed absent, configured/peak non-positive, well-sized (peak ≥ 50%), GBSecondCost absent/≤0, no safe downsize tier, or saving non-positive. The prior advisory/$0 state is removed; the resize lever (contract.LambdaMemorySize via RecommendTarget) is now reachable on live data. (Note: the "Advisory-only terminal states" table elsewhere predates the GB-second producer landing; the rule now emits a quantified saving, no auto-remediation only because GB-second sizing is non-linear.)

## Dropping to the next memory tier

1. Check the function's configured memory, at any size; there is no minimum for this rule
2. Review CloudWatch Maximum Memory Used metric
3. If peak usage \< 50% of configured memory, reduce it
4. Set memory to the next 128 MB tier above peak usage plus 64 MB of headroom
5. Test function performance after the change

## Where MaxMemoryUsed comes from

MaxMemoryUsed (30-day, now LIVE)
