Skip to content

Snowflake Cost Management

This guide covers cost management strategies for Snowflake, including credit optimization, warehouse sizing, cost monitoring, and best practices for reducing Snowflake expenses.

Snowflake uses a credit-based pricing model where you’re charged based on compute resources consumed during query execution. Cost management focuses on optimizing credit usage while maintaining query performance.

  • Compute Credits: Primary cost driver - compute resources consumed
  • Warehouse Size: Larger warehouses consume more credits
  • Query Complexity: Complex queries may consume more credits
  • Data Scanning: Amount of data processed affects credit usage
  • Warehouse Runtime: Time warehouses are running

Select the right warehouse size for your workload to optimize cost and performance.

# Small workload - 1 credit per hour
warehouse: "X-SMALL"
# Medium workload - 2 credits per hour
warehouse: "SMALL"
# Large workload - 4 credits per hour
warehouse: "MEDIUM"
# Very large workload - 8 credits per hour
warehouse: "LARGE"
# Extra large workload - 16 credits per hour
warehouse: "X-LARGE"
# Extra extra large workload - 32 credits per hour
warehouse: "XX-LARGE"

Configure warehouse settings for optimal cost and performance.

# Cost-optimized warehouse configuration
warehouse: "MEDIUM"
auto_suspend: 60 # Suspend after 60 seconds of inactivity
auto_resume: true
max_cluster_count: 10
min_cluster_count: 1
scaling_policy: "STANDARD"

Enable auto-suspend to save credits when warehouses are idle.

# Good: Enable auto-suspend
warehouse: "MEDIUM"
auto_suspend: 60 # Suspend after 60 seconds
auto_resume: true
# Avoid: Keep warehouse running
warehouse: "MEDIUM"
auto_suspend: 0
auto_resume: false

Set appropriate auto-suspend timing based on your workload.

# For frequent queries
warehouse: "MEDIUM"
auto_suspend: 300 # 5 minutes
# For occasional queries
warehouse: "MEDIUM"
auto_suspend: 60 # 1 minute
# For batch processing
warehouse: "MEDIUM"
auto_suspend: 30 # 30 seconds

Implement multi-cluster warehouses for workloads with variable demand.

# Multi-cluster warehouse
warehouse: "MEDIUM"
max_cluster_count: 10
min_cluster_count: 1
scaling_policy: "STANDARD"

Choose the right scaling policy for your workload.

# Standard scaling - immediate scaling
scaling_policy: "STANDARD"
# Economy scaling - delayed scaling
scaling_policy: "ECONOMY"

Track daily credit consumption to identify cost trends.

-- Monitor daily credit usage
SELECT
DATE(start_time) as usage_date,
SUM(credits_used) as total_credits,
COUNT(*) as query_count,
AVG(credits_used) as avg_credits_per_query
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD(day, -7, CURRENT_DATE())
GROUP BY 1
ORDER BY 1 DESC

Monitor credit usage by warehouse to identify optimization opportunities.

-- Track credit usage by warehouse
SELECT
warehouse_name,
DATE(start_time) as usage_date,
SUM(credits_used) as total_credits,
COUNT(*) as query_count,
AVG(execution_time) as avg_execution_time
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD(day, -7, CURRENT_DATE())
GROUP BY 1, 2
ORDER BY 1, 2 DESC

Find queries that consume the most credits.

-- Find expensive queries
SELECT
query_id,
start_time,
credits_used,
execution_time,
query_text
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD(day, -7, CURRENT_DATE())
ORDER BY credits_used DESC
LIMIT 20

Analyze monthly credit usage patterns.

-- Monthly cost analysis
SELECT
YEAR(start_time) as usage_year,
MONTH(start_time) as usage_month,
SUM(credits_used) as monthly_credits,
COUNT(*) as monthly_query_count,
AVG(credits_used) as avg_credits_per_query
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD(month, -12, CURRENT_DATE())
GROUP BY 1, 2
ORDER BY 1 DESC, 2 DESC

Analyze costs by different types of queries.

-- Cost by query type
SELECT
CASE
WHEN query_text ILIKE '%SELECT%' THEN 'SELECT'
WHEN query_text ILIKE '%INSERT%' THEN 'INSERT'
WHEN query_text ILIKE '%UPDATE%' THEN 'UPDATE'
WHEN query_text ILIKE '%DELETE%' THEN 'DELETE'
ELSE 'OTHER'
END as query_type,
SUM(credits_used) as total_credits,
COUNT(*) as query_count,
AVG(credits_used) as avg_credits_per_query
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD(day, -30, CURRENT_DATE())
GROUP BY 1
ORDER BY total_credits DESC

Analyze warehouse efficiency and utilization.

-- Warehouse efficiency analysis
SELECT
warehouse_name,
DATE(start_time) as usage_date,
SUM(credits_used) as total_credits,
COUNT(*) as query_count,
AVG(execution_time) as avg_execution_time,
SUM(credits_used) / COUNT(*) as credits_per_query
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD(day, -7, CURRENT_DATE())
GROUP BY 1, 2
ORDER BY 1, 2 DESC

Improve query performance to reduce credit consumption.

-- Good: Optimized query
SELECT
user_id,
COUNT(*) as order_count
FROM orders
WHERE order_date >= '2024-01-01'
AND order_date < '2024-02-01'
GROUP BY 1
-- Avoid: Inefficient query
SELECT
user_id,
COUNT(*) as order_count
FROM orders
WHERE YEAR(order_date) = 2024
AND MONTH(order_date) = 1
GROUP BY 1

Leverage Snowflake’s query result caching to avoid recomputation.

-- Good: Use cached results
SELECT
user_id,
COUNT(*) as order_count
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY 1

Set appropriate query timeouts to prevent runaway queries.

-- Set query timeout
ALTER SESSION SET STATEMENT_TIMEOUT_IN_SECONDS = 300;

Use appropriate data types and compression to reduce storage costs.

-- Good: Use appropriate data types
CREATE TABLE analytics.user_orders (
user_id VARCHAR,
order_date DATE,
revenue DECIMAL(10,2),
order_type VARCHAR
)

Set up data retention and archival policies.

-- Implement data retention
SELECT * FROM analytics.user_orders
WHERE order_date >= DATEADD(year, -2, CURRENT_DATE())

Implement clustering to improve query performance and reduce costs.

-- Create clustered table
CREATE TABLE analytics.user_orders (
user_id VARCHAR,
order_date DATE,
revenue DECIMAL(10,2),
order_type VARCHAR
)
CLUSTER BY (user_id, order_date)

Use appropriate warehouse sizes for your workload.

# Good: Right-size warehouse
warehouse: "SMALL" # For small workloads
# Avoid: Over-provisioning
warehouse: "X-LARGE" # For small workloads

Schedule warehouses to run only when needed.

# Schedule warehouse
warehouse: "MEDIUM"
schedule: "0 8 * * *" # Start at 8 AM daily
auto_suspend: 60

Implement multi-cluster warehouses for variable workloads.

# Multi-cluster warehouse
warehouse: "MEDIUM"
max_cluster_count: 5
min_cluster_count: 1
scaling_policy: "ECONOMY"

Set up alerts for daily credit thresholds.

-- Check daily credits
SELECT
DATE(start_time) as usage_date,
SUM(credits_used) as daily_credits
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time = CURRENT_DATE()
GROUP BY 1
HAVING SUM(credits_used) > 100.00 -- Alert threshold

Monitor monthly spending patterns.

-- Check monthly credits
SELECT
YEAR(start_time) as usage_year,
MONTH(start_time) as usage_month,
SUM(credits_used) as monthly_credits
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD(month, -1, CURRENT_DATE())
GROUP BY 1, 2
HAVING SUM(credits_used) > 1000.00 -- Alert threshold

Implement credit limits for warehouses.

-- Set warehouse credit limit
ALTER WAREHOUSE my_warehouse SET WAREHOUSE_SIZE = 'MEDIUM';
ALTER WAREHOUSE my_warehouse SET AUTO_SUSPEND = 60;

Track credit consumption against limits.

-- Monitor credit consumption
SELECT
warehouse_name,
DATE(start_time) as usage_date,
SUM(credits_used) as total_credits
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD(day, -7, CURRENT_DATE())
GROUP BY 1, 2
ORDER BY 1, 2 DESC

Choose warehouse sizes based on workload requirements.

# Good: Right-size warehouse
warehouse: "SMALL" # For small workloads
# Avoid: Over-provisioning
warehouse: "X-LARGE" # For small workloads

Enable auto-suspend to save credits.

# Good: Enable auto-suspend
warehouse: "MEDIUM"
auto_suspend: 60
auto_resume: true
# Avoid: Keep warehouse running
warehouse: "MEDIUM"
auto_suspend: 0
auto_resume: false

Implement multi-cluster warehouses for variable workloads.

# Good: Multi-cluster for variable workloads
warehouse: "MEDIUM"
max_cluster_count: 5
min_cluster_count: 1
scaling_policy: "ECONOMY"

Improve query performance to reduce credit consumption.

-- Good: Optimized query
SELECT
user_id,
COUNT(*) as order_count
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY 1
-- Avoid: Inefficient query
SELECT
user_id,
COUNT(*) as order_count
FROM orders
WHERE YEAR(order_date) = 2024
GROUP BY 1

Leverage Snowflake’s query result caching.

-- Good: Use cached results
SELECT
user_id,
COUNT(*) as order_count
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY 1

Set appropriate query timeouts.

-- Set query timeout
ALTER SESSION SET STATEMENT_TIMEOUT_IN_SECONDS = 300;

Conduct regular cost analysis and optimization.

  • Weekly cost analysis
  • Monthly optimization reviews
  • Quarterly cost planning
  • Annual cost budgeting

Set up automated cost monitoring and alerts.

  • Daily credit usage alerts
  • Monthly cost threshold alerts
  • Query performance monitoring
  • Warehouse utilization tracking

Regularly review and optimize costs.

  • Analyze cost trends and patterns
  • Identify optimization opportunities
  • Implement cost-saving measures
  • Monitor cost impact of changes

Problem: Sudden increase in Snowflake costs

Solutions:

  • Check for new queries or increased usage
  • Review warehouse sizing and configuration
  • Implement cost controls and alerts
  • Optimize expensive queries

Debug Steps:

  1. Analyze credit usage by query
  2. Check warehouse configuration
  3. Review query patterns and frequency
  4. Implement cost monitoring

Problem: Warehouses consuming too many credits

Solutions:

  • Right-size warehouses
  • Implement auto-suspend
  • Optimize query patterns
  • Use multi-cluster warehouses

Debug Steps:

  1. Analyze warehouse utilization
  2. Check warehouse sizing
  3. Review auto-suspend settings
  4. Optimize warehouse configuration

Problem: Queries consuming excessive credits

Solutions:

  • Optimize query structure
  • Implement clustering
  • Use appropriate data types
  • Add effective filtering

Debug Steps:

  1. Analyze query execution plans
  2. Check clustering effectiveness
  3. Review data types and storage
  4. Optimize query patterns
  • Weekly cost analysis
  • Monthly optimization reviews
  • Quarterly cost planning
  • Annual cost budgeting
  • Set up cost alerts
  • Implement cost dashboards
  • Monitor cost trends
  • Track optimization impact
  • Regular query performance analysis
  • Implement query optimization
  • Monitor query patterns
  • Optimize expensive queries
  • Right-size warehouses
  • Implement auto-suspend
  • Use multi-cluster warehouses
  • Monitor warehouse utilization