New to Kestra?
Use blueprints to kickstart your first workflows.
Audits Google BigQuery TABLE_STORAGE to detect large dormant tables exceeding retention thresholds, alerting FinOps teams on Slack.
In Google Cloud BigQuery, enterprise analytics teams frequently generate temporary staging tables, sandbox copies, and materialized ETL snapshots. Over time, these datasets are abandoned by developers as project requirements evolve, but continue to reside in active logical storage.
Because BigQuery bills continuously for both active ($0.02/GB/month) and long-term ($0.01/GB/month) storage, unmanaged multi-terabyte datasets generate thousands of dollars of recurring monthly billing waste. Furthermore, redundant tables clutter data catalogs and confuse downstream analysts.
This blueprint provides an automated Cloud FinOps auditor that inspects INFORMATION_SCHEMA.TABLE_STORAGE across BigQuery datasets on a weekly schedule. It identifies tables exceeding 10 GB in size that have remained dormant past your retention threshold (default: 90 days), calculates monthly dollar costs, and dispatches structured optimization recommendations to Slack.
weekly_storage_audit trigger (io.kestra.plugin.core.trigger.Schedule) executes every Monday at 09:00 UTC.audit_idle_tables task (io.kestra.plugin.gcp.bigquery.Query) queries INFORMATION_SCHEMA.TABLE_STORAGE, filters tables older than inactive_days_threshold, and computes monthly storage fees.evaluate_idle_storage flowable task (io.kestra.plugin.core.flow.If) branches based on whether any large dormant tables were identified.notify_slack_finops_team (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) delivers an actionable triage card detailing dataset schemas, gigabytes, and estimated monthly dollar waste.log_clean_storage_status records nominal status in execution logs.export_storage_manifest task records execution state for cloud budget dashboards.Building custom BigQuery scheduled queries or Cloud Functions for cost governance requires maintaining separate GCP resources, IAM role bindings, and notification pipelines. Kestra unifies native BigQuery SQL execution, conditional logic, and enterprise Slack alerting into a declarative workflow that runs reliably.
| Name | Type | Default | Description |
|---|---|---|---|
gcp_project_id |
STRING | my-gcp-project |
Target Google Cloud project ID. |
gcp_region |
STRING | region-us |
BigQuery regional qualifier (e.g. region-us). |
inactive_days_threshold |
INT | 90 |
Minimum age in days before evaluation. |
storage_price_per_gb_month |
FLOAT | 0.02 |
Standard BigQuery active storage pricing per GB. |
slack_channel |
STRING | #data-finops |
Slack channel destination for alerts. |
{{ outputs.audit_idle_tables.rows }}: Array of table records containing schema, table name, gigabytes, and estimated cost.{{ outputs.audit_idle_tables.rows | length }}: Count of tables breaching the retention threshold.{{ outputs.export_storage_manifest.value }}: Structured JSON telemetry manifest recording execution timestamp and status.bigquery.jobs.create, bigquery.tables.get.GCP_SERVICE_ACCOUNT_KEY: Google Cloud service account JSON key string.SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL.GCP_SERVICE_ACCOUNT_KEY and SLACK_WEBHOOK_URL in your Kestra namespace secrets.INFORMATION_SCHEMA.TABLE_STORAGE views are regional; ensure gcp_region matches your dataset location (e.g., region-us or region-eu).storage_price_per_gb_month if using physical compressed storage.io.kestra.plugin.gcp.bigquery.Query to automatically set partition_expiration_days or expiration_timestamp on non-compliant staging tables.INFORMATION_SCHEMA.JOBS_BY_PROJECT to verify that zero queries have accessed the table over the past 90 days.