New to Kestra?
Use blueprints to kickstart your first workflows.
Automated BigQuery FinOps workflow to query JOBS_BY_PROJECT, detect runaway multi-terabyte query scans, and alert Slack.
In Google BigQuery on-demand analysis models, query costs scale directly with the volume of bytes scanned ($6.25 per terabyte). An unpartitioned analytical query, unintended cross-join, or unconstrained exploratory query in a multi-user organization can trigger full-table scans across multi-terabyte datasets, producing hundreds or thousands of dollars in surprise cloud compute charges within seconds.
Furthermore, in capacity-based reservations, rogue queries with excessive slot consumption exhaust assigned slots, causing high-priority production pipelines and executive dashboards to stall in queuing states.
This blueprint establishes an automated FinOps guardrail for BigQuery. Running hourly or on-demand, it inspects INFORMATION_SCHEMA.JOBS_BY_PROJECT within your target GCP region to detect completed queries that scanned more than your configured terabyte threshold or consumed excessive slot computation time. When detected, it dispatches an actionable Slack alert with user attribution, estimated dollar impact, and query snippets.
hourly_finops_audit trigger (io.kestra.plugin.core.trigger.Schedule) executes at minute 15 of every hour, or runs on-demand via the Kestra UI.audit_expensive_jobs task (io.kestra.plugin.gcp.bigquery.Query) queries regional INFORMATION_SCHEMA.JOBS_BY_PROJECT, filtering completed queries in the lookback window that breached terabyte or slot thresholds and calculating estimated dollar costs.evaluate_job_anomalies flowable task (io.kestra.plugin.core.flow.If) branches based on whether any runaway queries were returned.notify_finops_slack (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) delivers an alert card detailing the job ID, author email, billed terabytes, dollar cost, and query snippet.log_nominal_capacity records nominal status in execution logs.export_job_manifest task records telemetry outputs for cloud cost accounting records.Google Cloud native billing exports operate on multi-hour delays, making real-time spend intervention difficult. Kestra provides declarative, fast orchestration: it queries BigQuery's near-real-time INFORMATION_SCHEMA, evaluates threshold breaches hourly, notifies the team directly in Slack, and securely handles GCP service account credentials.
| Name | Type | Default | Description |
|---|---|---|---|
region |
STRING | us |
Google Cloud region where BigQuery query execution history resides. |
lookback_hours |
INT | 1 |
Historical time window in hours to inspect completed BigQuery query jobs. |
max_billed_tb_threshold |
FLOAT | 2.0 |
Flag any single query that scanned and billed more than this volume in terabytes. |
max_slot_minutes_threshold |
INT | 30 |
Flag queries consuming more than this cumulative slot computation time in minutes. |
cost_per_tb_usd |
FLOAT | 6.25 |
On-demand query pricing per terabyte. |
slack_channel |
STRING | #finops-alerts |
Slack channel destination for BigQuery FinOps cost alerts. |
{{ outputs.audit_expensive_jobs.rows }}: Array of job records containing job_id, user_email, billed_terabytes, estimated_cost_usd, slot_minutes_consumed, and query_snippet.{{ outputs.audit_expensive_jobs.size }}: Total number of runaway queries detected during the lookback window.{{ outputs.evaluate_job_anomalies }}: Result of conditional branch evaluation.{{ outputs.export_job_manifest.value }}: Structured JSON telemetry manifest recording execution timestamp and status.roles/bigquery.resourceViewer or roles/bigquery.admin to query project-level INFORMATION_SCHEMA.JOBS_BY_PROJECT.GCP_PROJECT_ID: Your Google Cloud Project ID.GCP_SERVICE_ACCOUNT_JSON: Service account key JSON authorized to view project BigQuery jobs.SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL used for sending alert notifications.GCP_PROJECT_ID, GCP_SERVICE_ACCOUNT_JSON, and SLACK_WEBHOOK_URL in your Kestra namespace secrets.INFORMATION_SCHEMA.JOBS_BY_PROJECT must be qualified with the region where query jobs executed (e.g., `my-project`.`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT). Ensure inputs.region matches your query location.bigquery.jobs.listAll permission, typically provided by the roles/bigquery.resourceViewer IAM role.statement_type != 'SCRIPT' to focus on individual root queries.user_email.ALTER PROJECT ... SET OPTIONS (maximum_bytes_billed = ...).