Skip to main content

cloudwatch-janitor 🧹

CI PyPI License: MIT Python 3.10+

Find the CloudWatch waste hiding in your AWS bill — in one read-only command.

CloudWatch costs creep up silently: log groups that keep data forever, alarms watching resources that were deleted months ago, dashboards nobody has opened since 2024. cloudwatch-janitor scans your account, lists every finding, and estimates what it's costing you per month.

It never modifies anything. Four read-only API calls, that's it.

CHECK             RESOURCE                        ISSUE                                              EST. $/MO
----------------  ------------------------------  -------------------------------------------------  ---------
log-retention     /aws/lambda/etl-processor       No retention policy (312.40 GB stored, growing…)   9.37
log-retention     /aws/eks/prod-cluster/apps      No retention policy (88.10 GB stored, growing…)    2.64
idle-log-groups   /aws/lambda/old-webhook-fn      No incoming events in 90 days (12.33 GB stored)    0.37
stale-alarms      db-conn-alarm-legacy            INSUFFICIENT_DATA for 214 days (metric likely…)    0.10
stale-dashboards  team-x-dashboard                Not modified in 431 days                           3.00

5 finding(s), estimated savings: $15.48/month (rough estimate, standard pricing)

Install

pip install cloudwatch-janitor

Or straight from GitHub:

pip install git+https://github.com/varunmj/cloudwatch-janitor.git

Or clone and run directly:

git clone https://github.com/varunmj/cloudwatch-janitor.git
cd cloudwatch-janitor && pip install -e .

Usage

# Scan the default profile/region
cloudwatch-janitor

# Specific profile and region
cloudwatch-janitor --profile prod --region us-west-2

# Only some checks
cloudwatch-janitor --checks log-retention,stale-alarms

# JSON output (pipe it, save it, alert on it)
cloudwatch-janitor --json > findings.json

What it checks

Check What it finds Why it matters
log-retention Log groups with no retention policy Logs are stored forever at ~$0.03/GB-month, growing every day
idle-log-groups Log groups with zero incoming events in 90 days but data still stored Usually left behind by deleted Lambdas/services — safe to remove
stale-alarms Alarms in INSUFFICIENT_DATA for 30+ days The metric is probably gone; you're paying for monitoring that monitors nothing
stale-dashboards Dashboards not modified in 180+ days Dashboards beyond the first 3 cost $3/month each

Cost estimates are deliberately rough (us-east-1 standard pricing) — they're there to help you prioritize, not to reconcile your bill.

Permissions

Least privilege, read-only. Attach docs/iam-policy.json:

{
  "Action": [
    "logs:DescribeLogGroups",
    "cloudwatch:DescribeAlarms",
    "cloudwatch:GetMetricData",
    "cloudwatch:ListDashboards"
  ]
}

Contributing

New checks are the easiest way to contribute — each check is a single file in cw_janitor/checks/ exposing CHECK_ID, TITLE, and run(session, region) -> list[Finding]. See CONTRIBUTING.md and the open issues for ideas (unused custom metrics, orphaned metric filters, Contributor Insights rules...).

License

MIT

Metadata

Release files for cloudwatch-janitor 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cloudwatch-janitor 0.1.0
File Size Uploaded
cloudwatch_janitor-0.1.0.tar.gz 9.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cloudwatch-janitor 0.1.0
File Interpreter ABI Platform
cloudwatch_janitor-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.3 kB

Release files / cloudwatch_janitor-0.1.0.tar.gz

Download URL cloudwatch_janitor-0.1.0.tar.gz
Size 9.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d156d48a3d70a3c1e9d92c32fe3ed9b311e9abbebb0007b7dfea5d35138adb78
BLAKE2b-256 checksum
How to use checksums
d74c98fc7a207f69adb28e7198c226c77177fc6342ad5038a6c5638459a98405
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.

Transparency log

Release files / cloudwatch_janitor-0.1.0-py3-none-any.whl

Download URL cloudwatch_janitor-0.1.0-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b02dfbfc40a0ee2c8463d2fcd755d47028b84f86895708adc33ab052aa9f0fe
BLAKE2b-256 checksum
How to use checksums
c5861578eda30b25162e61c88aa82381d045a77fabe8f42c9c465587e82857d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page