Skip to content
KostrixBeta, home

235 AWS cost optimization checks, and an honest account of where they stop.

Kostrix is a scanner, a reconciler and a report, in that order. The list below is the scanner in full, and the AWS cost-saving opportunities it looks for: unused EBS volumes and orphaned snapshots, idle EC2 instances, idle RDS databases, idle NAT gateways, load balancers with no healthy targets, S3 buckets without lifecycle rules, and Savings Plans and reserved instance coverage. What makes the output usable in a room with a CFO is that every figure states its unit, names its denominator, and shows the terms it was built from.
Scan scopedefaults
Detection rules
235 built in
Service families
15 covered
Regions
All enabled, unless pinned
Window
Trailing 30 days, run rate
Finding key
account + region + rule + resource

Eleven things the output does on every run

  1. 01

    235 AWS cost checks on every scan

    Storage, compute, networking, databases, serverless, containers, ML and governance. Each one named, each one identifiable on the finding it raises.

  2. 02

    Savings Plans and reserved-instance coverage

    Savings Plans coverage as a share of eligible spend, reserved instance coverage as a share of eligible hours, and a purchase sized to steady-state usage.

  3. 03

    Every enabled AWS region

    Not a default list, not the regions that happened to be cheap to query. Every region enabled on the account, unless the operator pins the list deliberately.

  4. 04

    Prints the arithmetic

    Each estimate carries its terms. Multiply the printed terms and you land on the printed saving, exactly.

  5. 05

    Reconciles findings against the bill

    Findings are checked back against billed line items, and the items no rule covers are listed as plainly as the ones that are.

  6. 06

    Refuses to invent data

    A failed or empty call is skipped and logged loudly. It is never quietly rendered as a zero, and a price is never guessed: where your bill carries the usage, a finding is priced at what you actually paid per unit over the last 30 days - after your free allowances and discounts - and the finding says so; where it does not, the finding prints the quantity and says why.

  7. 07

    Asks AWS for a second opinion

    Cost Optimization Hub and Compute Optimizer are read on every scan. Each finding says whether AWS agrees, is silent, or raised it alone; AWS's estimate is printed beside Kostrix's, never added to it.

  8. 08

    Reads the AI bill by model

    Bedrock spend by provider, model, inference type and feature, with the token mix; models paying on-demand with no batch inference, sending input with no prompt caching, or holding provisioned throughput below its break-even are flagged - priced from your own bill and AWS's published ratios, never a guess.

  9. 09

    Allocates what the tags miss

    Allocation rules give resources without cost allocation tags a team by account, tag, name or service; shared pools are split evenly or in proportion; the unallocated remainder is listed, not spread. Your AWS Cost Categories are read and shown beside it.

  10. 10

    Answers "what if I commit $X an hour?"

    Pick a Savings Plan type, term, payment option and hourly commitment: coverage, utilization, net saving and break-even over your recent on-demand usage, hour by hour, with AWS's own recommendation beside it. Nothing is bought from the page.

  11. 11

    Names the cause of a spend spike

    Daily spend is tested per service, per region and per member account, AWS Cost Anomaly Detection is read where it is on, and the CloudTrail change events of that day are attached: who launched or changed what.

Every check, with the identifier it puts on a finding.

Fifteen service families, counted below and listed in full under them: open a family to read each check and the rule identifier it stamps on its findings.

The checks cover unattached EBS volumes and orphaned snapshots, idle and stopped EC2 instances, unassociated Elastic IPs, NAT gateways moving no bytes, load balancers with no healthy targets, RDS and ElastiCache instances nobody connects to, over-provisioned DynamoDB tables, idle Lambda functions, EKS and ECS waste, GPU boxes sitting warm, SageMaker endpoints and Bedrock provisioned throughput nobody calls, plus Graviton and Spot migration candidates and public IPv4 charges. Each check is priced from the AWS Price List API for the region the resource sits in; where a rate cannot be fetched the finding is still raised, without a figure attached.

Two families are written up in full, with the metric each check reads: unused EBS volumes and orphaned snapshots and idle EC2 instances, RDS databases, NAT gateways and load balancers.

Block storage and object storage

25 checks

EBS volumes and snapshots, S3 buckets, EFS file systems, AWS Backup, Storage Gateway, FSx and Transfer Family

Show the 25 checks
  • EBS volumes unattached or attached with zero I/Oebs-unattached
  • Orphaned or aged EBS snapshotsebs-snapshot-orphans
  • gp2 volumes cheaper as gp3ebs-gp2-to-gp3
  • Incomplete multipart uploads and missing lifecycle policiess3-hygiene
  • Large Standard-class buckets with no tiering configurations3-intelligent-tiering
  • io1/io2 volumes that fit inside gp3's performance envelopeebs-io-rightsize
  • Fast Snapshot Restore enabled on snapshots nothing has been restored fromebs-fsr-idle
  • EFS file systems with no client connections and no I/O over the lookbackefs-idle-filesystem
  • EFS file systems on Provisioned Throughput driving far less than they pay forefs-provisioned-throughput-idle
  • EFS file systems with no IA or Archive lifecycle transition while their data looks coldefs-lifecycle-absent
  • Regional EFS file systems whose mount targets all sit in one Availability Zoneefs-one-zone-candidate
  • S3 buckets holding stale incomplete multipart upload parts, billed and invisible to object listingss3-incomplete-multipart-uploads
  • Versioning-enabled S3 buckets with no whole-bucket noncurrent-version expiration rules3-noncurrent-version-bloat
  • S3 lifecycle rules archiving objects small enough that per-object overhead swamps the savings3-archive-small-object-overhead
  • S3 Intelligent-Tiering monitoring fee paid on objects too small ever to tiers3-intelligent-tiering-small-object-fee
  • Long-retained standalone EBS snapshots in the standard tier that are archive-tier candidatesebs-snapshot-archive-candidates
  • AWS Backup recovery points whose source resource no longer exists and which never expirebackup-orphaned-recovery-points
  • Long-retention AWS Backup plans that never transition recovery points to cold storagebackup-cold-storage-lifecycle-absent
  • Storage Gateway with no traffic for 30 days still holding billable volumes or virtual tapesstorage-gateway-idle
  • FSx file system (Windows, Lustre, ONTAP or OpenZFS) with no data read or written for 30 daysfsx-idle-filesystem
  • FSx for Windows / ONTAP / OpenZFS provisioned at a throughput tier far above its measured ceilingfsx-throughput-overprovisioned
  • FSx for ONTAP volumes pinned to SSD with capacity-pool tiering disabledfsx-ontap-tiering-absent
  • AWS Transfer Family servers billing protocol-hours for SFTP/FTPS/FTP/AS2 endpoints with zero confirmed transfer activity in 30 daystransfer-family-protocol-idle
  • S3 Batch Operations jobs billed for failed task attempts alongside successful oness3-batch-operations-failed-billed
  • S3 Storage Lens configurations on the paid advanced-metrics tier, sized by objects monitoreds3-storage-lens-advanced-metrics-cost

EC2 and compute

22 checks

Instances, images, addresses, purchase mode, container capacity, Lightsail, GameLift, AppStream and Outposts

Show the 22 checks
  • Elastic IPs not associated with any resourceeip-unassociated
  • Running instances with negligible CPU and networkec2-idle
  • Long-stopped instances still billing for storageec2-stopped
  • AMIs referenced by no instanceami-unreferenced
  • Dev/test instances running 24×7offhours-candidates
  • x86 instances with a drop-in Graviton equivalent at a lower On-Demand rategraviton-migration
  • Underutilized EC2/RDS instances with a cheaper same-family sizeec2-rds-rightsizing
  • Interruption-tolerant On-Demand workloads that could run on Spotspot-candidates
  • Fargate services idle or oversized for their reserved task sizeecs-rightsizing
  • EKS control planes with no nodegroups, no Fargate profiles and no tagged nodeseks-cluster-waste
  • GPU/accelerator instances with near-idle CPUgpu-idle
  • Dedicated Hosts running no instances, or packed below half capacitydedicated-host-underutilized
  • Running instances on previous-generation x86 families that cost more than the same-size current-generation equivalentec2-previous-generation-family
  • T-family instances in unlimited mode paying surplus CPU credit charges above the cost of a fixed-performance instanceec2-burstable-surplus-credits
  • ECS clusters whose EC2 container instances are reserved far below capacityecs-ec2-cluster-packing
  • Licence-included SQL Server billed per vCPU on instances CPU metrics show sitting idlesql-server-license-density
  • Lightsail instances billing a full monthly bundle while doing nothing, including stopped oneslightsail-idle-instance
  • Lightsail static IPs, disks, snapshots and load balancers left behind after their instance is gonelightsail-orphaned-resources
  • GameLift managed EC2 fleets holding ACTIVE instances with no game or player sessions, or chronic idle capacity with no scaling policygamelift-fleet-idle
  • AppStream fleets holding capacity with no streaming sessions, or chronic low utilization with no scaling policyappstream-fleet-idle
  • EKS clusters billed the extended-support control-plane surcharge for running a Kubernetes version past standard supporteks-extended-support-charges
  • AWS Outposts racks/servers whose committed EC2 capacity sits mostly unlaunchedoutposts-capacity-underutilized

Networking, CDN and edge

27 checks

Load balancers, NAT, PrivateLink, Transit Gateway, CloudFront, Route 53, Route 53 ARC, Cloud WAN, VPC Lattice and dedicated links

Show the 27 checks
  • Load balancers with no listeners or no healthy targetselb-half-connected
  • Target groups with no registered targetstarget-group-empty
  • NAT gateways with ~zero bytes processednat-idle
  • VPCs sending S3/DynamoDB traffic through a NAT gateway instead of a free gateway endpointvpc-missing-gateway-endpoints
  • In-use public IPv4 addresses billing $3.65/month eachpublic-ipv4-audit
  • CloudFront distributions paying for Dedicated IP custom SSL where free SNI would servecloudfront-dedicated-ip-ssl
  • Near-zero-traffic CloudFront distributions still billing through an attached paid featurecloudfront-idle-billable-attachments
  • High-volume CloudFront distributions with a low cache hit rate traceable to the cache keycloudfront-cache-hit-low
  • CloudFront behaviours serving compressible content with compression off or defeated by the cache keycloudfront-compression-disabled
  • Transit Gateway attachments billing hourly with no bytes crossing themtgw-attachment-idle
  • Interface VPC endpoints billing ENI-hours in Availability Zones with no trafficvpce-interface-idle
  • Client VPN endpoints billing association-hours with nobody connectingclientvpn-endpoint-idle
  • Subnet and ENI flow logs re-delivering traffic a VPC-level flow log already deliversflow-logs-duplicate-coverage
  • Route 53 Resolver endpoints billing ENI-hours with no queries or no path to receive themroute53-resolver-endpoint-idle
  • Traffic Flow policy records still instantiated against a dead zone or dead endpointsroute53-traffic-policy-orphan
  • Route 53 hosted zones with no useful records, no VPC association, or no queries over 30 daysroute53-hosted-zone-unused
  • Route 53 health checks nothing in this account references, or that have been down all windowroute53-health-check-orphan
  • Global Accelerator accelerators billing the fixed fee while disabled, endpoint-less or flow-freeglobalaccelerator-idle
  • Site-to-Site VPN connections billing hourly whose tunnels were down for the entire windowvpn-tunnel-never-established
  • Direct Connect ports billing port-hours with no virtual interface or no BGP session all windowdx-connection-or-vif-orphan
  • VPC IPAM billed at Advanced Tier while none of its own tier-downgrade-blocking features are configuredipam-advanced-tier-unneeded
  • Route 53 ARC routing control clusters billed hourly with zero routing controls configuredroute53arc-cluster-empty
  • Route 53 ARC readiness checks billing hourly whose audited resources read as unresolvableroute53arc-readiness-check-stale
  • Gateway Load Balancers billed hourly with an empty or genuinely traffic-free target groupgwlb-target-group-empty
  • Cloud WAN core network edges billed hourly with zero attachments or zero attachment trafficcloudwan-edge-idle
  • VPC Lattice Services billed hourly with zero requests over the trailing 30 daysvpclattice-service-idle
  • Classic Load Balancers billed hourly with zero requests to zero healthy instancesclb-idle-zero-traffic

Databases and caches

36 checks

RDS and Aurora, DynamoDB and DAX, ElastiCache, MemoryDB, DocumentDB, Neptune, Amazon MQ, Keyspaces, DMS and Timestream

Show the 36 checks
  • RDS instances with zero connectionsrds-idle
  • Provisioned DynamoDB far above consumptiondynamodb-overprovisioned
  • ElastiCache clusters with no client connectionselasticache-idle
  • Provisioned DynamoDB tables with zero consumed capacitydynamodb-idle
  • MemoryDB clusters with no client connectionsmemorydb-idle
  • Aurora clusters on Standard paying heavy I/O charges, or on I/O-Optimized paying the premium for trivial I/Oaurora-storage-class-mismatch
  • Aurora Serverless v2 clusters billed at a minimum-ACU floor they never rise aboveaurora-serverless-v2-min-acu-floor
  • DocumentDB clusters with no connections, unused reader replicas, and over-long backup retentiondocumentdb-idle
  • Databases enrolled in RDS Extended Support for an end-of-life engine versionrds-extended-support-charges
  • Stopped RDS instances still billing for storage, and restarted every seven daysrds-stopped-instance-residual
  • Multi-AZ enabled on a database tagged non-productionrds-multiaz-nonproduction
  • RDS instances on previous-generation classes with a cheaper current-generation equivalentrds-previous-generation-class
  • Manual snapshots, orphaned snapshots and retained automated backups billing indefinitelyrds-backup-storage-sprawl
  • RDS Proxies with no client connections, or pointing at an unavailable targetrds-proxy-idle
  • RDS instances on io1/io2 or over-allocated gp2 paying for IOPS gp3 includesrds-provisioned-iops-overpay
  • Neptune clusters holding a loaded graph with no query traffic, idle provisioned readers, and Serverless instances pinned at the minimum-NCU floorneptune-idle
  • Aurora clones older than the measurement window whose database connections have been measured at zero throughout itaurora-clone-sprawl
  • Aurora MySQL clusters with a backtrack window configured and billing whose backtrack capability has not been exercised in the measurement windowaurora-backtrack-unused
  • RDS instances with storage autoscaling enabled whose minimum free space never fell below the configured share of a permanently ratcheted allocationrds-storage-highwater-mark
  • Amazon MQ brokers whose connection, message, producer and consumer maxima are measured at zero on every node for the whole measurement windowmq-idle-broker
  • Amazon Keyspaces tables over-provisioned, in the costlier capacity mode, or billing storage and PITR with no query traffickeyspaces-capacity-mismatch
  • DMS replication instances (and DMS Serverless replications) billing with no running migration taskdms-idle-replication-instance
  • Timestream tables holding data in the memory store far longer than their metered bytes are shown to needtimestream-memory-store-retention
  • Performance Insights long-term retention or Database Insights Advanced mode, enabled fleet-wide, priced from the account's own billrds-performance-insights-retention
  • DAX cluster nodes billed per node-hour while serving zero cache requestsdynamodb-dax-idle
  • PITR and on-demand backup storage billed on a table nobody readsdynamodb-pitr-backup-storage
  • Global Secondary Indexes billed for storage and throughput while never once being querieddynamodb-gsi-unused
  • Standard-class tables whose measured storage-vs-throughput mix already crosses over to Standard-IAdynamodb-standard-ia-candidate
  • Global-table replica regions billed full replicated-write price while serving zero local readsdynamodb-global-table-replica-idle-reads
  • ElastiCache Serverless caches billed for a fixed storage floor their measured data never approacheselasticache-serverless-storage-floor
  • ElastiCache snapshot storage billed above the one-free-snapshot-per-cache allowanceelasticache-backup-storage-overage
  • ElastiCache cache.r6gd data-tiering clusters whose measured dataset never approaches the equivalent memory-only capacityelasticache-r6gd-tier-unused
  • Aurora Global Database secondary-region clusters billing full standing compute and storage with no CloudWatch evidence of read trafficaurora-global-db-secondary-standing-cost
  • Aurora Global Database replicated-write-I/O charges accruing in every secondary region, proportional to primary write volumeaurora-global-db-replicated-write-io-spend
  • Aurora Global Database redo-log cross-region data-transfer charges billed on top of the per-I/O replication feeaurora-global-db-cross-region-data-transfer
  • Timestream for InfluxDB dedicated DB instances billed hourly (plus provisioned storage) while CPU and query activity stay near zerotimestream-influxdb-instance-idle

Serverless and integration

15 checks

Lambda, API Gateway, Step Functions, SQS, SNS and EventBridge

Show the 15 checks
  • Lambda functions with zero invocations in 30 dayslambda-idle
  • x86 Lambda functions that would bill ~20% less on arm64lambda-graviton
  • Lambda provisioned concurrency that nothing invokedlambda-provisioned-concurrency-idle
  • API Gateway stage caches billing by the hour while serving few or no cache hitsapigw-stage-cache-unused
  • REST API stages billed at REST rates while using only features an HTTP API supportsapigw-rest-to-http-api
  • Lambda functions billing GB-seconds against memory their measured peak never approacheslambda-memory-overallocated
  • Lambda functions whose recursive invocation loops AWS had to terminate, and functions with loop detection disabledlambda-recursive-loop-burn
  • High-volume, short-lived Standard Workflows that meet every Express Workflow eligibility gatesfn-standard-to-express
  • SQS queues short-polling hard enough that most billed ReceiveMessage calls return nothingsqs-short-poll-empty-receives
  • SNS topics billing publish requests with zero live subscriptions to deliver tosns-topic-no-live-subscribers
  • API Gateway, Step Functions and AppSync resources pinned to their most verbose logging setting, driving CloudWatch Logs ingestion chargesmanaged-service-log-verbosity
  • EventBridge archives on indefinite retention, large and old, with no replay in the account's replay historyeventbridge-archive-never-replayed
  • Express Step Functions workflows whose billed memory is inflated far above the 64 MB minimum by oversized payloadssfn-express-billed-memory
  • Standard Step Functions state machines burning billed state transitions on executions that fail, abort or time outsfn-failed-execution-transitions
  • Lambda functions provisioning /tmp above the 512 MB free allotment, billing a per-GB-second overage on every invocationlambda-ephemeral-storage-overprovisioned

Machine learning and AI

15 checks

Bedrock, SageMaker, Comprehend, Kendra, Rekognition, Personalize and Q Business

Show the 15 checks
  • Bedrock provisioned throughput billing hourly with near-zero invocationsbedrock-spend-guard
  • SageMaker endpoints with zero invocationssagemaker-endpoint-idle
  • SageMaker notebook instances left running with no Jupyter activitysagemaker-notebook-idle
  • SageMaker Studio apps left InService, billing an ML instance with nobody using themsagemaker-studio-app-idle
  • SageMaker training, processing and transform jobs that failed but were still billedsagemaker-training-job-failed-billed
  • Comprehend custom-model endpoints running with no inferencecomprehend-endpoint-idle
  • Kendra indexes billing edition base and capacity units with no querieskendra-index-idle
  • SageMaker real-time endpoint variants running more instances than their traffic needssagemaker-endpoint-overprovisioned
  • SageMaker Studio spaces billing provisioned ML storage with no app attachedsagemaker-space-orphan-storage
  • SageMaker Feature Store online stores written to but never readsagemaker-feature-store-online-unread
  • Comprehend custom-model endpoints provisioned at more inference units than they consumecomprehend-endpoint-overprovisioned
  • Rekognition Custom Labels model versions left in RUNNING, billing inference-unit-hoursrekognition-custom-labels-model-running
  • Managed MLflow tracking servers left running after the experiment ended, and servers billing while marked inactivesagemaker-mlflow-idle
  • Personalize campaigns and recommenders billing a minProvisionedTPS floor with zero measured trafficpersonalize-campaign-overprovisioned
  • Q Business indexes billing capacity units with nothing indexed, no live consumer, or capacity well past what indexed content needsqbusiness-index-idle

Security and compliance

22 checks

GuardDuty, Security Hub, WAF, Secrets Manager, KMS, ACM, Access Analyzer, Detective, Inspector, Macie, Shield, Audit Manager, Security Lake, Resilience Hub, Private CA, License Manager, CloudHSM, Directory Service and Cognito

Show the 22 checks
  • ACM certificates nearing expiryacm-expiry
  • GuardDuty detectors billing in regions where the account holds no workload to analyseguardduty-idle-region-spend
  • Security Hub CSPM billing per check in regions where the account holds no resources to checksecurityhub-idle-region-standards
  • WAFv2 REGIONAL web ACLs billed with no associated resource (CloudFront-scope ACLs are not assessed)waf-webacl-unassociated
  • Secrets billed monthly that have not been retrieved in the trailing 90 days, and their separately-billed replicassecretsmanager-unused-secrets
  • Customer-managed KMS keys billed monthly while disabled or pending deletion (unreferenced-key detection is deliberately not attempted)kms-idle-cmk-billing
  • IAM Access Analyzer internal-access analyzers billing $9/resource/region/month against an over-broad inclusion ruleaccess-analyzer-internal-access-scope
  • Unused-access analyzers billing $0.20/principal/month, duplicated or spent on long-dead IAM principalsaccess-analyzer-unused-access-dead-principals
  • Detective behaviour graphs ingesting at $2/GB, including data-source packages for services the account does not rundetective-graph-and-package-scope
  • GuardDuty Runtime Monitoring billed per vCPU on compute this scan can independently show is idle or stoppedguardduty-runtime-monitoring-scope
  • Inspector Lambda code scanning and CIS assessment schedules billed across the whole fleet, including never-invoked functionsinspector-paid-addon-scope
  • Macie automated sensitive-data discovery scoped over log, backup and analytics buckets at $1/GB inspectedmacie-discovery-scope
  • Shield Advanced's flat $3,000/month subscription protecting zero or vanished resourcesshield-advanced-unused-subscription
  • S3 buckets encrypted with SSE-KMS but without S3 Bucket Keys enabled, multiplying KMS request chargeskms-sse-kms-without-bucket-keys
  • ACTIVE AWS Private CAs billing their flat monthly operation fee with zero certificates issued in the trailing 30 daysacm-pca-idle-ca
  • AWS License Manager user-based subscriptions still billing a user associated to a terminated or long-stopped EC2 instancelicensemanager-usersub-orphaned-association
  • Audit Manager assessments billing per-resource-assessment charges that have never produced an assessment reportaudit-manager-active-no-report
  • Security Lake data lakes ingesting, normalizing and storing log sources with zero subscribers configured to read themsecurity-lake-collector-no-subscribers
  • Resilience Hub applications already billing their monthly fee whose compliance has not been re-evaluated in over 30 daysresilience-hub-app-compliance-stale
  • CloudHSM clusters with billing HSMs that are not initialised or active, so they bill by the hour and serve nothingcloudhsm-cluster-not-serving
  • Directory Service directories (Managed Microsoft AD, Simple AD) that are not Active or served no LDAP, Kerberos or NTLM request in the windowdirectory-service-idle
  • Cognito user pools on the Essentials or Plus tier with no sign-ins in the window, or on Plus with threat protection switched offcognito-paid-tier-unused

Observability and governance

18 checks

CloudWatch metrics, alarms, dashboards and logs, AWS Config, CloudTrail, tagging, Application Signals, CloudWatch RUM, X-Ray and Managed Grafana

Show the 18 checks
  • Log groups with retention set to Never Expirelogs-retention
  • Resources missing required cost-allocation tagstag-hygiene
  • CloudWatch alarms watching EC2, RDS, ELB, Lambda, DynamoDB, ElastiCache, OpenSearch, ECS or EKS resources that no longer existcloudwatch-alarm-orphaned
  • Custom CloudWatch metrics receiving data that no in-account alarm, dashboard or metric stream consumescloudwatch-custom-metrics-unreferenced
  • Billable CloudWatch dashboards whose referenced metrics return no datapoints and which have not been modified in monthscloudwatch-dashboard-dead
  • CloudWatch metric streams whose destination has been failing for the whole window, or which stream every namespace in the regioncloudwatch-metric-stream-waste
  • High-volume Standard-class CloudWatch log groups using no Standard-only feature, eligible for the Infrequent Access classlogs-standard-to-infrequent-access
  • Periodic Config rules evaluating hourly, and managed rules billed twice through a conformance packconfig-rule-hourly-evaluation-frequency
  • Config recorders recording global IAM resource types in more than one regionconfig-recorder-sprawl
  • Config recorders on all resource types at CONTINUOUS frequency where measured churn is past the per-day break-evenconfig-recording-scope-and-frequency
  • More than one trail or Lake event data store delivering the same management eventscloudtrail-duplicate-management-trails
  • CloudTrail Insights billing to analyse every event while detecting nothingcloudtrail-insights-no-detections
  • CloudWatch Contributor Insights rules matching nothing, or matching everything with no alarm or dashboard consuming itcontributor-insights-rules-unused
  • Application Signals services with measurable traffic, no SLO, and no alarm or dashboard consuming their signalsapplication-signals-no-objective
  • CloudWatch RUM app monitors sampling all sessions with every telemetry type on, on measurable high trafficrum-appmonitor-oversampled
  • X-Ray sampling rules capturing traces at or near 100% on high, wildcard-scoped trafficxray-sampling-overcollection
  • Transaction Search indexing above its free 1%, and the span-ingestion charge it routes onto the CloudWatch Logs billxray-transaction-search-indexing
  • Managed Grafana workspaces billing Editor licences where Viewer would dografana-workspace-license-audit

Media and broadcast

7 checks

MediaLive, MediaConvert, MediaTailor, IVS, MediaConnect and Kinesis Video Streams

Show the 7 checks
  • MediaLive channels left RUNNING with no usable input or no delivered outputmedialive-channel-idle
  • Active MediaLive reservations billing more reserved capacity than measured channel usage in their specification bucketmedialive-reservation-idle
  • MediaConvert reserved-slot queues whose measured transcoding is far below the reserved commitmentmediaconvert-reserved-queue-underused
  • MediaTailor Channel Assembly channels running with zero or near-zero manifest requestsmediatailor-channel-idle
  • IVS channels billing continuous video input with essentially no delivered viewer timeivs-input-without-viewers
  • MediaConnect flows billed the full flow-hour rate for 30 days with every configured source never connectedmediaconnect-flow-source-lost
  • Kinesis Video Streams streams ingesting and storing footage nobody has read back in 30 dayskinesisvideo-stream-no-consumer

Developer tools and CI/CD

8 checks

CodeBuild, CodePipeline, CloudFormation, Batch, Q Developer, DevOps Guru and Migration Hub Refactor Spaces

Show the 8 checks
  • CodeBuild reserved-capacity fleets provisioned far above the build minutes routed to themcodebuild-fleet-underutilized
  • CodeBuild projects spending billed minutes re-downloading sources and installing dependencies with caching disabledcodebuild-cache-disabled
  • CodePipeline pipelines on the wrong V1/V2 pricing model for how much they actually runcodepipeline-pricing-model-mismatch
  • Failed and abandoned CloudFormation stacks still holding chargeable resourcescfn-stack-orphans
  • Managed AWS Batch compute environments holding a non-zero minvCpus floor with no jobs runningbatch-compute-env-idle-floor
  • Amazon Q Developer Pro seats billed at $19/user/month with zero recorded IDE activity in the trailing 30 daysqdeveloper-pro-seat-idle
  • Refactor Spaces environments billed hourly with zero measured traffic through any of their routesrefactorspaces-environment-idle
  • DevOps Guru analysing resources (billed per resource-hour) with no insight produced in 90 daysdevops-guru-no-insights

IoT and edge computing

4 checks

IoT Device Management, IoT Device Defender, IoT SiteWise and Ground Station's satellite contacts

Show the 4 checks
  • AWS IoT fleet-indexing index-update spend with no visible query consumeriot-fleet-indexing-unqueried
  • IoT Device Defender ML Detect profiles billing datapoints with models that never activated, unused retained metrics, and double-counted metricsiot-mldetect-model-not-active
  • IoT SiteWise storage left at unlimited hot-tier retention, and disassociated time-series storage left enabledsitewise-hot-tier-unbounded-retention
  • Ground Station reserved-minute allocation going unscheduled across complete calendar monthsgroundstation-reserved-minutes-unused

Communications and application services

5 checks

Connect, SES, WorkMail, Amplify and AppFlow

Show the 5 checks
  • Amazon Connect phone numbers claimed but not routable, or claimed against an instance with no call trafficconnect-phone-number-idle
  • SES dedicated IPs at a flat monthly rate that no configuration set or identity default routes mail throughses-dedicated-ip-unrouted
  • Enabled WorkMail mailboxes that have never accumulated any mailworkmail-empty-mailbox
  • Amplify branches auto-building on every push while serving no custom domain, and stale pull-request preview branchesamplify-branch-build-waste
  • Scheduled AppFlow flows billing a run fee on every poll that returns nothing, or that fail every timeappflow-idle-scheduled-flow

Commitments

3 checks

Reserved instances and capacity reservations examined as resources in their own right

Show the 3 checks
  • On-Demand Capacity Reservations whose reserved slots go unoccupied: an active ODCR bills the full On-Demand rate for every slot whether an instance sits in it or not, so a half-empty reservation is a 100%-on-demand charge for air. Measured over the trailing 30 days from AWS/EC2CapacityReservations UsedInstanceCount against TotalInstanceCount, and priced only from the account's own billed UnusedBox line itemcapacity-reservation-unused
  • Zonal Reserved Instances stranded in an Availability Zone with no matching instanceszonal-ri-mismatch
  • Convertible Reserved Instances stranded on instance families the account no longer runsconvertible-ri-exchange

End-user computing

2 checks

WorkSpaces

Show the 2 checks
  • ALWAYS_ON WorkSpaces with no user connectionsworkspaces-idle
  • ALWAYS_ON WorkSpaces whose measured usage would cost less billed AUTO_STOPworkspaces-runningmode-mismatch

A separate analysis, with its units kept apart.

Reserved instances are bought in hours. Savings Plans are bought in dollars per hour of committed spend. Blending the two coverage figures produces a percentage of nothing, so Kostrix keeps them apart and prints the denominator beside each one.

Savings Plans coverage and utilizationshare of eligible SPEND
How much of your Savings-Plan-eligible compute and database spend over the trailing thirty days is already covered, how much is still paying On-Demand, and how much of what you have committed to is actually being used. Spend, never a blended percentage, because a Savings Plan is bought in dollars per hour.
Reserved instance coverage and utilizationshare of eligible HOURS
The same two questions for reservations across EC2, RDS, ElastiCache, Redshift, OpenSearch and MemoryDB - measured in hours, because that is the unit reservations are bought in, and reported separately from Savings Plans because the remedy is a different purchase.
Expiry cliffsscheduled cost increases
Reservations and Savings Plans whose term ends while the workload they cover is still running. This is a forecastable increase in next month's bill, not a saving, and it is deliberately kept out of the savings total.
Sized purchase recommendationsone per instrument
A Compute Savings Plan for SP-eligible compute and a Reserved Instance recommendation for RDS and Redshift, each sized at 80 percent of the uncovered amount so a quiet week does not leave you holding hours you never use.
Commitment coverageworked example
Reserved instance coverage62.4%

share of eligible HOURS · denominator 18,240 eligible instance-hours

Savings Plans coverage41.9%

share of eligible SPEND · denominator 12,880.00 USD of eligible spend

blended coverage 52.2% never printed

Two different denominators, so two different numbers. Averaging them would produce a figure that measures nothing. The percentages here illustrate the rule; your own are measured over a trailing 30 days.

Savings Plans and reserved-instance coverage, measured separately: the full write-up

Evidenceebs-unattached / ap-south-1
Terms behind the estimated monthly saving for unattached EBS volumes
Unattached volumes2,113volumes
Mean provisioned size16.00GB
Provisioned total33,808GB
gp3 storage rate, ap-south-10.0800USD / GB-month
Estimated monthly saving2,704.64USD / month

2,113 x 16.00 GB = 33,808 GB
33,808 GB x 0.0800 USD/GB-month = 2,704.64 USD/month

Figures from one real scan of WhizzyGeeks' own AWS account; the resource ids are redacted. The rate comes from the AWS Price List API for the region in question. Kostrix never guesses a price: if the rate cannot be fetched, the finding is reported without a figure rather than with an invented one.

Every term on screen, every product exact.

An estimate that cannot be recomputed by hand is a claim, not a measurement. Kostrix prints the count, the size, the rate and its source, so the saving can be verified by anyone in the room without asking us how it works.

Where prices come from

Rates are fetched from the AWS Price List API for the region and product in question. If a rate cannot be fetched, the finding is still reported, without a figure. Kostrix never falls back to a remembered, averaged or approximated price.

The coverage gap is a feature, not an omission.

A scanner only knows what its rules know. Kostrix therefore walks the bill and asks the opposite question: which billed line items did no rule touch? On the reference account that was 18 of 34, and those 18 appear in the product beside the savings, not in a footnote.

Without this, an unexamined service looks exactly like an examined and clean one. That is the single most expensive misreading a cost tool can encourage, and it is the reason this view exists.

Bill reconciliationreference account
Billed line items
34
Covered by a rule
16
Not yet covered
18
Kostrix walks the billed line items, not its own rule list. A service it has never examined cannot pass itself off as a clean one.
Pooled findingsgrouped by required action

Delete unattached EBS volumes

2,113 volumes · ap-south-1 · $2,704.64/month

1 decision

Pooling is by account, region, rule and resource, because a resource id is not globally unique. The individual resources stay attached to the row and export with it.

Grouped by the decision, not by the object.

A list of 2,113 unattached volumes is not a report, it is a chore. Kostrix pools findings by the action they require, so the row you read is the decision you have to make, priced.

Keyed properly
Findings are keyed by account, region, rule and resource. Resource ids are not globally unique, and a tool that assumes they are will silently merge two accounts.
Lineage attached
Unattached volumes name their source snapshot, the AMI that snapshot backs, and whether a launch template still references it.
Empty is not unknown
A rule that ran and found nothing reads as empty. A rule that could not run reads as unknown. The UI and the report distinguish them.
Demo stays demo
Demonstration data is never mixed into a real account view, in either direction.

An absent measurement is not a measurement of zero.

When a metrics call returns nothing, the honest output is nothing. Rendering it as zero would invent an idle fleet and a saving to go with it, and that saving would be the one someone acts on.

Mean CPU utilizationtrailing 30 days
Mean CPU utilization by region, showing an absent measurement
RegionMean CPU
ap-south-14.1%
eu-west-111.7%
eu-north-1no measurement
CloudWatch returned no datapoints for eu-north-1. That region is skipped and logged loudly. Writing 0% there would have invented an idle fleet and a saving to go with it.

Run the 235 checks and get AWS cost optimization recommendations for your own account.