8.3 Snowpipe Streaming & Real-Time Ingestion

Key Takeaways

  • Snowpipe Streaming ingests rows directly from applications into Snowflake tables (or Snowflake-managed Iceberg tables) without staging files, with ingest-to-queryable latency as low as about 5 seconds and up to 20 GB/s per table.
  • The high-performance architecture routes rows through a PIPE object; Elastic Channels (at-least-once, Snowflake-managed) suit IoT and app events, while Named Channels with offset tokens give ordered, exactly-once ingestion for Kafka partitions or CDC.
  • Clients use the Java, Python, or Node.js SDK (shared Rust core) or a REST API with NDJSON payloads; billing is throughput-based in credits per uncompressed GB ingested.
  • The classic architecture uses the snowflake-ingest-java SDK (insertRows, getLatestCommittedOffsetToken) without a PIPE object and is planned for future deprecation, so new designs should use the high-performance architecture.
  • Pairing Snowpipe Streaming for row landing with dynamic tables or streams and tasks for transformation builds low-latency pipelines without external stream processors.
Last updated: September 2026

8.3 Snowpipe Streaming & Real-Time Ingestion

Traditional bulk ingestion (COPY INTO) and continuous file ingestion (Snowpipe) share one dependency: data must first be written as files to a stage before Snowflake loads it. For event streams — fraud signals, telemetry, clickstreams, CDC — producing files adds latency and operational work.

Snowpipe Streaming removes the file step: applications send rows directly to Snowflake, which makes them queryable within seconds.


Snowpipe Streaming Architecture: Fileless Ingestion

Instead of Snowflake pulling files from a stage, client applications push rows to Snowflake through an SDK or a REST API.

+-----------------------------------------------------------------------------------------+
|                     TRADITIONAL FILE-BASED INGESTION (MINUTES)                          |
| Producer -> Micro-batch Buffer -> Cloud Storage Stage (PUT API) -> Snowpipe -> Table    |
+-----------------------------------------------------------------------------------------+
                                             vs
+-----------------------------------------------------------------------------------------+
|                       SNOWPIPE STREAMING (SECONDS)                                      |
| Producer -> SDK or REST API -> Channel -> PIPE object -> Target table                   |
+-----------------------------------------------------------------------------------------+

The High-Performance Architecture

  1. Client side: The Java, Python, or Node.js SDK (all built on a shared Rust client core) buffers appended rows, batches them by time and size, compresses them, and sends them to Snowflake. Lightweight clients (IoT devices, edge services) can call the REST API directly with newline-delimited JSON (NDJSON).
  2. PIPE object: Rows flow through a PIPE object to the target table. The pipe can apply in-flight transformations using COPY-style syntax (reorder, cast, expressions) and can pre-cluster data for tables with clustering keys. Snowflake also provides a default pipe per table.
  3. Channels: A channel is the logical path that carries rows through the pipe:
    • Elastic Channels (recommended starting point): producers just write; Snowflake manages channels and scales ingestion. Delivery is at-least-once without ordering guarantees.
    • Named Channels: the application opens named channels (for example one per Kafka partition) and supplies offset tokens for ordered, exactly-once ingestion within each channel.
  4. Serverless ingestion: Snowflake commits the rows to the table; they are typically queryable in as little as about 5 seconds, with throughput of up to 20 GB/s per table depending on workload shape.

Architectural Benefits

  • Low latency without files: no staging buckets, no file-size tuning, no event notifications.
  • Throughput-based pricing: billed in credits per uncompressed GB ingested; no warehouse to size or suspend.
  • Iceberg and schema evolution: can stream into Snowflake-managed Iceberg tables and can add new columns detected in the stream.
  • Error visibility: optional error logging captures rows that fail processing after they were acknowledged.

Client Channels & SDK Implementation Mechanics

The fundamental abstraction in Snowpipe Streaming is the Channel.

What is a Channel?

A channel is a logical path that carries rows into a table. With Named Channels, multiple client processes can open independent channels to the same table — typically one per upstream partition (Kafka partition, Kinesis shard, CDC slot) — and each channel keeps its own ordering and offset position.

Channel Lifecycle in the Classic Java SDK

The example below uses the classic architecture (snowflake-ingest-java), which you will still see in existing deployments and exam-style scenarios. It has no explicit PIPE object; channels are opened directly against the table. Snowflake plans to announce its deprecation (with an 18-month migration window afterward), so new designs should use the high-performance SDKs, which follow the same channel and offset-token concepts.

// Step 1: Initialize the streaming ingest client with RSA key-pair authentication
SnowflakeStreamingIngestClient client = SnowflakeStreamingIngestClientFactory
    .builder("STREAMING_CLIENT_01")
    .setProperties(connectionProperties)
    .build();

// Step 2: Open a dedicated channel to the target table
OpenChannelRequest openChannelRequest = OpenChannelRequest
    .builder("kafka_partition_channel_0")
    .setDBName("CORE_DB")
    .setSchemaName("STREAMING")
    .setTableName("IOT_EVENTS")
    .setOnErrorOption(OpenChannelRequest.OnErrorOption.CONTINUE)
    .build();

SnowflakeStreamingIngestChannel channel = client.openChannel(openChannelRequest);

// Step 3: Stream rows with an offset token for exactly-once tracking
Map<String, Object> row = new HashMap<>();
row.put("device_id", "DEV-9942");
row.put("reading", 42.85);
row.put("event_timestamp", System.currentTimeMillis());

InsertRowsResponse response = channel.insertRows(
    Collections.singletonList(row),
    "offset_token_1004829" // Monotonically increasing offset
);

if (response.hasErrors()) {
    // Inspect row insertion errors
    List<InsertError> errors = response.getInsertErrors();
}

Exactly-Once Delivery Guarantees via Offset Tokens

In high-throughput distributed streaming architectures, network drops, worker container crashes, and consumer group rebalances inevitably cause message retransmissions. Achieving exactly-once semantics without expensive downstream SQL MERGE or deduplication tables is a core architectural requirement.

The Offset Token Mechanism

Snowpipe Streaming solves distributed deduplication through Channel Offset Tokens:

  1. When the client calls insertRows, it associates the batch with an opaque string identifier: the offset_token (e.g., Kafka partition offset 1004829, Kinesis sequence number, or transaction LSN).
  2. Snowflake commits the offset token into the table metadata simultaneously with the row data commit.
  3. Recovery Sequence on Worker Restart:
    • If a client worker crashes and restarts, it reconnects and re-opens the channel.
    • The client invokes channel.getLatestCommittedOffsetToken().
    • Snowflake returns the last successfully committed token (1004829).
    • The client seeks its source stream (e.g., Kafka consumer) to 1004830 and resumes streaming.
    • Exactly-once depends on this pattern: the application reads the committed token and resumes after it, so rows at or before the committed offset are never re-sent. Offset tokens are opaque strings to Snowflake; the client defines their meaning.
+-----------------------------------------------------------------------------------------+
|                       CRASH RECOVERY WITH OFFSET TOKENS                                 |
+-----------------------------------------------------------------------------------------+
| 1. Client streams records 1001-1005 with offset_token = "1005".                        |
| 2. Snowflake commits micro-partition & records offset_token = "1005" in catalog.        |
| 3. Client crashes before receiving acknowledgment.                                      |
| 4. Client restarts -> Calls channel.getLatestCommittedOffsetToken().                   |
| 5. Snowflake responds: Latest offset is "1005".                                         |
| 6. Client fast-forwards upstream queue and resumes from 1006. Zero duplicates!          |
+-----------------------------------------------------------------------------------------+

Exam Trap: Offset tokens are strictly channel-scoped, not table-scoped. If Client A opens channel_1 and Client B opens channel_2 against the same table, each channel tracks its own independent offset token sequence.

Architectural Comparison: Bulk COPY vs. Snowpipe vs. Snowpipe Streaming

Choosing the correct ingestion pattern is a fundamental competency tested on the SnowPro Advanced: Architect exam.

Architectural DimensionBulk COPY INTO <table>Snowpipe (Auto-Ingest)Snowpipe Streaming
Primary Ingestion ParadigmScheduled BatchContinuous Micro-BatchContinuous Real-Time Streaming
End-to-End Ingestion LatencyMinutes to hours (batch schedule)About a minute or two after file arrivalSeconds (as low as ~5 s)
Data UnitLarge files (100 MB–250 MB)Small files (10 MB–100 MB)Individual Rows / Records
Intermediate Cloud Stage?Mandatory (S3/Azure/GCS)Mandatory (S3/Azure/GCS)None (Direct fileless streaming)
Compute InfrastructureCustomer Virtual WarehouseSnowflake-managedSnowflake-managed
Billing ModelWarehouse credits per secondFixed credits per GB loadedCredits per uncompressed GB ingested
Deduplication Engine64-day load metadata14-day pipe load historyOffset tokens (Named Channels)
Primary Exam ScenarioLarge historical bulk migrationsRegular files landing in cloud bucketsKafka, IoT, CDC streaming queues

The Snowflake Connector for Apache Kafka

The Snowflake Connector for Kafka supports two loading methods: Snowpipe (the connector writes files to an internal stage and calls Snowpipe) and Snowpipe Streaming. Streaming is the lower-latency choice:

# Snowflake Kafka Connector configuration for Snowpipe Streaming
connector.class=com.snowflake.kafka.connector.SnowflakeSinkConnector
tasks.max=8
topics=financial_transactions
snowflake.topic2table.map=financial_transactions:FCT_TRANSACTIONS
snowflake.ingestion.method=SNOWPIPE_STREAMING
snowflake.role.name=INGEST_PROD_ROLE

With Snowpipe Streaming, each Kafka topic partition maps to its own channel, and the connector stores Kafka offsets as offset tokens so it can resume exactly where it left off after a restart. Latency drops from minutes to seconds and no intermediate files are created.

Downstream Architectures: Streaming Ingestion with Dynamic Tables

Snowpipe Streaming is optimized for high-throughput row landing. However, analytical workloads rarely query raw, denormalized streaming payloads directly. Modern enterprise architectures combine Snowpipe Streaming with Dynamic Tables to create automated, declarative streaming ELT pipelines:

  1. Landing Tier (Bronze): Snowpipe Streaming writes raw records into a landing table within seconds.
  2. Transformation Tier (Silver): A declarative Dynamic Table queries the landing table with TARGET_LAG = '1 minute'. Snowflake automatically computes incremental deltas, parses JSON attributes, and materializes cleaned dimensional records.
  3. Aggregation Tier (Gold): Downstream Dynamic Tables or aggregate views calculate rolling KPIs for real-time dashboards.

For many pipelines this removes the need for an external stream processor (such as Flink or Spark Streaming) just to pre-process data before loading into Snowflake.

Loading diagram...
Snowpipe Streaming End-to-End Real-Time Architecture
Test Your Knowledge

An e-commerce platform produces 50,000 order events per second into Apache Kafka. Fraud analytics needs the data queryable in Snowflake within seconds, and the team wants to avoid managing staged files. Which ingestion strategy fits best?

A
B
C
D
Test Your Knowledge

During a network outage, an application worker streaming IoT events via the Snowpipe Streaming SDK loses connection to Snowflake. After the worker process restarts, how does it prevent duplicate records from being committed to the target table without executing an expensive downstream SQL deduplication query?

A
B
C
D
Test Your Knowledge

Which statement accurately describes an architectural difference between Snowpipe (Auto-Ingest) and Snowpipe Streaming?

A
B
C
D