Menu
Blog Documentation Community Pricing Demo Call Sign Up
Sign Up

An Intro to Snowflake Streams and Tasks

Learn how Snowflake streams and tasks work, when to use them, how they compare to dynamic tables, and the main production pitfalls.

Snowflake

This post was written by an engineer at QueryPlane. QueryPlane is an app builder for your database: bring your own postgres db and you can create interactive applications to share with other developers, coworkers or even your customers. If you’re interested in trying it out, get started here.


Snowflake streams and tasks are still one of the most important building blocks for warehouse automation. Even with dynamic tables gaining mindshare, streams and tasks remain the better fit for many real-world data engineering jobs because they give you explicit control over change capture and execution behavior.

This guide explains how they work, when to use them, and where teams usually run into trouble.

In this post, we’ll cover:

  • What streams do
  • What tasks do
  • A simple CDC pipeline example
  • Triggered tasks and staleness
  • When to choose streams and tasks over dynamic tables

What a stream does

A Snowflake stream records change data capture information for a source object between transactional points in time. In practical terms, it lets you ask “what changed in this table since the last time I consumed changes?”

That is why streams are useful for:

  • incremental ELT
  • CDC-style transformations
  • audit-style processing
  • event-driven warehouse automation

Snowflake supports different stream types. The standard stream captures inserts, updates, and deletes as a delta. Append-only streams capture only inserts.

For many teams, this is the simplest way to stop reprocessing an entire table every run.

What a task does

A task executes SQL on a schedule or in response to conditions. That means tasks are the execution mechanism that turns a stream into a pipeline.

Tasks are useful for:

  • scheduled incremental jobs
  • multi-step task graphs
  • consuming change data and merging it into downstream tables
  • calling stored procedures on a cadence

You can think about streams as the “what changed?” layer and tasks as the “when do we act on those changes?” layer.

A simple pattern: stream plus task

Imagine you ingest raw customer events and want to keep a clean latest-state table.

First, define the raw table and a stream on top of it:

CREATE OR REPLACE STREAM raw.customer_events_stream
ON TABLE raw.customer_events;

Then create a task that consumes changes and merges them into a downstream model:

CREATE OR REPLACE TASK analytics.refresh_customers
  WAREHOUSE = transform_wh
  SCHEDULE = '5 MINUTE'
AS
MERGE INTO analytics.customers AS target
USING (
  SELECT *
  FROM raw.customer_events_stream
) AS source
ON target.customer_id = source.customer_id
WHEN MATCHED THEN UPDATE SET
  email = source.email,
  status = source.status,
  updated_at = source.event_ts
WHEN NOT MATCHED THEN INSERT (
  customer_id,
  email,
  status,
  updated_at
) VALUES (
  source.customer_id,
  source.email,
  source.status,
  source.event_ts
);

This is the classic Snowflake pattern: track deltas with a stream, apply them with a task.

Triggered tasks make the pattern more event-driven

Snowflake also supports triggered tasks, which are useful when you do not want fixed cron-style execution. A triggered task checks for changes in the stream and runs when relevant data appears.

This is often better than “run every five minutes no matter what” because it reduces wasted work when nothing has changed.

It is particularly useful for:

  • near-real-time ingestion flows
  • stream-driven transformations
  • workloads with irregular arrival patterns

The official docs note that triggered tasks run at most every 30 seconds by default, with options to reduce the minimum interval. That makes them a good middle ground between batch scheduling and fully custom orchestration.

The biggest operational risk: stream staleness

One of the most common mistakes with Snowflake streams is forgetting that they are not infinite buffers. If changes are not consumed before retention expires, the stream can become stale.

Snowflake’s docs explicitly talk about avoiding stream staleness, and this is where a lot of teams get burned:

  • a task is suspended
  • a dependency breaks
  • no one notices for long enough
  • the change window is lost

This is why streams and tasks are not just SQL objects. They are operational systems. If you use them in production, you should care about monitoring, lag, failure handling, and ownership.

Streams and tasks vs dynamic tables

This is the decision most teams are making in 2026.

Choose streams and tasks when you need:

  • explicit execution control
  • procedural logic
  • custom merge behavior
  • event-style pipelines
  • orchestration you can reason about step by step

Choose dynamic tables when you need:

  • simpler declarative refresh behavior
  • less pipeline plumbing
  • outcome-first table definitions

If your pipeline is basically “consume changes and perform controlled SQL logic,” streams and tasks are often still the better abstraction. If your pipeline is “keep this transformed table fresh,” dynamic tables may be simpler.

Neither feature makes the other obsolete.

See what QueryPlane can build for you

Connect to your database, write SQL with AI, and build shareable apps — all from your browser.

Common mistakes

Assuming a stream is the source of truth

It is not. The base table is the source of truth. The stream is a change-tracking mechanism with lifecycle constraints.

Not consuming changes transactionally

If a task reads stream data and downstream writes are not handled carefully, you can create duplicate or inconsistent outcomes. Design the consumer logic as a real incremental pipeline, not a loose collection of SQL statements.

Letting tasks fail silently

Streams and tasks feel simple to create, which makes teams underestimate the need for observability. If a task stops running, the pipeline is not healthy just because the SQL definition still exists.

Using them when a declarative table refresh would be simpler

Sometimes teams build task graphs because that is what they already know, not because the pipeline really needs that level of control.

When to use streams and tasks

They are a strong fit for:

  • CDC ingestion and merge pipelines
  • event-driven transformations
  • incremental warehouse models with explicit logic
  • pipelines that must coordinate multiple steps carefully

They are less attractive when:

  • the pipeline is mostly table-shaped and declarative
  • your team wants less orchestration code
  • target freshness matters more than exact step scheduling

Frequently asked questions

What is the difference between a Snowflake stream and a task? A stream is change-data-capture metadata over a table: it remembers which rows have been inserted, updated, or deleted since you last read from it. A task is a scheduled or DAG-driven piece of SQL that Snowflake runs on your behalf. Streams describe what changed; tasks describe when to do something about it. Almost every production pipeline pairs them.

Does a stream consume the changes when I read it? Only when you read it inside a DML statement that succeeds (e.g., INSERT ... SELECT FROM stream or MERGE ... USING stream). A bare SELECT FROM stream does not advance the offset. The advance happens at commit, so streams are naturally exactly-once with respect to their consumer transaction.

What is the difference between a standard stream, an append-only stream, and an insert-only stream? A standard stream captures inserts, updates, and deletes (six metadata columns per row). An append-only stream captures inserts only on standard tables — cheaper to maintain when you do not need delete/update semantics. An insert-only stream captures inserts on external tables and directory tables, where Snowflake cannot observe updates or deletes from the warehouse side.

How long do streams retain change data? A stream retains change data for the maximum of the source table’s DATA_RETENTION_TIME_IN_DAYS and the account-level retention, capped by the source table’s MAX_DATA_EXTENSION_TIME_IN_DAYS setting. If you do not consume from the stream within that window, it becomes stale and you have to recreate it from a snapshot.

Should I use a serverless task or a warehouse-backed task? Serverless tasks bill in 1-second increments and are good for short, infrequent work because there is no warehouse start-up cost. Warehouse-backed tasks are usually cheaper for longer-running or higher-throughput jobs, especially if the warehouse is already running for other workloads. Mix them on the same pipeline if you have both shapes.

Can a task call another task? Tasks form a DAG via AFTER <parent_task> dependencies, not by calling each other. A child task runs only after its parents complete successfully, and Snowflake handles the orchestration. You enable the root task and the rest of the DAG follows on the same schedule.

Why does my task run report “no data to process”? SYSTEM$STREAM_HAS_DATA('<stream>') returns false when the stream has no new change rows since the last consumer offset. Production pipelines almost always wrap task bodies in WHEN SYSTEM$STREAM_HAS_DATA('s') so that the task does not bill for empty work.

Wrapping up

Snowflake streams and tasks are still core infrastructure for serious warehouse automation. Streams tell you what changed. Tasks decide when and how to act on those changes. That pattern remains useful because it is explicit, flexible, and well suited to real incremental pipelines.

If your team wants more control than dynamic tables provide, streams and tasks are probably still the right answer. If your team wants less orchestration overhead, dynamic tables may simplify part of the system.

If you’re evaluating how to work with these features day to day, our guide to the best Snowflake GUI tools can help you pick the right interface. And if you are deciding between abstractions, pair this with our dynamic tables guide. For the upstream ingestion side — what feeds the source tables streams sit on — see our guide to Snowflake stages, COPY INTO, and Snowpipe.