Snowflake

Snowflake Dynamic Tables: Declarative Pipelines Explained

2026-03-26
更新: 2026-03-27
NicheeLab Editorial Team

Dynamic Tables are Snowflake's declarative data pipeline primitive. With the traditional Streams + Tasks approach you have to procedurally define how to transform data and when to run it, but with Dynamic Tables you simply declare the final result set you want in a SELECT statement, and Snowflake handles refresh scheduling, incremental processing, and dependency resolution automatically.

Core Concepts of Declarative Pipelines

Dynamic Tables internally form a DAG (directed acyclic graph). When Dynamic Table B references source table A and Dynamic Table C references B, Snowflake automatically detects the A → B → C dependency chain and refreshes them in the correct order. You no longer need to manage Task execution order or Stream consumption timing yourself.

There are two refresh modes — Incremental and Full — and Snowflake analyzes the query to pick the optimal one automatically. Queries built from simple SELECT / JOIN / WHERE / GROUP BY operations qualify for Incremental refresh and only process the changed data, which is far more cost efficient.

CREATE DYNAMIC TABLE Syntax

-- Create a basic Dynamic Table
CREATE OR REPLACE DYNAMIC TABLE silver_orders
  TARGET_LAG = '5 minutes'
  WAREHOUSE = transform_wh
AS
  SELECT
    o.order_id,
    o.order_date,
    o.customer_id,
    c.customer_name,
    c.segment,
    o.total_amount
  FROM raw.orders o
  JOIN raw.customers c ON o.customer_id = c.customer_id
  WHERE o.order_date >= '2025-01-01';

-- Verify after creation
SHOW DYNAMIC TABLES LIKE 'SILVER_ORDERS';
DESCRIBE DYNAMIC TABLE silver_orders;

TARGET_LAG is the maximum allowed delay between a source-data change and its reflection in the Dynamic Table.WAREHOUSE specifies the warehouse used to execute refreshes.

Design Guidelines for TARGET_LAG

TARGET_LAG valueUse caseCost profile
1 minuteNear-real-time dashboards, fraud detectionHigh (frequent refreshes)
5-10 minutesBI reporting, operational monitoringMedium (balanced)
1 hour or longerDaily batch aggregation, historical analysisLow (infrequent refreshes)
DOWNSTREAMIntermediate DAG tables (auto-tracks the downstream lag)Depends on the downstream setting

DAG Dependency Resolution with DOWNSTREAM

When you chain multiple Dynamic Tables, as in a medallion architecture, set TARGET_LAG = DOWNSTREAM on the intermediate layers. Set a concrete lag value only on the most downstream Dynamic Table, and Snowflake works backwards to automatically schedule refreshes for each upstream table.

-- Medallion pipeline: Bronze -> Silver -> Gold

-- Silver layer: follows downstream via DOWNSTREAM
CREATE OR REPLACE DYNAMIC TABLE silver_daily_sales
  TARGET_LAG = DOWNSTREAM
  WAREHOUSE = transform_wh
AS
  SELECT
    DATE_TRUNC('DAY', order_date) AS sale_date,
    product_category,
    COUNT(*) AS order_count,
    SUM(total_amount) AS revenue
  FROM bronze_orders
  GROUP BY 1, 2;

-- Gold layer: concrete lag value (DAG terminal)
CREATE OR REPLACE DYNAMIC TABLE gold_sales_summary
  TARGET_LAG = '10 minutes'
  WAREHOUSE = transform_wh
AS
  SELECT
    sale_date,
    product_category,
    order_count,
    revenue,
    revenue / NULLIF(order_count, 0) AS avg_order_value
  FROM silver_daily_sales
  WHERE sale_date >= DATEADD(MONTH, -12, CURRENT_DATE());

Refresh Monitoring

You can inspect Dynamic Table refresh history through the INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORYtable function and the ACCOUNT_USAGE.DYNAMIC_TABLE_REFRESH_HISTORY view.

-- Inspect refresh history for the past 24 hours
SELECT
  name,
  refresh_trigger,
  refresh_action,       -- INCREMENTAL or FULL
  state,                -- SUCCEEDED / FAILED / CANCELLED
  state_message,
  data_timestamp,
  refresh_start_time,
  refresh_end_time,
  DATEDIFF('SECOND', refresh_start_time, refresh_end_time) AS duration_sec
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORY(
  NAME_PREFIX => 'SILVER_',
  ERROR_ONLY => FALSE
))
WHERE refresh_start_time >= DATEADD(HOUR, -24, CURRENT_TIMESTAMP())
ORDER BY refresh_start_time DESC;

Operational Commands

-- Change TARGET_LAG
ALTER DYNAMIC TABLE silver_orders SET TARGET_LAG = '15 minutes';

-- Change the warehouse
ALTER DYNAMIC TABLE silver_orders SET WAREHOUSE = new_transform_wh;

-- Suspend and resume refreshes
ALTER DYNAMIC TABLE silver_orders SUSPEND;
ALTER DYNAMIC TABLE silver_orders RESUME;

-- Manual refresh (for debugging or validation)
ALTER DYNAMIC TABLE silver_orders REFRESH;

Dynamic Tables vs Streams + Tasks

Comparison axisDynamic TablesStreams + Tasks
ParadigmDeclarative (define what you want)Procedural (define how to process)
Dependency managementAutomatic (DAG built internally)Manual (you design the Task Tree)
Incremental processingAutomatically chosen (Incremental / Full)Requires manual Stream offset management
SLA controlDeclared via TARGET_LAGControlled via CRON schedule
Error-handling flexibilityRetries are automaticCustom retry logic can be implemented in Tasks

Design Best Practices

  • Concrete lag at the tail, DOWNSTREAM in the middle: set a time-based TARGET_LAG only on the terminal table of the DAG, and let intermediate tables auto-adjust with DOWNSTREAM.
  • Design SELECT statements to favor Incremental refresh: avoid window functions and SELECT DISTINCT; SQL built on JOIN / GROUP BY / WHERE is more likely to qualify for Incremental refresh.
  • Allocate a dedicated warehouse: isolate the Dynamic Table warehouse so query workloads and refresh workloads do not contend with each other.
  • Continuously monitor with DYNAMIC_TABLE_REFRESH_HISTORY: regularly check whether Full Refresh is firing unintentionally and whether any refreshes have failed.
  • Temporarily upsize the warehouse for the initial load: the first Full Refresh has to process the entire dataset, so run it on a larger warehouse and scale back once it completes.

Check Your Understanding

Data Engineering

問題 1

You build a 3-tier medallion pipeline of Dynamic Tables: Bronze -> Silver -> Gold. The BI dashboard reads from Gold and the data freshness requirement is within 10 minutes. Which TARGET_LAG setting is most appropriate for the Silver table?

  1. TARGET_LAG = '10 minutes' (explicitly set to the same value as Gold)
  2. TARGET_LAG = '1 minute' (minimize lag to maximize freshness)
  3. TARGET_LAG = DOWNSTREAM (auto-track the downstream Gold table's lag)
  4. TARGET_LAG is optional and can be omitted

正解: C

The best practice for intermediate tables in the DAG is TARGET_LAG = DOWNSTREAM. Snowflake works backwards from Gold (10 minutes) to schedule Silver's refreshes automatically, so you do not need to set a value yourself. Option A may trigger unnecessary refreshes, option B is cost-excessive, and option D fails because omitting TARGET_LAG makes Dynamic Table creation error out.

Frequently Asked Questions

How does shortening TARGET_LAG affect the cost of Dynamic Tables?

Setting a short TARGET_LAG (such as 1 minute) makes Snowflake check for source-table changes and run refreshes more frequently, which increases Serverless Credit consumption. Polling cost is incurred even when the source rarely changes, so 5-10 minutes is recommended when business requirements allow, to balance cost and freshness. Regularly check refresh cadence and credit usage via the DYNAMIC_TABLE_REFRESH_HISTORY view.

Are there SQL constructs that Dynamic Tables do not support?

In the SELECT statement of a Dynamic Table's AS clause, you cannot use non-deterministic functions (such as CURRENT_TIMESTAMP() or RANDOM()), stored procedure calls, external function calls inside UDFs, or LIMIT / OFFSET. Window functions are allowed but typically fall outside the Incremental refresh path and may trigger Full Refresh. Choose SQL constructs with the refresh mode (Incremental vs Full) explicitly in mind.

What does the DOWNSTREAM setting do in Dynamic Tables?

Specifying DOWNSTREAM for TARGET_LAG means the Dynamic Table itself has no explicit time value; instead, its refresh schedule is automatically derived from the TARGET_LAG of downstream (dependent) Dynamic Tables. Snowflake manages refresh consistency across the entire DAG, so you no longer need to set per-table lag values for intermediate tables. The terminal (most downstream) Dynamic Table must always have a concrete time-based TARGET_LAG.

Check what you learned with practice questions

Practice with certification-focused question sets

無料で問題を解いてみる
Author

NicheeLab Editorial Team

NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.


Related articles
Snowflake

Snowflake Certifications: All 11 Exams Explained (2026)

Every SnowPro certification — Associate, Core, Specialty, Ad...

Snowflake

Snowflake Exam Difficulty Ranking: All 11 Certs Compared (2026)

All 11 SnowPro exams ranked by difficulty with study-time es...

Snowflake

Snowflake Study Guide: Fastest Pass Route by Exam (2026)

How to pass SnowPro certifications efficiently — official ma...

Snowflake

SnowPro Core (COF-C03): Complete Exam Guide (2026)

Pass the SnowPro Core exam — six domains, scope, sample ques...

Snowflake

SnowPro Associate Platform (SOL-C01): Complete Guide (2026)

The entry-level SnowPro Associate exam — scope, weighting, s...

Browse all Snowflake articles (103)
© 2026 NicheeLab All rights reserved.