Use SQL to capture Snowflake usage data and calculate compute, storage, and transfer costs directly inside PostgreSQL.
Snowflake bills on three levers: compute credits (warehouses & tasks), storage (compressed bytes stored), and data transfer (egress to the internet or another region). Understanding each lever helps you build cost models that are easy to query and forecast.
Export the views METERING_HISTORY and STORAGE_USAGE_HISTORY from Snowflake to CSV or Snowpipe-into-S3, then COPY the files into a PostgreSQL table named snowflake_usage
. This table will drive every cost query you write.
CREATE TABLE snowflake_usage (
usage_date date,
resource_type text, -- COMPUTE, STORAGE, TRANSFER
credits_used numeric,
bytes bigint,
region text,
comment text
);
Multiply credits_used
by your contracted credit rate. Storing that rate in a config table lets you change pricing without rewriting queries.
SELECT usage_date,
SUM(credits_used * cr.credit_rate_usd) AS compute_cost_usd
FROM snowflake_usage su
JOIN cost_rates cr ON cr.resource_type = 'COMPUTE'
WHERE resource_type = 'COMPUTE'
GROUP BY usage_date
ORDER BY usage_date;
Snowflake charges per average compressed byte-hours. Convert bytes to GB-months, then multiply by the storage rate.
SELECT date_trunc('month', usage_date) AS month,
ROUND(SUM(bytes) / 1024^3 / 24 / 30, 2) AS avg_gb,
ROUND(SUM(bytes) / 1024^3 / 24 / 30 * cr.credit_rate_usd, 2) AS storage_cost
FROM snowflake_usage su
JOIN cost_rates cr ON cr.resource_type = 'STORAGE'
WHERE resource_type = 'STORAGE'
GROUP BY month;
Tag Snowflake warehouses with the same customer_id
as your Customers
table. After ingest, join the tag to customer metadata.
SELECT c.name,
SUM(su.credits_used * cr.credit_rate_usd) AS total_cost
FROM snowflake_usage su
JOIN customers c ON c.id = su.comment::int -- tag holds customer_id
JOIN cost_rates cr ON cr.resource_type = su.resource_type
GROUP BY c.name
ORDER BY total_cost DESC;
Use auto-resume/auto-suspend on warehouses, schedule warehouse sizes by workload, and archive infrequently used tables to cheaper storage tiers. Monitor daily costs with the queries above and automate Slack alerts when spend spikes.
A credit is a billing unit representing one hour of compute on a Medium warehouse. Larger warehouses consume credits faster; smaller warehouses consume them more slowly.
Daily exports keep cost dashboards current without overwhelming PostgreSQL. Schedule exports at off-peak hours to minimize load.
Yes. Use a 30-day moving average of daily costs and project it forward, factoring in any planned warehouse size changes.