Serverless Function Memory Limit Exceeded – Fix It Fast
Your serverless function hit its memory cap. Here's why it happens and how to fix it without wasting time. I've seen this trip up new and experienced devs alike.
1. Your Memory Allocation Is Too Low (Most Common Fix)
This is the first thing I check. Nine times out of ten, the function just needs more memory. Serverless platforms like AWS Lambda, Azure Functions, and Google Cloud Functions let you set a memory limit—usually from 128 MB up to 10 GB. If your function processes a bigger dataset or handles more concurrent requests, you'll hit the limit fast.
Last month, a client's Lambda kept crashing every time they imported a 50 MB CSV file. They blamed the code. I bumped the memory from 256 MB to 1 GB, and it ran fine. No code changes needed.
Here's a AWS CLI command to update memory allocation for a Lambda function:
aws lambda update-function-configuration --function-name your-function-name --memory-size 1024
For Azure Functions, you'd change it in the function.json file under bindings or set it in the portal under Configuration. For Google Cloud Functions, use the --memory flag during deploy:
gcloud functions deploy your-function --memory 1024MB --runtime nodejs18 --trigger-http
Don't just guess—use a memory monitoring tool. AWS X-Ray, Azure Monitor, or GCP Cloud Monitoring can show you what your function actually uses. I've seen functions that need 300 MB running fine at 512 MB, but others that spike to 2 GB when handling large payloads. Start with 1 GB and step up if needed. Most platforms charge by memory-time, so going too high wastes money. But a crash costs more in downtime.
2. You Have a Memory Leak in Your Code
If you increase memory and the error keeps happening (or happens more often over time), you likely have a memory leak. This is classic: your code holds onto objects it doesn't need, and each function invocation eats more RAM until it crashes. I've seen loops that accumulate data in arrays, global caches that never clear, or database connections left open.
Real story: a dev on my team had a Node.js Lambda that pulled user records from DynamoDB. They stored results in a global array thinking it would speed up repeat calls. But after 20 invocations, the array held 50 MB of stale data, and the function hit the limit every time. Moved the array inside the handler, and it worked.
Here's a common pattern that causes leaks in Node.js:
// bad: global state persists between invocations
let cache = [];
exports.handler = async (event) => {
cache.push(JSON.parse(event.body));
// ... process cache
};
Fix it by scoping variables inside the handler:
// good: fresh state per invocation
exports.handler = async (event) => {
let cache = [];
cache.push(JSON.parse(event.body));
// ... process cache
};
For Python functions, watch out for global lists or modules that import large libraries. In one case, a dev imported Pandas in a Google Cloud Function just to parse a tiny JSON. Pandas alone eats ~200 MB. Swap it for json.loads—problem solved.
To find leaks, add memory logging in dev. In Node.js, I use process.memoryUsage() at the start and end of the handler. In Python, try psutil.Process().memory_info().rss. Run the function 10 times with mock data and check if memory grows. If it does, you've got a leak.
3. Your Function Handles Too Much Data in One Request
Sometimes it's not a leak—it's just too much data at once. If your function receives a huge file, loads an entire database table, or sends a massive response, it'll hit the memory cap regardless of how good your code is. I had a client whose Lambda processed images: they'd upload a 10 MB image, and the function tried to load it all into memory before resizing. Boom, out of memory.
Here's the fix: stream the data instead of loading it all. Or chunk it. Use streaming libraries. On AWS Lambda with Node.js, use the aws-lambda-stream package or read the event body as a stream. For Python, use io.BytesIO to handle data in chunks. Example for a Lambda reading a large S3 object:
import boto3
import json
import io
s3 = boto3.client('s3')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
response = s3.get_object(Bucket=bucket, Key=key)
# read in chunks instead of loading all at once
data = response['Body'].read(1024 * 1024) # read 1 MB at a time
# process each chunk
while data:
# ...
data = response['Body'].read(1024 * 1024)
Another trick: reduce the payload size before sending it to the function. If you control the caller, compress the data (gzip) and decompress in the function. Or split the work into multiple invocations. For example, instead of one function processing 10,000 records, send 10 invocations each with 1,000 records. This spreads the memory load and makes it easier to debug.
Quick-Reference Summary Table
| Cause | Signs | Fix |
|---|---|---|
| Memory too low | Error happens on big payloads, function uses less than limit | Increase memory allocation (e.g., 256 MB to 1 GB) |
| Memory leak | Error grows over time, memory usage climbs between runs | Scoped variables, close connections, don't use globals |
| Too much data per request | Error on specific large inputs, function tries to load everything | Stream data, chunk it, or split work into smaller invocations |
If none of these work, check your timeout settings—sometimes a timeout looks like a memory error in logs. Also, some platforms have soft limits you can't change (like AWS Lambda's 512 MB for temp disk). But 90% of the time, one of these three fixes will get you back online.
Was this solution helpful?