Schedule icon
Query icon
If icon
SlackIncomingWebhook icon
Log icon
Return icon

Snowflake Table Storage and Time Travel FinOps Audit

Automated FinOps workflow to query Snowflake table storage metrics, detect runaway Time Travel and Fail-safe costs, and alert Slack.

Categories
BusinessData

In Snowflake cloud data warehouses, physical storage costs encompass three distinct layers: active data bytes, Time Travel retention bytes, and 7-day Fail-safe protection bytes. For high-churn ETL staging tables, scratch tables, or daily full-refresh data pipelines, default 90-day retention policies cause historical versions and fail-safe copies to swell to 5x to 10x the size of the underlying active table.

Organizations often incur thousands of dollars in monthly cloud storage fees for unneeded historical snapshots of temporary tables that are completely overwritten each morning.

This blueprint establishes an automated FinOps guardrail for Snowflake storage. Running weekly or on-demand, it queries SNOWFLAKE.ACCOUNT_USAGE.TABLE_STORAGE_METRICS, calculates the protective storage overhead ratio ((time_travel + failsafe) / active_data), and flags tables larger than your threshold that exceed configured limits. When runaway bloat is detected, it alerts your data platform team on Slack with dollar waste estimates and exact SQL remediation commands.

How it works

  1. Scheduled FinOps Audit: The weekly_finops_audit trigger (io.kestra.plugin.core.trigger.Schedule) executes every Sunday at 06:00 UTC, or runs on-demand via the Kestra UI.
  2. Storage Metrics Query: The audit_storage_overhead task (io.kestra.plugin.jdbc.snowflake.Query) queries snowflake.account_usage.table_storage_metrics, joining active, time travel, and fail-safe bytes to compute protection overhead ratios and dollar impacts.
  3. Anomaly Gate: The evaluate_storage_anomalies flowable task (io.kestra.plugin.core.flow.If) branches based on whether any tables breach max_overhead_ratio.
  4. Slack Alert Dispatch: If wasteful tables are discovered, notify_finops_slack (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) delivers an actionable Slack card detailing table names, active vs. protective gigabytes, and ALTER TABLE commands.
  5. Optimized Logging: When all tables exhibit healthy storage ratios, log_compliant_storage records compliant status in the execution log.
  6. Audit Manifest: The export_finops_manifest task records telemetry data for lineage logs and FinOps cost dashboards.

What you get

  • Automated discovery of Snowflake tables with runaway Time Travel and Fail-safe storage fees.
  • Identification of transient ETL tables misconfigured as permanent tables.
  • Estimated monthly dollar waste calculations directly in Slack notifications.
  • Immediate remediation SQL statements to reclaim storage capacity.

Who it is for

  • FinOps Practitioners and Cloud Economists governing Snowflake warehouse and storage spend.
  • Data Platform Engineers auditing multi-terabyte data warehouse assets.
  • Analytics Engineering leads configuring dbt model materializations and retention policies.

Why orchestrate this with Kestra

Snowflake provides storage views in Account Usage, but built-in alerts only notify on hard credit quotas rather than storage overhead ratios. Kestra provides declarative, scheduled orchestration: it handles secure Snowflake JDBC connectivity, computes statistical overhead ratios, evaluates threshold breaches, and dispatches rich formatted notifications to your team.

Inputs

Name Type Default Description
min_table_size_gb INT 50 Only flag tables whose total physical footprint exceeds this size in gigabytes.
max_overhead_ratio FLOAT 2.0 Flag tables where Time Travel and Fail-safe storage exceed active data by this multiple.
storage_cost_per_tb_usd FLOAT 23.00 Estimated monthly cost per terabyte of Snowflake storage.
slack_channel STRING #finops-alerts Slack channel destination for FinOps storage cost alerts.

Expected outputs

  • {{ outputs.audit_storage_overhead.rows }}: Array of table storage records containing database_name, schema_name, table_name, active_gb, time_travel_gb, failsafe_gb, protection_overhead_ratio, and estimated_monthly_waste_usd.
  • {{ outputs.audit_storage_overhead.size }}: Total count of tables exceeding the protective storage ratio.
  • {{ outputs.evaluate_storage_anomalies }}: Result of conditional branch evaluation.
  • {{ outputs.export_finops_manifest.value }}: Structured JSON audit manifest recording execution timestamp and compliance status.

Prerequisites

  • A Snowflake account with access to SNOWFLAKE.ACCOUNT_USAGE schema views.
  • A Snowflake service account with a role granted IMPORTED PRIVILEGES on the SNOWFLAKE database.
  • A Slack Incoming Webhook URL targeting your FinOps notification channel.

Secrets

  • SNOWFLAKE_JDBC_URL: Snowflake JDBC connection string (e.g. jdbc:snowflake://<account_locator>.snowflakecomputing.com?warehouse=COMPUTE_WH&db=SNOWFLAKE&schema=ACCOUNT_USAGE).
  • SNOWFLAKE_USER: Username of the service account authorized to query account usage.
  • SNOWFLAKE_PASSWORD: Password for the Snowflake service account.
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL used for sending alert notifications.

Quick start

  1. Configure SNOWFLAKE_JDBC_URL, SNOWFLAKE_USER, SNOWFLAKE_PASSWORD, and SLACK_WEBHOOK_URL in your Kestra namespace secrets.
  2. Import this flow YAML into your Kestra instance.
  3. Click Execute in the UI to run an initial audit of your Snowflake storage metrics.
  4. Review execution outputs to inspect table storage breakdowns and overhead ratios.

Common pitfalls and troubleshooting

  • Account Usage View Latency: Views in SNOWFLAKE.ACCOUNT_USAGE such as TABLE_STORAGE_METRICS experience 45 to 120 minutes of data latency. Schedule the flow weekly or off-peak for reconciled metrics.
  • Dropped Tables: By default, TABLE_STORAGE_METRICS retains dropped tables during Time Travel and Fail-safe retention. The query filters WHERE deleted = FALSE to target currently active table assets.
  • Transient Tables: Transient tables do not incur Fail-safe storage fees and support a maximum of 1 day of Time Travel. Converting high-churn staging tables to TRANSIENT immediately prevents future bloat.

How to extend

  • Add an automated remediation task executing ALTER TABLE ... SET DATA_RETENTION_TIME_IN_DAYS = 1; for approved non-production schemas.
  • Email weekly executive summaries to engineering managers using io.kestra.plugin.notifications.mail.MailSend.
  • Integrate with Jira or GitHub Issues to create automated optimization tickets for data engineers.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.