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-revenueThe 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 triggerTwo 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.

