Guides
Guide

How to View and Search AWS Lambda Logs

By Sazabi Team

Last verified on Nov 8, 2026.

Lambda sends everything your function writes to stdout or stderr to Amazon CloudWatch Logs, in a log group named /aws/lambda/<function-name>. You read them in the Lambda console under Monitor, from a terminal with aws logs tail, or by querying the log group with Logs Insights. This guide covers each route, the shape of a Lambda log stream, and what to check when nothing shows up.

Where Lambda Logs Go

By default Lambda captures logs for every invocation and writes them to a log group named /aws/lambda/<function-name>, provided the function's execution role has permission to do so. CloudWatch creates the group the first time the function is invoked, so a function that has never run has no group.

Two permissions-related facts are worth knowing up front:

  • The execution role needs logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents. The AWSLambdaBasicExecutionRole managed policy contains all three.
  • AWS notes that logs can take 5 to 10 minutes to appear after an invocation, so an empty console right after a test is not proof of a problem.

You can point a function at a different group, for example one shared by every function in an application. Custom group names must not begin with aws/, or Lambda cannot create the group and your logs are not delivered.

aws lambda update-function-configuration \
  --function-name my-function \
  --logging-config LogGroup=my-app-logs

When you set the group from the CLI, Lambda does not add logs:PutLogEvents to the role for you. The console does it in some cases, but the CLI never does.

Reading a Log Stream

Each execution environment gets its own log stream, and a new environment means a new stream. When a function scales out, concurrent instances each write to a separate stream. In the default group the stream name looks like YYYY/MM/DD[Function version][Execution environment GUID]. In a custom group, Lambda inserts the function name so streams from different functions stay distinguishable.

Even if your code prints nothing, every invocation produces three platform lines:

START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms  Billed Duration: 80 ms  Memory Size: 128 MB  Max Memory Used: 73 MB

Everything between START and END belongs to one invocation. The REPORT line carries the numbers you usually want: duration, billed duration, memory configured, and memory used. When the invocation was a cold start it also includes Init Duration, the time spent running code outside the handler. The request ID stays the same across retries of the same request.

Viewing Logs in the Console

  1. Open the function in the Lambda console and choose the Monitor tab.
  2. Choose View CloudWatch logs.
  3. Pick the log stream for the invocation you care about.

For logs as they arrive, use Live Tail: open the Test tab, choose CloudWatch Logs Live Tail in the test event pane, optionally add a filter pattern, and choose Start. Live Tail bills by session minute, handles up to 500 events per second, and covers asynchronous invocations. In the Lambda console you can tail up to five log groups at once. A session stops after 15 minutes of inactivity.

Tailing Lambda Logs from the CLI

With AWS CLI version 2, aws logs tail streams a group's events across all its streams. By default it returns the last ten minutes.

# Last 15 minutes, then keep following
aws logs tail /aws/lambda/my-function --since 15m --follow

# Only events containing ERROR (filter patterns are case sensitive)
aws logs tail /aws/lambda/my-function --since 1h --filter-pattern ERROR

# Either of two terms
aws logs tail /aws/lambda/my-function --since 1h --filter-pattern '?ERROR ?"Task timed out"'

# One execution environment's streams by prefix
aws logs tail /aws/lambda/my-function --log-stream-name-prefix 2026/11/08 --format short

--since takes an ISO 8601 timestamp or a single relative unit such as 30s, 5m, 2h, 1d, or 1w. Combined units like 5h30m are not supported. --format can be detailed, short, or json, and json pretty-prints messages that are entirely JSON. AWS notes there is no guarantee of exact timestamp ordering.

For a single synchronous test call, --log-type Tail returns the tail of the invocation log with the response:

aws lambda invoke --function-name my-function out --log-type Tail \
  --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode

That output is capped at the first 4 KB of the invocation's logs, works only for synchronous invocations, and adds to response latency. Use it for smoke tests, and use aws logs tail or Live Tail for anything real.

Querying Lambda Logs with Logs Insights

When you need counts, percentiles, or a search across days, query the group with CloudWatch Logs Insights. Lambda logs always expose the fields @timestamp, @logStream, @message, @requestId, @duration, @billedDuration, @type, @maxMemoryUsed, and @memorySize. Select the /aws/lambda/... group, set the narrowest time range you can, and run one of these. The Logs Insights guide covers the syntax in general.

Everything one invocation logged:

fields @timestamp, @message
| filter @requestId = "57f231fb-1730-4395-85cb-4f71bd2b87b8"
| sort @timestamp asc

Timeouts per half hour:

filter @message like /Task timed out/
| stats count() by bin(30m)

The ten slowest invocations:

filter @type = "REPORT"
| fields @requestId, @duration, @maxMemoryUsed / 1024 / 1024 as usedMB
| sort @duration desc
| limit 10

Cold start share, using the presence of Init Duration on the REPORT line:

filter @type = "REPORT"
| stats sum(strcontains(@message, "Init Duration")) / count(*) * 100 as coldStartPct,
        avg(@duration) as avgMs by bin(15m)

Switching to JSON Logs

Plain text is the default for Lambda runtimes. JSON log format makes each line an object with timestamp, level, message, and requestId keys for supported logging methods, and Logs Insights discovers those fields without parsing. It is available for Node.js 16 and later, Python 3.8 and later, Java (except Java 8 on Amazon Linux 1), and .NET 8 and later, among others, when you log through the runtime's built-in logger or console methods. AWS keeps the full runtime table.

aws lambda update-function-configuration \
  --function-name my-function \
  --logging-config LogFormat=JSON,ApplicationLogLevel=INFO,SystemLogLevel=WARN

Switching changes only new log events, and it makes messages larger. Turning on JSON without choosing a level sets both application and system levels to INFO, which can quietly drop DEBUG output you were relying on. If your code sets its own level, that takes precedence over the Lambda setting. See structured logging and the JSON logging guide for field design.

When Lambda Logs Are Missing

Work down this list:

  1. Wrong region or function. Log groups are regional. Check the region in the console or pass --region.
  2. Never invoked. No invocation, no log group.
  3. Execution role. Confirm logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents. Attach AWSLambdaBasicExecutionRole if they are absent, especially after changing the log group from the CLI.
  4. Custom group name starts with aws/. Lambda cannot create it, so nothing is delivered.
  5. Level filtering. In JSON format, anything below the configured application level is dropped before it reaches CloudWatch.
  6. Timing. Wait several minutes, then refresh.
  7. Retention. A short retention period on the group deletes old events. See log retention.

Searching Lambda Logs with Sazabi

Sazabi, an AI-native observability and security platform, reads Lambda logs through the same CloudWatch log groups. In Sazabi go to Settings > Log streams, choose Add source, and select CloudWatch. Create the IAM role with CloudFormation, Terraform, or the AWS CLI using the snippets the dashboard gives you, paste the role ARN, then choose Add log stream and pick your /aws/lambda/... groups. Sazabi installs a subscription filter on each selected group, and only groups in the same region as your Sazabi project are listed.

AWS lists a quota of five subscription filters per log group, while Sazabi's setup doc describes a limit of two, so check what is already attached with aws logs describe-subscription-filters --log-group-name /aws/lambda/my-function before adding a stream. Once records show on the Intake page, ask questions from the CLI, for example sazabi logs ask "timeouts per function in the last hour". The setup is covered in the CloudWatch log source docs and on the CloudWatch integration page. For cost, see CloudWatch pricing.

Frequently Asked Questions

Where are AWS Lambda logs stored?

In Amazon CloudWatch Logs. By default Lambda writes to a log group named /aws/lambda/ followed by the function name, and creates it on the first invocation. Each execution environment writes to its own log stream.

Why are my Lambda logs not showing up in CloudWatch?

The usual causes are an execution role missing logs:CreateLogGroup, logs:CreateLogStream, or logs:PutLogEvents, a custom log group name that starts with aws/, a log level that filters out your messages, looking in the wrong region, or a function that has not been invoked yet.

How do I tail Lambda logs from the command line?

Run aws logs tail /aws/lambda/your-function --follow --since 15m with AWS CLI version 2. Add --filter-pattern ERROR to show only matching events.

How do I see the logs for a single Lambda invocation?

Every invocation has a request ID printed on its START, END, and REPORT lines. Search the log group for that ID, or run a Logs Insights query that filters on @requestId.

Sources

  1. Default log group /aws/lambda/<function-name>, required logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents permissions, the AWSLambdaBasicExecutionRole managed policy, and the 5 to 10 minute delay note (accessed Nov 8, 2026)
  2. Console Monitor tab, log stream naming, START, END, and REPORT lines, Live Tail, aws lambda invoke --log-type Tail limited to 4 KB, and the Logs Insights queries for timeouts, cold starts, and duration (accessed Nov 8, 2026)
  3. JSON log format keys, supported runtimes, and the --logging-config LogFormat=JSON command (accessed Nov 8, 2026)
  4. Custom log groups, the custom stream naming convention, the rule that custom names must not begin with aws/, and that CLI configuration does not add logs:PutLogEvents (accessed Nov 8, 2026)
  5. Log-level filtering needs JSON format; default application level INFO; ApplicationLogLevel and SystemLogLevel settings (accessed Nov 8, 2026)
  6. aws logs tail options --since, --follow, --format, and --filter-pattern, and the ten minute default window (accessed Nov 8, 2026)
  7. Filter patterns are case sensitive; ?term optional matching and JSON selectors such as { $.errorCode = 400 } (accessed Nov 8, 2026)
  8. aws logs describe-subscription-filters lists the subscription filters on a log group (accessed Nov 8, 2026)
  9. Subscription filter quota per log group (accessed Nov 8, 2026)
  10. Connecting a CloudWatch log source from Settings > Log streams, the IAM role setup methods, the same-region rule, and subscription filter installation (accessed Nov 8, 2026)