Idle RDS instances, Azure SQL databases without logins and Cloud SQL instances without connections bill instance hours while nobody runs a query: the test environment's database after the release, the replica of a service that was switched off, the schema of a prototype. The saving comes from a stopped, paused or serverless database billing only storage, and from the providers supporting the stop with their own periods and automations. The fix belongs to the team that owns the application that once needed the database.

Symptom

The bill shows database hours without connections. On AWS these are lines with lineItem/UsageType EUC1-InstanceUsage:db.m6g.large or EUC1-Multi-AZUsage:db.m6g.large under AmazonRDS, with 720 or 744 hours per lineItem/ResourceId, while the metric DatabaseConnections sits at zero. On Azure they are MeterCategory SQL Database with vCore meters per database, or Azure Database for PostgreSQL with compute meters per server, with flat connection_successful and cpu_percent metrics. On Google Cloud Cloud SQL carries the SKUs for vCPU and RAM hours per resource.name, with database/network/connections at zero. What a database charges in principle is in managed databases; the levers for running databases in database optimisation.

A database nobody queriesInstance hours, 720 or 744per resource and month:InstanceUsage, vCore orvCPU and RAM metersConnections metric at zero:DatabaseConnections,connection_successful,database/network/connectionsThe bill: databasehours without connections
The instance-hours line counts every hour of the month per database while the connections metric beside it stays at zero

How to detect it

AWS

The instances with class, engine and status:

aws rds describe-db-instances \
  --query 'DBInstances[].[DBInstanceIdentifier,DBInstanceClass,Engine,DBInstanceStatus,MultiAZ,ReadReplicaSourceDBInstanceIdentifier]' --output table

One instance's connections over two weeks, as a daily maximum:

aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name DatabaseConnections \
  --dimensions Name=DBInstanceIdentifier,Value=<instance> --statistics Maximum \
  --start-time 2026-10-07T00:00:00Z --end-time 2026-10-21T00:00:00Z --period 86400

Two checks AWS runs (read on 2026-10-21): Trusted Advisor flags under "Amazon RDS idle DB instances" an active instance without a connection in the last seven days; Compute Optimizer classifies an RDS instance as idle when it is not a replica and had no connections, low CPU and low read and write activity over the lookback period, and recommends a stop for up to seven days, a snapshot and a deletion, or for Aurora the move to db.serverless:

aws compute-optimizer get-idle-recommendations --filters name=ResourceType,values=RDSDBInstance

In billing data the candidate is an InstanceUsage line with full hours and no RDS:StorageIOUsage line of note growing beside it (AWS Cost and Usage Report).

Azure

The databases and servers with their compute configuration:

az sql db list --server <server> --resource-group <rg> \
  --query "[?name!='master'].{name:name, tier:currentSku.tier, sku:currentSku.name, capacity:currentSku.capacity, status:status, autoPause:autoPauseDelay}" -o table
az postgres flexible-server list --query "[].{name:name, rg:resourceGroup, sku:sku.name, tier:sku.tier, state:state}" -o table

One database's connection_successful metric over two weeks:

az monitor metrics list --resource <database-resource-id> --metric connection_successful \
  --aggregation Total --interval P1D --start-time 2026-10-07T00:00:00Z --end-time 2026-10-21T00:00:00Z

Azure Advisor has no recommendation on idle SQL or PostgreSQL instances; for Azure Cosmos DB it flags containers without activity over 30 days and for Data Explorer running clusters without user activity. In the cost export the candidate is a ResourceId under SQL Database or Azure Database for PostgreSQL with a full compute Quantity (Azure cost exports).

Google Cloud

The instances with type, version and availability:

gcloud sql instances list --format="table(name,databaseVersion,settings.tier,settings.availabilityType,state,region)"

The Cloud SQL idle instance recommender rates primary instances older than 30 days over the last 30 days and flags an instance whose activity stays below its threshold, with the maximum CPU utilisation as evidence:

gcloud recommender recommendations list --project=<project-id> --location=<region> \
  --recommender=google.cloudsql.instance.IdleRecommender --format="table(name.basename(),description,stateInfo.state)"

In the billing export the candidate is a resource.name under Cloud SQL with full vCPU and RAM hours (Google Cloud billing export).

How to fix it

  1. Ask the owner and set a deadline; a database needed only at certain times gets a schedule instead of a deletion (scheduling and auto-scaling).
  2. Stop where the provider allows it. AWS: aws rds stop-db-instance --db-instance-identifier <instance> stops an instance for at most seven consecutive days, after which RDS starts it itself so maintenance is not missed; while stopped, storage, provisioned IOPS, backup storage and a public IPv4 address keep billing, instance hours do not; an instance with a read replica and a SQL Server instance in Multi-AZ cannot be stopped (stop an RDS instance). Azure: az postgres flexible-server stop --resource-group <rg> --name <server> stops the compute, and Microsoft starts the server automatically after seven days without a manual start (stop a server). Google Cloud: gcloud sql instances patch <instance> --activation-policy=NEVER stops the instance without a time limit; storage keeps billing.
  3. Let it pause where the database is used irregularly. Azure SQL Database in the serverless tier pauses after the configured delay, at least 15 minutes in the General Purpose tier, 60 by default, and bills only storage while paused (serverless tier): az sql db update --server <server> --resource-group <rg> --name <db> --compute-model Serverless --auto-pause-delay 60. Aurora Serverless v2 pauses with a minimum capacity of 0 ACUs after an idle period of 300 to 86,400 seconds, 300 by default, and bills no instance capacity while paused (automatic pause): aws rds modify-db-cluster --db-cluster-identifier <cluster> --serverless-v2-scaling-configuration MinCapacity=0,MaxCapacity=8,SecondsUntilAutoPause=600.
  4. Delete after the deadline, with a snapshot: aws rds delete-db-instance --db-instance-identifier <instance> --final-db-snapshot-identifier <snapshot>, az sql db delete after an export or a copy, gcloud sql instances delete <instance> after gcloud sql backups create. None of these calls has a dry run; the list from the detection and the release stand in for it.

The stop takes effect on instance hours at once; the daily export shows it the next day.

yesnoyesnoAsk the owner andset a deadlineNeeded only atcertain times?A schedule insteadof a deletionStop where the providerallows it: instance hoursend; AWS and Azure start itagain after seven daysUsed irregularly?Let it pause in aserverless tier: onlystorage while pausedDelete after the deadline,with a snapshot; the listand the release stand infor a dry run
The owner and a deadline come first, the stop is the reversible step with its holding period, and the delete with a snapshot follows the deadline

Risks and side effects

  • No connections does not mean no data: the database may hold data with a retention obligation. The snapshot before the deletion and its own period belong in old snapshots and machine images.
  • Starting a stopped instance takes minutes to hours, with recovery; a database needed daily needs a schedule that starts it before work begins.
  • Pausing has cold starts: the first login after the pause waits, and features such as replication, geo-replication or long-running jobs prevent the pause; on Aurora logical replication prevents pausing.
  • A Reserved Instance or a reservation for the database class runs on whether the instance runs or not; the saving is then the difference another instance brings under the reservation (reserved capacity for managed services).
  • Stopping removes pending maintenance on RDS, and a stopped Azure server is started briefly for maintenance; neither is an error, but both are a reason to check versions and parameters after the start.

How to verify the saving

Before: per instance, the InstanceUsage, vCore or vCPU hours and their amount in the last full month, beside the connection metric. After: the same instance in the first full month after the stop, pause or deletion; the hours have to fall to zero or, under serverless, to the hours with load, and the storage and backup lines remain as the second list. The recommender's amount is the estimate, the team's consent makes it accepted, the stop implemented, and the following month's invoice realises it in the pattern of estimated, accepted, implemented, verified. The number of databases without connections in the last 14 days is the figure that then sits in the cost review.

Sources

Read on 2026-10-21. Stopping an RDS instance temporarily, Aurora Serverless v2 automatic pause, Trusted Advisor cost optimization checks, Compute Optimizer idle resource recommendations, Azure SQL Database serverless tier, Azure Database for PostgreSQL, stop a server, Azure Advisor cost recommendations, Cloud SQL idle instance recommender, Recommenders.