← Blog
lambdaserverlessreliability

A failing Lambda doesn't cost less

By , founder of CostPulse ·

A Lambda function that starts failing doesn't cost less because it's broken — it usually costs dramatically more. Every retry is a full billed invocation, a function that times out bills its entire timeout per attempt, and most event sources are explicitly designed to keep redelivering until something succeeds. When a dependency goes down at 2am, that persistence turns into a billing event: invocation count and duration both spike while useful work done is exactly zero.

Retries are the default, everywhere

Asynchronous invocations (S3 events, EventBridge, SNS) retry failed executions twice by default, with the event kept for hours. SQS goes further: a message whose processing fails becomes visible again after its visibility timeout and is redelivered — until it either succeeds or exceeds the queue's maxReceiveCount. If there's no redrive policy, that count is effectively infinite, and one malformed message — a poison pill — can be processed, failed, and re-billed thousands of times. Stream sources (Kinesis, DynamoDB Streams) block on the failing batch and retry it until it expires, stalling the shard while billing every attempt.

billed invocationsupstream requestsdependency downtime →

A dependency outage from the billing meter's point of view: upstream traffic never moved — every extra billed invocation is the retry machinery talking to itself.

Timeouts multiply the damage

The expensive failure mode isn't an exception thrown in ten milliseconds — it's a hung dependency. A function that normally finishes in 300ms but waits on an unresponsive API until its 30-second timeout bills 100× its usual duration per attempt, and then the retry machinery runs the attempt again. Error rate up, duration at ceiling, redelivery in a loop: each factor multiplies the others. This is how a function that costs a few dollars a month produces a triple-digit day without a single successful execution.

Retry amplification across layers

Retries also stack across the call chain. If your client SDK retries three times, the function it calls retries its own downstream call three times, and the event source redelivers on top of that, a single logical operation can fan out into dozens of billed attempts. Each layer's retry policy is individually reasonable; the product of them is not. The fix is architectural — retry at one layer, fail fast at the others, and send what still fails to a dead-letter queue instead of around the loop again.

What to check first

  • Graph CloudWatch Errors against Invocations per function — a rising error ratio with flat upstream traffic means the extra invocations are retries, not customers.
  • Check every SQS-triggered function's queue for a redrive policy: a maxReceiveCount of 3-5 and a dead-letter queue turn an infinite loop into a bounded one with an audit trail.
  • For async invocations, set MaximumRetryAttempts and MaximumEventAge deliberately, and configure an on-failure destination — the defaults favor delivery, not your bill.
  • Compare each function's timeout to its p99 duration. A 30-second timeout on a 300ms function is a 100× cost amplifier waiting for the first hung dependency.
  • On stream sources, alarm on IteratorAge — a growing iterator age is the earliest sign a batch is stuck in the retry loop.

Retry storms are invisible in a monthly bill — a bad night averages away inside a 30-day total. They are extremely visible as a spend anomaly: Lambda cost spiking far above its own recent baseline the same day, in one service, is close to a signature. Whatever alerting you use, that same-day comparison is the one that catches this class of failure while it's still one bad night instead of a bad week.

CostPulse watches for this automatically — a 7-day rolling baseline per service and region, with the alert in Slack, Teams or email within about a day of it starting. Not on the invoice a month later.

Have an AWS spend commitment? Buy through AWS Marketplace and it may count toward it, depending on your agreement. Want a full teardown instead? Book an audit — $3,500.