How to Cut Redshift Costs by Pausing Idle Clusters

A Redshift cluster nobody queries bills the same as one running dashboards. Pausing a business-hours-only warehouse cuts roughly 70% of its compute charge.

Published July 26, 2026 · Last updated August 12, 2026

Redshift tends to be the line item people notice last and dread most. It is rarely the biggest number on the bill, but it is always a four-figure one, and nobody wants to be the person who deleted the data warehouse. So the analytics-dev cluster someone spun up for a dashboard prototype in March is still available in July — running twenty-four hours a day, seven days a week, for a team that opens a query editor against it on maybe four afternoons a month. Redshift has a genuinely good answer to this that most people never touch: you can pause a cluster, keep every byte of data and every bit of configuration, and stop paying for compute while it sits. This post covers how to prove a warehouse is idle, and how to pause it — on a schedule, so it stays that way.

Why does a warehouse nobody queries cost this much?

Redshift provisioned clusters bill node-hours. You pay the hourly rate for your node type, multiplied by the number of nodes, for every hour the cluster is in the available state. Query volume does not enter into it. A cluster serving nothing bills exactly what a cluster serving your entire BI stack bills.

The rates are what make this hurt. In us-east-1, on-demand:

Node typePer node/hour2-node cluster/month
dc2.large$0.25~$365
ra3.xlplus$1.086~$1,586
ra3.4xlarge$3.26~$4,760

So the smallest sensible cluster you can stand up — two dc2.large nodes — is about $365 a month, or $4,380 a year, to keep a dev warehouse warm. Two ra3.xlplus nodes cross $19,000 a year. These are not rounding errors, and they accrue silently because the cluster looks healthy the whole time.

The pattern is the same one that gets people with idle load balancers and caches: the meter runs on provisioned time, not usage. What makes Redshift different — and better — is that unlike ElastiCache, it has a stop button.

What does pausing actually save?

When you pause a cluster, on-demand compute billing stops. The cluster keeps its data, its users, its schemas, its workload management config, its parameter group — everything. Resuming puts it back exactly as it was, typically in a few minutes.

The saving is a straight function of how many hours you leave it paused. A dev or analytics cluster that only needs to be up on weekdays from 9am to 7pm is available 50 hours out of the 168 in a week. Pause it the rest of the time and you are paying for roughly 30% of the hours you pay for today — about a 70% cut to that cluster's compute line. On those two dc2.large nodes, $365 a month becomes about $109. On the ra3.xlplus pair, $1,586 becomes roughly $472.

How do I confirm nobody is using it?

Start by listing what exists, with node type and count — this is where forgotten clusters surface:

aws redshift describe-clusters \
  --query 'Clusters[].[ClusterIdentifier,NodeType,NumberOfNodes,ClusterStatus,ClusterCreateTime]' \
  --output table \
  --region us-east-1

Then the decisive metric: DatabaseConnections. A warehouse in use has clients connected to it — BI tools, ETL jobs, scheduled queries, someone's SQL client. A flat line at zero means nothing is talking to it.

aws cloudwatch get-metric-statistics \
  --namespace AWS/Redshift \
  --metric-name DatabaseConnections \
  --dimensions Name=ClusterIdentifier,Value=analytics-dev \
  --start-time "$(date -u -d '14 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --period 86400 \
  --statistics Average Maximum \
  --region us-east-1 \
  --output table

Read both statistics. An Average near zero with a Maximum of 6 on two of the fourteen days does not mean idle — it means a nightly ETL or a Monday-morning report connects, and deleting the cluster would break it. It is, however, a perfect candidate for a schedule. Average and maximum both flat at zero across the full two weeks is the case for pausing indefinitely.

Corroborate with CPUUtilization on the same namespace and dimension. Fourteen days is the right window because it survives weekly and fortnightly jobs; a cluster can look dead on a Tuesday and be genuinely load-bearing on Sunday night. Parsivex uses the same shape of test — average connections under 0.5 and average CPU under 5% over 14 days, on a cluster at least 14 days old, so nothing brand new gets flagged before it is wired up.

One more check before you touch anything: query history tells you who, which CloudWatch cannot.

-- Run against the cluster: distinct users and query counts over the last 14 days
SELECT usename, COUNT(*) AS queries, MAX(starttime) AS last_query
FROM stl_query
JOIN pg_user ON usesysid = userid
WHERE starttime > DATEADD(day, -14, GETDATE())
GROUP BY usename
ORDER BY queries DESC;

Also check for datashares consumed by other clusters, and any Quicksight or Tableau data source pointed at this endpoint. A datashare producer that gets paused takes its consumers' queries down with it.

How do I pause it — and keep it paused?

For a cluster you are confident is idle, pausing by hand is one command:

aws redshift pause-cluster --cluster-identifier analytics-dev --region us-east-1

# When someone needs it back
aws redshift resume-cluster --cluster-identifier analytics-dev --region us-east-1

In the console it is Redshift → Clusters → select → Actions → Pause. Either way, take a manual snapshot first if the cluster holds anything you cannot rebuild — pausing preserves data, but a snapshot costs little and removes the "what if" from the conversation entirely.

Pausing by hand once solves this month. For the far more common case — a cluster that is genuinely needed, just not at 3am on a Sunday — use scheduled actions, which are built into Redshift and cost nothing:

# Pause weekdays at 19:00 UTC
aws redshift create-scheduled-action \
  --scheduled-action-name analytics-dev-pause \
  --target-action '{"PauseCluster":{"ClusterIdentifier":"analytics-dev"}}' \
  --schedule "cron(0 19 ? * MON-FRI *)" \
  --iam-role arn:aws:iam::123456789012:role/RedshiftScheduler \
  --region us-east-1

# Resume weekdays at 08:00 UTC
aws redshift create-scheduled-action \
  --scheduled-action-name analytics-dev-resume \
  --target-action '{"ResumeCluster":{"ClusterIdentifier":"analytics-dev"}}' \
  --schedule "cron(0 8 ? * MON-FRI *)" \
  --iam-role arn:aws:iam::123456789012:role/RedshiftScheduler \
  --region us-east-1

The IAM role needs redshift:PauseCluster and redshift:ResumeCluster and a trust policy for scheduler.redshift.amazonaws.com. Set the resume slightly earlier than people actually arrive — a resume takes a few minutes, and a warehouse that is still starting at 9:01 gets the schedule switched off by an irritated analyst within a week.

If a cluster is idle because the workload it served is gone entirely, deleting it with a final snapshot is the honest answer — but pause first and wait a sprint. A paused cluster costs almost nothing while you find out whether anyone shouts. And if the workload is real but genuinely bursty, Redshift Serverless is worth pricing out: it scales to zero between queries, which is the same saving without the scheduling.

What else should I check while I am in the data tier?

Idle warehouses rarely idle alone. The same "provisioned for a workload that moved on" pattern runs through everything around them: the RDS instance the ETL read from, the cache in front of the API that fed the dashboard, the EC2 box that ran the scheduler. If the analytics stack quietly stopped being used, all of it is still billing.

Start with the cache layer, which has the same shape of problem and none of Redshift's stop button — see are you paying for an idle ElastiCache (Redis) cluster? for how to tell an abandoned Redis cluster from a quiet but load-bearing one. Then do the database pass; Idle RDS instance covers the equivalent connection-based test for Postgres and MySQL, including the gotcha that a stopped RDS instance restarts itself after seven days — which is precisely the trap Redshift's pause does not have.

The transactional databases that feed the warehouse deserve the harder question rather than the binary one. A warehouse is either queried or it is not; an RDS instance is usually used, just three sizes larger than the workload needs, and shrinking it is the fix rather than pausing it. Right-sizing an over-provisioned RDS instance without downtime walks through the metrics that justify the change and how Multi-AZ makes it survivable.

How do I find idle warehouses across my whole account?

Checking one cluster is a twenty-minute job. Doing it for every Redshift cluster in every region, pulling fourteen days of connection and CPU history for each, telling a genuinely dormant warehouse from one that wakes up for a Sunday-night ETL, and then re-checking next quarter after someone stands up a new dev cluster for a migration and forgets it — that is the tedious part, and it is where these charges survive for years. A dormant warehouse is often the single largest item on a small team's bill, but it is rarely the only one — our guide to cutting an AWS bill covers the compute, storage, and networking passes that usually follow it. That is what a scan is for. Parsivex checks each region, flags clusters with no connections and negligible CPU against real 14-day metrics, estimates what pausing would save, and then keeps watching, so the next forgotten warehouse does not bill quietly for a year.

For what this finding means once it appears in your report, see Idle Redshift cluster, or read how scans work before you connect an account.