FFastero

Connect any database. Ask in plain English.

Try free
Back to blog

Blog article

How to Set Up Event-Driven Triggers for Your Data Pipelines

Polling wastes compute and adds latency. Event-driven triggers fire your pipelines when data actually changes — via Snowflake CDC, Kafka messages, webhooks, database row changes, or cron. Here's how to configure each one.

Fastero Dev TeamFastero Dev Team
2026-08-08
triggersevent-drivendata-pipelinesworkflowsautomation
How to Set Up Event-Driven Triggers for Your Data Pipelines

Event-driven triggers start your data pipeline the moment something changes — a row inserted, a Kafka message published, a webhook received — instead of running on a blind schedule. Fastero supports five trigger types: Snowflake CDC streams, Kafka topic consumers, database row changes, inbound webhooks, and cron expressions. Each one wires to workflows that run SQL, Python, dashboard refreshes, or alerts.

Why does polling cost more and deliver less?

The default pattern is a cron job every 15 minutes. It works. It's also wasteful in two directions: when data arrives between runs, you eat unnecessary latency. When data hasn't changed, you burn compute checking empty tables.

Polling (cron every 15 min):
 
  Data lands:   08:02    08:31         09:47
                  |        |             |
  Cron runs:  08:00  08:15  08:30  08:45  09:00  09:15  09:30  09:45  10:00
                       |           |                                    |
                    process     process                              process
                   (13m late)  (14m late)                            (13m late)
 
  5 empty runs. 3 late runs. Max latency: 14 minutes.
 
Event-driven:
 
  Data lands:   08:02    08:31         09:47
                  |        |             |
  Trigger:      08:02    08:31         09:47
                  |        |             |
  Process:      08:02    08:31         09:47
 
  0 empty runs. 0 late runs. Max latency: seconds.

The cost difference compounds. A warehouse waking up 96 times per day at the minimum billing increment costs real money. A trigger that fires 10 times when data actually changes costs a fraction of that. And 14 minutes of staleness is the difference between catching a payment failure now and catching it after the customer has already emailed support.

What trigger types are available?

Fastero's trigger system supports five types. Each one fits a different data source pattern:

Trigger Type Fires When Best For
Snowflake stream CDC stream has unconsumed rows Warehouse-native transforms, fact table merges
Kafka topic Messages arrive on a topic Streaming analytics, real-time alerting
Database change New/updated rows detected (Postgres, MySQL) Application database reactions, audit logging
Webhook Inbound HTTP POST received Third-party integrations (Stripe, Shopify, HubSpot)
Cron Schedule expression matches Batch reports, nightly aggregations, periodic cleanup

All five wire to the same workflow engine. A Snowflake trigger and a webhook trigger produce the same output: context variables your workflow steps can reference. The trigger decides when. The workflow decides what.

Fastero

Connect your database. Ask questions. Get dashboards.

Postgres, BigQuery, Snowflake, and 10+ sources — live-connected, AI-powered, no dashboard builder learning curve.

Try free →

How do you set up a Snowflake change trigger?

Snowflake streams track row-level inserts, updates, and deletes on a table. Fastero's Snowflake trigger monitors a stream and fires your workflow when unconsumed changes exist. You don't manage stream consumption or staleness — the trigger handles the lifecycle.

trigger:
  type: snowflake_stream
  connection: warehouse-prod
  stream: RAW.PUBLIC.ORDERS_STREAM
  check_interval: 60s
 
steps:
  - name: merge_changed_orders
    action: run_sql
    sql: |
      MERGE INTO ANALYTICS.FACT_ORDERS t
      USING RAW.PUBLIC.ORDERS_STREAM s ON t.order_id = s.order_id
      WHEN MATCHED THEN UPDATE SET t.status = s.status, t.updated_at = s.updated_at
      WHEN NOT MATCHED THEN INSERT (order_id, customer_id, amount, status, created_at)
        VALUES (s.order_id, s.customer_id, s.amount, s.status, s.created_at);
 
  - name: refresh_dashboard
    action: refresh_dashboard
    dashboard: daily-revenue

The check_interval is how often Fastero polls the stream metadata — not the data itself. That check is lightweight. When the stream has rows, the workflow fires. When it doesn't, nothing happens. More on Snowflake-specific patterns: How to Set Up Snowflake Triggers for Real-Time Pipelines.

How do you wire a Kafka topic to a workflow?

Kafka triggers join a consumer group on your cluster and fire workflows as messages arrive. Batch or per-message, depending on whether you need sub-second alerts or hourly aggregations.

trigger:
  type: kafka
  connection: kafka-prod
  topic: payments.completed
  consumer_group: fastero-payment-analytics
  batching:
    max_size: 200
    max_wait_seconds: 30
 
steps:
  - name: aggregate_payments
    action: run_sql
    sql: |
      INSERT INTO payment_metrics_hourly (hour, payment_count, total_amount)
      SELECT
        date_trunc('hour', (event->>'timestamp')::timestamptz),
        COUNT(*),
        SUM((event->>'amount')::numeric)
      FROM unnest({{ trigger.messages }}) AS event
      GROUP BY 1
      ON CONFLICT (hour) DO UPDATE SET
        payment_count = payment_metrics_hourly.payment_count + EXCLUDED.payment_count,
        total_amount = payment_metrics_hourly.total_amount + EXCLUDED.total_amount;

The trigger manages offsets and rebalancing. Your SQL just needs to be idempotent — ON CONFLICT upserts handle duplicates during consumer group rebalances. Full walkthrough: How to Set Up Kafka Triggers for Streaming Analytics.

What about webhooks and cron schedules?

Webhooks are the simplest trigger type. Fastero gives you an endpoint URL, and any system that can POST to it — Stripe, Shopify, GitHub, your own app — fires your workflow.

trigger:
  type: webhook
  path: /hooks/stripe-invoice-failed
  secret: ${WEBHOOK_SECRET}   # HMAC validation
 
steps:
  - name: log_failed_invoice
    action: run_sql
    sql: |
      INSERT INTO billing_alerts (invoice_id, customer_id, amount, failed_at)
      VALUES (
        '{{ trigger.body.data.object.id }}',
        '{{ trigger.body.data.object.customer }}',
        {{ trigger.body.data.object.amount_due }} / 100.0,
        NOW()
      );
 
  - name: alert_finance
    action: send_notification
    channel: slack
    destination: "#billing-ops"
    message: "Failed invoice {{ trigger.body.data.object.id }} for ${{ trigger.body.data.object.amount_due / 100 }}"

Cron triggers are for jobs that genuinely belong on a schedule — nightly report generation, weekly data quality scans, monthly rollups. Standard cron syntax: 0 9 * * 1-5 for weekdays at 9am, 0 */4 * * * for every 4 hours. Use cron when the business need is time-based ("send the weekly report Monday morning"), and event-driven triggers when the need is data-based ("process new orders as they arrive").

How does the trigger-to-action flow actually work?

Every trigger type feeds into the same execution model:

  ┌─────────────────────────────────────────────────┐
  │                  TRIGGER LAYER                   │
  │                                                  │
  │  Snowflake   Kafka    Webhook   DB Change  Cron  │
  │  Stream      Topic    POST      NOTIFY     Expr  │
  └──────┬────────┬────────┬─────────┬─────────┬─────┘
         │        │        │         │         │
         └────────┴────┬───┴─────────┴─────────┘


              ┌────────────────┐
              │  Context Vars  │  ← trigger.messages, trigger.body,
              │  (JSON)        │    trigger.changed_rows, etc.
              └───────┬────────┘

         ┌────────────┼────────────┐
         ▼            ▼            ▼
   ┌──────────┐ ┌──────────┐ ┌──────────┐
   │ SQL Step │ │ Python   │ │ Notify / │
   │          │ │ Step     │ │ Refresh  │
   └────┬─────┘ └────┬─────┘ └──────────┘
        │             │
        ▼             ▼
   Next step (with conditions, retries, branching)

The trigger produces context variables. Your workflow steps consume them. Step outputs flow forward as additional variables — conditions on any step can reference results from any previous step. Error handling is per-step: retry with backoff, skip and continue, or abort and notify a separate ops channel. Same execution model whether the trigger is a Snowflake stream with 500 changed rows or a Stripe webhook with a single invoice event.

How do you pick the right trigger for your pipeline?

  What produces the data your pipeline needs?

  ├── Snowflake table changes
  │   └── Snowflake stream trigger

  ├── Kafka / event stream
  │   └── Kafka topic trigger

  ├── Application database (Postgres, MySQL)
  │   └── Database change trigger (LISTEN/NOTIFY)

  ├── External SaaS (Stripe, Shopify, HubSpot)
  │   └── Webhook trigger

  └── Nothing "arrives" — I just need periodic runs
      └── Cron trigger

Two patterns trip people up. First: using cron when you actually want event-driven. If you're polling a table for new rows every 5 minutes, a database change or Snowflake stream trigger gives you lower latency and zero wasted runs. Second: using event-driven when cron is fine. A weekly executive report needs to run on Monday at 9am, not react to every row change.

For teams migrating from Airflow or Dagster, the mapping is straightforward: each sensor-at-the-top-of-a-DAG becomes a trigger, each linear chain of operators becomes a workflow, and the DAGs with real fan-out/fan-in dependencies stay where they are.

FAQ

Can I use multiple trigger types on the same workflow? Yes. A workflow can have multiple triggers — for example, a Kafka trigger for real-time processing and a cron trigger for daily backfill runs. Each trigger fires an independent execution of the same workflow steps.

What happens if a triggered workflow fails mid-execution? Each step has its own error policy: retry with configurable backoff, skip and continue, or abort and notify. For Kafka triggers, the offset isn't committed until the workflow succeeds, so failed batches are automatically retried. Webhook triggers return a non-200 status so the sending system can retry on its end.

Do triggers work with databases other than Snowflake? Yes. Database change triggers support Postgres (via LISTEN/NOTIFY) and MySQL (via binlog). The Snowflake stream trigger is Snowflake-specific because it uses Snowflake's native CDC mechanism. Kafka and webhook triggers are source-agnostic — they work with any data that can be published to a topic or POSTed to a URL.

How is this different from Airflow sensors? Airflow sensors poll for a condition while holding a worker slot. When your S3 sensor waits 3 hours for a file, that's 3 hours of blocked compute. Fastero triggers are push-based — they register a listener and only consume resources when the event actually fires. No idle workers, no poke_interval tuning.

Is there a limit on how many triggers I can run? No hard limit. Triggers are lightweight — a cron trigger is a schedule entry, a webhook trigger is an endpoint registration, and even Kafka/Snowflake triggers only consume resources during active processing. Teams commonly run 50+ triggers across different sources without capacity planning.


Try Fastero free — set up Snowflake, Kafka, webhook, and cron triggers for your data pipelines in minutes. No credit card required.

Ready to try it yourself?

Connect your database, ask questions in plain English, and get live dashboards — in under 2 minutes. No credit card required.