New to Kestra?
Use blueprints to kickstart your first workflows.
Stream Pub/Sub messages into BigQuery with Kestra. A trigger micro-batches events and appends them as newline-delimited JSON, staying under per-row DML limits.
Stream Google Cloud Pub/Sub messages into BigQuery in near real time without writing a consumer service or fighting per-row streaming quotas. This blueprint uses a Pub/Sub trigger to micro-batch incoming events, converts them to newline-delimited JSON, and appends each batch to a raw BigQuery landing table in a single load job. It solves the classic event-ingestion problem: keeping analytics data fresh while staying well under BigQuery's streaming and DML limits and following the ELT pattern of capture first, parse downstream.
io.kestra.plugin.gcp.pubsub.Trigger polls the kestra-events-sub subscription on a fixed interval (PT1M) and starts the flow with the batch of messages it consumed, up to maxRecords (1000) per run, serialized as JSON.to_json task (io.kestra.plugin.serdes.json.IonToJson) converts the consumed batch from Kestra's internal ION format into the newline-delimited JSON that BigQuery accepts.load_to_bigquery task (io.kestra.plugin.gcp.bigquery.Load) appends the batch to the analytics.pubsub_events_raw table with format: JSON, autodetect: true, createDisposition: CREATE_IF_NEEDED, and writeDisposition: WRITE_APPEND, so the table is created on first load and grows append-only.alert_on_failure error handler (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) posts the failed execution to Slack.Pub/Sub can push or pull messages, but it has no scheduler that batches events, transforms them, loads them, and alerts on failure as one observable pipeline. Kestra adds an event-driven trigger that fires on new messages, retries on transient errors, full execution lineage and logs, and a declarative YAML definition you can version and review. The micro-batching cadence (interval plus maxRecords) is the specific gap Pub/Sub's own delivery cannot fill: it turns a continuous stream into clean, quota-friendly load jobs.
An existing Pub/Sub topic (events) with a subscription (kestra-events-sub) and a BigQuery analytics dataset. The analytics.pubsub_events_raw table is created automatically on the first load.
GCP_PROJECT_ID: GCP project hosting the Pub/Sub topic and BigQuery dataset.GCP_SERVICE_ACCOUNT: service account key JSON with BigQuery and Pub/Sub access.SLACK_WEBHOOK_URL: Slack incoming webhook URL for failure alerts.topic and subscription at your own Pub/Sub resources.disabled: true so importing the blueprint does not connect with placeholder config).analytics.pubsub_events_raw.interval for fresher data or raise maxRecords for larger, cheaper batches.io.kestra.plugin.gcp.bigquery.Query or dbt task to parse the raw message envelope (data, attributes, messageId) into typed columns.