This is the list we work through on the first day of a Redshift cost review. None of it is exotic; most of the savings on a typical environment come from five or six of these items that nobody has looked at since the cluster was built. Work top to bottom.
Compute
1. Set a max RPU on every Serverless workgroup. The default maximum is high. Cap it at the level that meets your latency target during peak, and raise it only with evidence. Check SYS_SERVERLESS_USAGE for how often you actually reach the cap.
2. Set base RPU from measurement, not the default. Base capacity is the floor for every query burst. Too high and every small query pays for capacity it does not use. Start low (8 or 16 RPUs for BI workloads), watch SYS_QUERY_HISTORY latency, and step up.
3. Put usage limits on every workgroup, with alerts. A monthly RPU-hour limit with emit-metric and a CloudWatch alarm is the single cheapest insurance against a runaway bill. Use deactivate for dev and test.
4. Cap Concurrency Scaling on provisioned clusters. The max_concurrency_scaling_clusters parameter defaults to 1 but teams raise it during an incident and forget. Each scaling cluster bills at the on-demand rate beyond the free daily credit. Also set a usage limit for Concurrency Scaling hours.
5. Pause provisioned clusters that are idle. Dev, test and POC clusters that run 24/7 for an 8-hour working day cost three times what they should. Schedule pause/resume, or move them to Serverless where idle is free.
6. Review Auto WLM query priorities. Give ETL and dashboard refreshes distinct priorities, and set query monitoring rules that abort queries scanning more than a threshold of rows or running beyond a threshold of minutes. A single runaway analyst query can consume a day's budget on Serverless.
7. Find the queries that cost the most.
SELECT user_id, query_text,
SUM(elapsed_time) / 1000000.0 / 3600 AS hours,
COUNT(*) AS runs
FROM SYS_QUERY_HISTORY
WHERE start_time > DATEADD(day, -30, GETDATE())
AND status = 'success'
GROUP BY 1, 2
ORDER BY hours DESC
LIMIT 25;
The top ten are usually dashboard queries that run every five minutes against an unsorted fact table. Fix the sort key or put a materialized view in front of them.
Queries and tables
8. Check materialized view refresh cost. Auto-refreshing MVs over large tables can consume more compute than the queries they serve. SYS_MV_REFRESH_HISTORY shows the refresh duration per view; for views that refresh every minute but are read once an hour, switch to scheduled refresh.
9. Enable and verify result caching. It is on by default, but enable_result_cache_for_session is sometimes disabled in connection strings by BI tools. Cached results cost zero compute. Check SYS_QUERY_HISTORY.result_cache_hit.
10. Audit stale tables. Tables nobody has queried in 90 days still cost RMS storage and slow down backups and restores.
SELECT t."table", t.size AS mb, t.tbl_rows,
MAX(q.start_time) AS last_queried
FROM SVV_TABLE_INFO t
LEFT JOIN SYS_QUERY_DETAIL q ON q.table_id = t.table_id
GROUP BY 1, 2, 3
HAVING MAX(q.start_time) < DATEADD(day, -90, GETDATE()) OR MAX(q.start_time) IS NULL
ORDER BY mb DESC;
Archive them to S3 as Parquet and query through Spectrum if anyone asks.
11. Apply Automatic Table Optimization recommendations. SVV_ALTER_TABLE_RECOMMENDATIONS lists sort and distribution changes that would reduce scan cost. Those with auto_eligible = f wait for you. See our sort and distribution key guide.
12. Rebuild tables with legacy encodings. Columns created years ago with ENCODE lzo or raw are larger and slower than AZ64/ZSTD. Check SVV_TABLE_INFO.encoded and PG_TABLE_DEF.encoding, and rebuild the biggest offenders.
Storage and data movement
13. Watch Redshift Managed Storage growth. RMS is billed per GB-month and grows silently: replicated zero-ETL tables, retained snapshots, and streaming materialized views that never age out. Chart the RedshiftManagedStorageTotalCapacity CloudWatch metric monthly and set retention on manual snapshots.
14. Share, do not copy. Every nightly UNLOAD-to-S3-then-COPY into another cluster is storage paid twice plus compute on both sides. Replace it with a datashare. The same applies to dev environments that copy prod: a datashare into a Serverless dev workgroup costs only the dev queries.
15. Right-size ingestion. Zero-ETL integrations replicating audit and log tables, streaming views polling an idle stream, and Concurrency Scaling triggered by a badly scheduled load all show up as compute nobody asked for. Review the integration filter list, the streaming view inventory, and the load schedule together.
How much is this worth?
It depends entirely on what has been neglected, and we do not quote a percentage without looking. What we can say is that items 1, 3, 4, 5 and 10 are each routinely worth more than the cost of checking them.
For a structured review with a written report and the changes implemented, see Redshift Performance Optimization. For the provisioned-vs-Serverless question underneath several of these items, read RA3 vs Serverless in 2026.