,

Lambda 90-Minute Timeout: How It Actually Works

Stopwatch at 90 minutes beside a serverless function block illustrating the Lambda 90-minute timeout

The 15-minute wall has been the defining constraint of serverless compute since 2018, and as of September 2026 it has a door in it. The lambda 90-minute timeout on Lambda Managed Instances lets a single invocation run for 5,400 seconds — six times longer than before. Before you go bump every timeout in your account to the new maximum, read the fine print, because this is narrower and more interesting than “AWS raised a number.”

What the lambda 90-minute timeout actually covers

Three conditions have to be true at once. First, the function must run on Lambda Managed Instances — the capacity-provider model where Lambda schedules your functions onto dedicated EC2 capacity you configure, rather than the shared on-demand fleet. Second, the invocation must be asynchronous or arrive through an event source mapping. Third, the ESM has to be one of the supported ones: SQS, Kinesis Data Streams, DynamoDB Streams, or Amazon MSK.

Everything else stays where it was. Synchronous invocations are still capped at 15 minutes no matter what you configure — API Gateway, an ALB target, a direct RequestResponse call from another service, all of them hit the same 900-second ceiling they always did. The configured timeout does not override that; the invocation mode decides. Amazon MQ and DocumentDB event source mappings also stay at 15 minutes. And the Init phase is still capped at 15 minutes, so a cold start that spends twenty minutes loading a model into memory is still a failed cold start.

That last detail matters more than it sounds. If your long-running job needs a 6 GB model file, you still load it inside the handler or stream it during execution — not in module scope where Init timing rules apply. The announcement post is explicit about the split, and it is the kind of thing that only bites you on the first cold start in production.

Turning it on

There are no code changes. The timeout is a configuration value, and 5,400 is now a legal value for it on Managed Instances:

aws lambda update-function-configuration \
  --function-name my-data-processor \
  --timeout 5400 \
  --region us-east-1

In the console it lives where it always did, under Configuration > General configuration. In IaC it is a one-line diff. A SAM function that is ready for the long haul looks like this:

Resources:
  DataProcessor:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: python3.12
      Handler: app.handler
      Timeout: 5400
      MemorySize: 10240

You can also drive it through the APIs, CDK, Terraform, or the Agent Toolkit for AWS. The easy part is the number. The hard part is everything downstream of it that assumed nothing would ever take that long.

SQS: the visibility timeout math changes

This is the setting that will break you first. With SQS event source mappings, the guidance is to set the queue’s visibility timeout to at least six times the function timeout. For a 5,400-second function that means 32,400 seconds — nine hours — on the queue.

If you leave visibility timeout at its default 30 seconds and set the function to 90 minutes, here is what happens: the message becomes visible again roughly 30 seconds into a job that has 89 more minutes to run, another poller picks it up, and you now have two invocations grinding through the same payload. Congratulations, you just doubled your bill and produced two copies of whatever the job writes. Six times the timeout is not a superstition; it is headroom for retries and batch redelivery.

aws sqs set-queue-attributes \
  --queue-url https://sqs.us-east-1.amazonaws.com/111122223333/media-jobs \
  --attributes VisibilityTimeout=32400

While you are in there, turn on partial batch failure reporting. Without it, one bad record in a batch that took 80 minutes to process sends the entire batch back for a retry — including the records that already succeeded. With ReportBatchItemFailures and a handler that returns batchItemFailures, only the failed message IDs go back. The error handling docs cover the response shape, and at 90-minute batch durations the difference between “retry one record” and “retry the whole batch” is real money.

Message queue feeding dedicated compute instances with a visibility gate holding messages back

Kinesis, DynamoDB Streams, and MSK

Stream sources have a different failure mode: head-of-line blocking. A shard is processed in order, so one 90-minute invocation on a shard means nothing else from that shard moves for 90 minutes. Two knobs matter.

MaximumBatchingWindowInSeconds controls how long the poller waits to accumulate records before invoking. Longer windows mean fuller batches and fewer invocations — good if the per-invocation setup cost is high, bad if you care about latency. ParallelizationFactor lets Lambda run up to ten concurrent batches per shard, which is the only way to keep a shard moving while a long job runs, and it changes your ordering guarantee from per-shard to per-partition-key. Read the Kinesis ESM docs before you turn that up; if your consumer assumes strict shard ordering, parallelization will find out.

The network is the part nobody tests

Long invocations expose infrastructure timeouts that shorter ones never reached. Four to check before you ship:

  • NAT Gateway idle timeout. A NAT Gateway drops idle TCP connections after 350 seconds. If your function opens a connection to an external API, kicks off a long job, and comes back an hour later expecting that socket to be alive, it is not. Send keep-alives, or reconnect. The NAT Gateway troubleshooting page spells out the behavior.
  • Downstream connection tolerance. RDS Proxy, ElastiCache, and third-party APIs all have their own idle and max-lifetime settings. A connection pool opened at minute zero may be closed on the other end by minute forty.
  • DNS TTLs. If a runtime caches a resolved address for the whole invocation, a failover or a scaling event on the far side can leave you talking to an IP that no longer answers. Respect the TTL.
  • Credentials. Temporary credentials from the execution role have a finite lifetime. Most AWS SDKs refresh them from the runtime environment automatically, but if you captured credentials into a long-lived client at startup or passed them to a subprocess, make sure something refreshes them in the background.

Retries, destinations, and the bill

For async invocations, the configured retry policy still applies — by default two retries — and failures route to your dead-letter queue or on-failure destination. At 90 minutes per attempt, three attempts is four and a half hours of compute burned on one event. Decide deliberately whether that is what you want, and instrument enough progress logging that you can tell a hung job from a slow one.

There is no additional charge for the longer timeout itself. You pay standard Lambda Managed Instances pricing — the underlying EC2 capacity plus the Lambda management fee — which is a different cost shape than per-millisecond on-demand Lambda and worth modeling before you move a fleet of jobs over.

At Enkompass (enkompass.net), this is our home turf. We build event-driven, serverless systems that scale to zero and bill like it — including the long-running jobs everyone used to shove into Fargate because Lambda said no. If you’d rather have seasoned cloud people handle it instead of learning the hard way at 2 AM, let’s talk. Reach out through our contact page or call us directly at +1-828-436-5667 — we’ll help you turn this from a someday-project into a done-deal.

Ready when you are

Let’s map your route to AWS

A free 60-minute architecture review with a senior engineer. No slides, no SDR, just a plan.