How to Delete AWS Lambda Logs from CloudWatch Using Python Scripts

4 min read

Lambda functions create CloudWatch log groups automatically, and they never clean up after themselves. Over time you end up with hundreds of log groups — many from functions you’ve already deleted. This guide shows you how to delete AWS Lambda logs from CloudWatch using Python scripts with boto3, plus a quick AWS CLI option for simpler cases.

The examples here are run on WSL2 Ubuntu in Windows, but they work the same on any system with Python and AWS credentials configured.

Prerequisites

  • Python 3.8+ and boto3 installed (pip install boto3)
  • AWS CLI v2 installed and configured with credentials
  • IAM permissions: logs:DescribeLogGroups, logs:DescribeLogStreams, logs:DeleteLogGroup, logs:DeleteLogStream

Option 1: Set a Retention Policy Instead of Deleting

Before deleting logs manually, consider setting a retention policy. By default, CloudWatch log groups retain logs forever. Setting a retention period lets AWS delete old logs automatically — no scripts needed.

aws logs put-retention-policy \
  --log-group-name /aws/lambda/my-function \
  --retention-in-days 14 \
  --region ap-southeast-1

Common retention values: 1, 3, 7, 14, 30, 60, 90, 180, 365 days. To set retention on all Lambda log groups at once:

import boto3

client = boto3.client('logs', region_name='ap-southeast-1')
paginator = client.get_paginator('describe_log_groups')

for page in paginator.paginate(logGroupNamePrefix='/aws/lambda/'):
    for group in page['logGroups']:
        name = group['logGroupName']
        if 'retentionInDays' not in group:
            print(f"Setting 14-day retention on: {name}")
            client.put_retention_policy(
                logGroupName=name,
                retentionInDays=14
            )

This script only updates log groups that don’t already have a retention policy set. If retention policies solve your problem, you can stop here. For log groups you want to remove entirely, keep reading.

Option 2: Delete a Single Log Group with AWS CLI

If you just need to remove one log group, the AWS CLI is the fastest option. This deletes the log group and all its log streams and events permanently:

aws logs delete-log-group \
  --log-group-name /aws/lambda/my-function \
  --region ap-southeast-1

No output means it succeeded. If the log group doesn’t exist, you’ll get a ResourceNotFoundException.

Option 3: Delete Log Streams from a Log Group

If you want to keep the log group but clear out old log streams, use this script. It paginates through all streams in the group and deletes them one by one:

import boto3

client = boto3.client('logs', region_name='ap-southeast-1')
log_group_name = '/aws/lambda/my-function'

def delete_log_streams(client, log_group_name):
    paginator = client.get_paginator('describe_log_streams')
    for page in paginator.paginate(logGroupName=log_group_name):
        for stream in page['logStreams']:
            name = stream['logStreamName']
            try:
                print(f"Deleting: {name}")
                client.delete_log_stream(
                    logGroupName=log_group_name,
                    logStreamName=name
                )
            except Exception as e:
                print(f"Error deleting {name}: {e}")

if __name__ == '__main__':
    print(f"Deleting all log streams in: {log_group_name}")
    delete_log_streams(client, log_group_name)
    print("Done")

This is useful when a log group has thousands of streams and you want a fresh start without recreating the group.

Option 4: Bulk Delete Lambda Log Groups

This is the most common use case — deleting log groups from Lambda functions that no longer exist. The script below lists all log groups matching /aws/lambda/, shows them in a dry-run first, then asks for confirmation before deleting:

import boto3

client = boto3.client('logs', region_name='ap-southeast-1')

def get_lambda_log_groups(client):
    groups = []
    paginator = client.get_paginator('describe_log_groups')
    for page in paginator.paginate(logGroupNamePrefix='/aws/lambda/'):
        for group in page['logGroups']:
            groups.append(group['logGroupName'])
    return groups

def delete_log_groups(client, groups):
    for name in groups:
        try:
            print(f"Deleting: {name}")
            client.delete_log_group(logGroupName=name)
        except Exception as e:
            print(f"Error deleting {name}: {e}")

if __name__ == '__main__':
    groups = get_lambda_log_groups(client)
    print(f"Found {len(groups)} Lambda log groups:\n")
    for g in groups:
        print(f"  {g}")

    confirm = input(f"\nDelete all {len(groups)} log groups? (yes/no): ")
    if confirm.lower() == 'yes':
        delete_log_groups(client, groups)
        print("Done")
    else:
        print("Cancelled")
  • logGroupNamePrefix='/aws/lambda/' — filters to only Lambda log groups
  • The dry-run lists all matches before deleting anything
  • Type yes to confirm, anything else cancels

To target a specific set of functions, change the prefix filter — for example, /aws/lambda/dev- to only match log groups from functions starting with dev-.

Required IAM Permissions

The IAM user or role running these scripts needs the following permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:DeleteLogGroup",
                "logs:DeleteLogStream",
                "logs:PutRetentionPolicy"
            ],
            "Resource": "arn:aws:logs:*:123456789012:log-group:/aws/lambda/*"
        }
    ]
}

The resource ARN is scoped to Lambda log groups only. Adjust it if you need to manage log groups from other services.

Conclusion

For ongoing log management, set retention policies so CloudWatch cleans up automatically. For one-off cleanup, use the AWS CLI for single groups or the Python bulk deletion script for clearing out old Lambda log groups. Always check what you’re deleting before confirming — deleted logs can’t be recovered.

If your Lambda functions are generating too many logs due to SQS retries, see How to Fix SQS Visibility Timeout in AWS Lambda. For organizing your Lambda code, check out How to Structure Your Python Projects for AWS Lambda, APIs, and CLI Tools.