Usage metrics
What each asset does, read once a day from your clouds' own metrics: idle assets, when each was last active, usage anomalies and what runs out.
Your clouds already measure what each resource does: CPU, requests, connections, bytes and the like. AssetHermit reads those metrics once a day for the assets each asset source holds, and uses them to find idle and oversized assets (priced as savings), say when each asset was last active, find usage anomalies, and forecast storage, backlogs and quotas running out. It's included in the Starter, Team and Enterprise plans.
Usage runs
Each asset source has a usage run of its own, apart from its syncs: once a day after 02:00 UTC, or once a week if an admin chooses. It reads complete UTC days, and the last 2 again, since points arrive late. Sync now never starts one, so you're never billed twice for the same day.
- The first usage run starts soon after an asset source's first sync, and reads 42 days back. It also reads each asset's older history, as far as the provider keeps it, to find when it was last active.
- Hourly points are kept for 35 days, then each day's figures, within the workspace's history.
- A usage run that fails, or whose reads the cloud partly denies, never changes the asset source's status or its syncs. It's tried again later.
- The figures reach search with the asset source's next sync, so they can lag a usage run by up to a sync.
Which metrics
- AWS: CloudWatch, read as the asset source's discovery role, whose read-only access already allows it. Service quotas are read the same way.
- Azure: Azure Monitor, read as the asset source's managed identity with the Reader role it already has.
- Google Cloud: Cloud Monitoring, read as the workspace's asset principal set and billed to the asset source's quota project. It needs the Monitoring Viewer role and the Monitoring API on the quota project: an optional step on the connect page, which you can grant later.
Each metric has the same name on every cloud: CPU is CloudWatch's CPUUtilization, Azure'sPercentage CPU and Compute Engine's CPU utilization alike. These are the resources read and their metrics; the activity metrics decide whether an asset is idle.
| Resource | Cloud | Metrics | Activity |
|---|---|---|---|
| Instance EC2 · aws/ec2/instance | AWS | CPU (cpu), Network in (networkIn), Network out (networkOut) | CPU, Network in, Network out |
| Volume EC2 · aws/ec2/volume | AWS | Read operations (readOps), Write operations (writeOps) | Read operations, Write operations |
| NAT gateway EC2 · aws/ec2/nat-gateway | AWS | Bytes processed (bytes), Connections (connections) | Bytes processed |
| Load balancer ElasticLoadBalancingV2 · aws/elasticloadbalancingv2/load-balancer | AWS | Requests (requests), Errors (errors), New connections (newConnections), Bytes processed (bytes) | Requests, New connections |
| Load balancer ElasticLoadBalancing · aws/elasticloadbalancing/load-balancer | AWS | Requests (requests) | Requests |
| DB instance RDS · aws/rds/db-instance | AWS | CPU (cpu), Connections (connections), Free storage (storageFree) | Connections |
| Cache cluster ElastiCache · aws/elasticache/cache-cluster | AWS | CPU (cpu), Connections (connections) | Connections |
| Domain OpenSearchService · aws/opensearchservice/domain | AWS | Requests (requests), Write operations (writeOps), Free storage (storageFree) | Requests, Write operations |
| Table DynamoDB · aws/dynamodb/table | AWS | Read capacity used (readUnits), Write capacity used (writeUnits) | Read capacity used, Write capacity used |
| Function Lambda · aws/lambda/function | AWS | Invocations (invocations), Errors (errors), Throttled requests (throttles) | Invocations |
| Service ECS · aws/ecs/service | AWS | CPU (cpu), Memory (memory) | None |
| Stream Kinesis · aws/kinesis/stream | AWS | Write operations (writeOps), Read operations (readOps), Throttled requests (throttles) | Write operations, Read operations |
| Queue SQS · aws/sqs/queue | AWS | Write operations (writeOps), Read operations (readOps), Backlog (backlog) | Write operations, Read operations |
| Bucket S3 · aws/s3/bucket | AWS | Storage used (storageUsed), Objects (objects) | None |
| Log group Logs · aws/logs/log-group | AWS | Ingested (ingested) | Ingested |
| Virtual machine Compute · azure/compute/virtual-machines | Azure | CPU (cpu), Network in (networkIn), Network out (networkOut) | CPU, Network in, Network out |
| Site App Service · azure/web/sites | Azure | Requests (requests), Errors (errors) | Requests |
| Flexible server Database for PostgreSQL · azure/dbforpostgresql/flexible-servers | Azure | CPU (cpu), Memory (memory), Connections (connections), Storage used (storagePercent) | Connections |
| Flexible server Database for MySQL · azure/dbformysql/flexible-servers | Azure | CPU (cpu), Memory (memory), Connections (connections), Storage used (storagePercent) | Connections |
| Application gateway Network · azure/network/application-gateways | Azure | Requests (requests) | Requests |
| NAT gateway Network · azure/network/nat-gateways | Azure | Bytes processed (bytes) | Bytes processed |
| Database account Cosmos DB · azure/documentdb/database-accounts | Azure | Requests (requests) | Requests |
| Redis Cache for Redis · azure/cache/redis | Azure | Connections (connections) | Connections |
| Instance Compute Engine · gcp/compute/instance | Google Cloud | CPU (cpu), Network in (networkIn), Network out (networkOut) | CPU, Network in, Network out |
| Instance Cloud SQL · gcp/sqladmin/instance | Google Cloud | CPU (cpu), Memory (memory), Connections (connections), Storage used (storagePercent) | Connections |
| Service Cloud Run · gcp/run/service | Google Cloud | Requests (requests) | Requests |
| Function Cloud Run functions (1st and 2nd gen) · gcp/cloudfunctions/function | Google Cloud | Invocations (invocations) | Invocations |
| Subscription Pub/Sub · gcp/pubsub/subscription | Google Cloud | Backlog (backlog) | None |
| Bucket Cloud Storage · gcp/storage/bucket | Google Cloud | Storage used (storageUsed) | None |
| Log bucket Cloud Logging · gcp/logging/log-bucket | Google Cloud | Ingested (ingested) | Ingested |
Idle and last active
An asset is idle when it existed and ran for the whole last 14 days, each of its activity metrics had points on at least 12 of them, and none rose above its floor on any day. The floors are strict on purpose: CPU at most 5% at the 95th percentile, network in and out at most 5 MB a day each, a NAT gateway at most 1 GB over the window, and nothing at all for requests, connections, invocations and the rest. A stopped asset is never idle, and one without enough points isn't called either way. Each idle asset says why in words.
Last active is the last day any activity metric was above its floor, as far back as the provider keeps metrics: 455 days on AWS, 93 on Azure and 42 on Google Cloud.
Idle and oversized assets as savings
Findings rules over usage find what you could stop, delete or make smaller, each with a guide, and the Savings tab prices them from the asset's own cost:
- Idle: EC2 instances, attached EBS volumes never read or written, NAT gateways, Application, Network and Classic Load Balancers, RDS instances, ElastiCache clusters, OpenSearch domains, Kinesis streams and log groups that take in nothing; Azure virtual machines, PostgreSQL and MySQL flexible servers and Cosmos DB accounts; Compute Engine and Cloud SQL instances. Each saves the asset's cost.
- Oversized: ECS services using under 30% of their CPU and memory, and Azure PostgreSQL and MySQL flexible servers and Cloud SQL instances using under 30% of their CPU and 50% of their memory, at the 95th percentile over 14 days. Each saves up to half the asset's cost. Virtual machines aren't rightsized yet, since their memory needs an agent of yours.
- Unused: Lambda functions with no invocation in 90 days are a finding, not priced.
The rules find nothing before an asset source's first usage run. See Savings.
Usage anomalies
Each usage run judges each asset's headline metrics (the work it does, such as requests or connections, or CPU and network out where it has none), and the sum for each account and resource type, against the series' own usual level and weekly pattern, as cost anomalies are judged.
- A series is judged once it has 14 days of history, and only above a floor for its metric, so a test function going from 3 calls to 9 is never news.
- A rise is at least 50% over the usual level and a fall at least 70% under it, by default; a workspace admin changes these on the workspace settings' Usage anomalies card. A metric that drops to nothing hasstopped, and an idle one that starts has woken, unless it often goes quiet and comes back. Errors and throttles are only judged for rises.
- A series that's quiet most days and busy on some, such as a development resource, is judged against its usual busy day, so each busy day isn't a rise.
- An account and type anomaly names up to 5 assets it came from. An anomaly is judged again for 14 days, and ends as recovered or as a new level.
- Severity follows how far it moved, then the asset's cost: an asset costing under $10 a month makes it low, which is never notified, though a stop stays news whatever it costs.
Anomalies are reviewed as cost anomalies are, with expected or not expected and a note. A cost anomaly also gets a Usage card: whether its resources' usage moved with the cost (usage-driven), stayed about the same while the cost moved (a price, a commitment or a new kind of charge), or neither can be told.
Forecasts and quotas
Each usage run follows capacity metrics (free storage, storage used as a percentage, queue and subscription backlogs) over their last 14 days, and forecasts a steady trend that runs out within 30 days, with the day it does, or a backlog that keeps growing.
On AWS, it also reads the service quotas that stop a launch, in each account and region where you have assets: vCPUs for On-Demand Standard, G and VT, and P and X instances, Spot Instance requests, Elastic IPs, VPCs per region and Lambda's concurrent executions. A quota at 80% or more of its value, or on a trend to reach it within 30 days, is listed with its highest daily use over the last 28 days and a link to ask AWS for an increase. Azure's and Google Cloud's quotas aren't read yet.
Where you see it
- The Usage page has three tabs: Idle (idle assets, costliest first, with why and their cost over the last 30 days, filtered by type), Anomalies (open or all, most severe first, each with its value a day against the usual, and each anomaly's page with its chart against the expected level) and Forecasts (service quotas, then what runs out and when).
- Asset detail has an Idle badge, and a Usage tab with each metric's chart over 7 days, 14 days or 6 weeks, its statistics over the last 14 days, the asset's changes marked, idle and why, last active, its forecasts and open anomalies, and its cost per unit of work (per million requests, per million invocations, per million writes, per million read units, per GB and per GB a month) where it has both cost and usage.
- The inventory has Idle, Last active and CPU (p95) columns, hidden until you pick them.
- An asset source's Usage tab has Read usage, to turn it off, and how often, daily or weekly, for admins; the last run, the day read through, how many assets had metrics, any reads the cloud denied with what grants them, and what a month of reads costs.
In search
Three common properties carry usage, over the last 14 days:
$usage.<metric>.<statistic>, compared as a number and sortable: a level such as CPU has avg, max and p95, an amount such as requests has sum and max.$idle,trueorfalse; an asset that can't be told has none.$lastActive, a date.
So $idle:true lists every idle asset, $type:compute.vm $usage.cpu.p95:<5 the virtual machines that barely use their CPU, $type:compute.vm order by $usage.cpu.p95 desc the busiest first, and $nativeType:aws/lambda/function -$lastActive:>now-90d the Lambda functions not active in 90 days. See Search.
Notifications
Usage has a category of its own in your notification settings: by default it reaches your inbox, and admins' daily digest too. Like every category, it can come in your inbox, by email and in Slack:
- Usage anomaly: a new anomaly above low that nobody has reviewed. The workspace settings' Usage anomalies card can narrow it to some asset groups; every anomaly is still listed.
- Running out: a forecast within 14 days, or a growing backlog.
- Near a quota: an AWS quota at 80% or more, or reaching it within 14 days.
- Usage can't be read: 5 failed usage runs in a row, or reads the cloud denied.
Each is an alert that resolves itself. See Notifications.
The assistant
The assistant reads usage as you: an asset's figures, why it's idle, when it was last active, its forecasts, anomalies and unit cost, or the workspace's idle assets, usage anomalies, forecasts and service quotas. AI clients connected through the MCP server can read them the same way.
What the reads cost
Metric reads aren't free: your cloud bills them, not AssetHermit, at its list price. On AWS a request is billed per metric whatever the days it covers, so the first run's 42 days cost the same as a day's.
| Cloud | Price | Free each month |
|---|---|---|
| AWS | $0.01 per 1,000 metrics requested | None |
| Azure | $0.01 per 1,000 metric calls | 1,000,000 a month |
| Google Cloud | $0.50 per million time series returned | 1,000,000 a month |
Azure's calls are counted one per resource. Free units are your billing account's, shared with everything else, so the estimate is the most it costs. Each asset source's Usage tab shows what a month of its reads costs at its interval. See Cloud read costs for every read AssetHermit makes that your cloud bills.