# Snowflake Streaming Destination


{{< announcement >}}
**The Snowflake Streaming destination is now Generally Available for Growth and Enterprise plans**

- [Enterprise](https://rudderstack.com/pricing/enterprise) customers get Snowflake Streaming as a part of their plan
- [Growth](https://rudderstack.com/pricing/) customers will get a free trial through June 8, 2026 — after which they can purchase it as an add-on

[Contact your Customer Success Manager](mailto:support@rudderstack.com) for any questions.
{{< /announcement >}}

[Snowflake Streaming](https://docs.snowflake.com/en/user-guide/data-load-snowpipe-streaming-overview) is a powerful tool for handling real-time data streams. It allows you to stream data rows directly in Snowflake tables with minimal latency.

Find the open source code for this destination in the [GitHub repository](https://github.com/rudderlabs/rudder-transformer/tree/main/src/v0/destinations/snowpipe_streaming).

{{< info >}}
**Migrating from Snowflake batch destination?**

To migrate from RudderStackʼs [Snowflake batch destination]({{< ref "destinations/warehouse-destinations/snowflake.md" >}}) to the newer, low-latency Snowflake Streaming destination, see the [Migration Guide]({{< ref "destinations/warehouse-destinations/snowflake-streaming/migration-guide.md" >}}) for detailed instructions.
{{< /info >}}

## When to use Snowflake Streaming

Snowflake Streaming is ideal for the following scenarios:

- **Continuous data streams**: If your data sources produce a steady stream of data in small batches, for example, clickstream data, event logs, etc.
- **Low latency requirements**: When your application requires immediate/frequent updates to the Snowflake table as new data arrives. Some use cases include real-time dashboards, streaming analytics, etc.
- **Cost optimization for streaming data**: Snowflake Streaming can potentially reduce costs for real-time pipelines as it allows micro-batch ingestion without needing a traditional Snowflake warehouse running constantly.

## Prerequisites

Before setting up the Snowflake Streaming destination in RudderStack:

- You will need to have the `ACCOUNTADMIN` system role or any account with `MANAGE GRANTS` privilege.
- You will need to set the correct user permissions in Snowflake for RudderStack to send the data correctly.

The following sections walk you through the process of setting up a virtual warehouse, database, role, and user in Snowflake.

### 1. (Optional) Create a warehouse

{{< info >}}
Note the following:

- You can skip this step if you wish to use an existing warehouse.
- For this integration, RudderStack uses the warehouse only to run some queries for performing connection validations as well as schema evolution management. It **does not use** the warehouse for data loading.
{{< /info >}}

In your Snowflake console, create a `X-Small` warehouse.

{{< image src="images/dw-integrations/snowflake-create-warehouse.webp" alt="Create a virtual warehouse" >}}

Alternatively, run the following SQL commands to create a new warehouse:

```sql
CREATE WAREHOUSE "<WAREHOUSE_NAME>"
  WITH WAREHOUSE_SIZE = 'XSMALL'
    WAREHOUSE_TYPE = 'STANDARD'
    AUTO_SUSPEND = 600
    AUTO_RESUME = TRUE;
```

{{< warning >}}
Make sure to set `AUTO_SUSPEND` to ~10 minutes and enable `AUTO_RESUME` to avoid any extra costs.
{{< /warning >}}

### 2. Create a database

RudderStack recommends creating a new database to avoid conflicts with your existing data. Note that RudderStack [creates its own tables]({{< ref "" >}}) within this database while storing your events.

{{< image src="images/dw-integrations/snowflake-create-database.webp" alt="Create a database" >}}

Alternatively, you can create a new database by running the following SQL command:

```sql
CREATE DATABASE "<DATABASE_NAME>";
```

### 3. Create a role for RudderStack

To create a new role with the required permissions to load your data into the above database, run the following SQL commands **in the exact order**. Make sure to replace the placeholder names with your preferred names.

1. Create a new role called `<ROLE>`:

```sql
CREATE ROLE "<ROLE>";
```

2. Grant access to the warehouse `<WAREHOUSE_NAME>`:

```sql
GRANT USAGE ON WAREHOUSE "<WAREHOUSE_NAME>" TO ROLE "<ROLE>";
```

3. Grant access to the database `<DATABASE_NAME>`:

```sql
GRANT USAGE ON DATABASE "<DATABASE_NAME>" TO ROLE "<ROLE>";
GRANT CREATE SCHEMA ON DATABASE "<DATABASE_NAME>" TO ROLE "<ROLE>";
GRANT ALL ON ALL SCHEMAS IN DATABASE "<DATABASE_NAME>" TO ROLE "<ROLE>";
```

{{< info >}}
You can also create a custom role with the necessary permissions and specify it in the [dashboard settings](#connection-settings) while setting up the Snowflake Streaming destination in RudderStack.
{{< /info >}}

### 4. Create a user

Since Snowflake is in the process of deprecating password-only authentication, the Snowflake Streaming destination only supports key-pair authentication.

Use the following query to create a Snowflake user that connects RudderStack to your warehouse. Make sure to replace the placeholder names with your preferred values.

```sql
CREATE USER "<USER_NAME>"
  RSA_PUBLIC_KEY = "<public_key>"
  MUST_CHANGE_PASSWORD = FALSE
  DEFAULT_ROLE = "<ROLE>"
  PASSWORD = NULL
GRANT ROLE "<ROLE>" TO USER "<USER_NAME>";
```

## Setup

{{< tip >}}
If your sources send data to different schemas, create multiple Snowflake Streaming destinations (each with a different namespace) and connect the relevant sources accordingly.
{{< /tip >}}

1. In your [RudderStack dashboard](https://app.rudderstack.com/), add a source. Then select **Snowflake Streaming** from the list of destinations.
2. Assign a name to your destination and click **Continue**.

### Connection settings

| Setting | <div style="width:300px">Description</div> |
| :-----| :-----| 
| Account | Enter the account ID of your Snowflake warehouse. This ID is part of the Snowflake URL.<br /><br />See the [Snowflake account ID examples](#snowflake-account-id-examples) for more information on how this ID varies depending on various cloud providers. |
| Database | Enter the name of the database created in the [Create database](#create-database) section. |
| Warehouse | Enter the name of your warehouse. |
| User | Enter the name of the user created in the [Create user](#create-a-user) section. |
| Role | Specify the role to be assigned to the above user. If not specified, RudderStack uses the [default role](#create-a-role-for-rudderstack). <br /><br />{{< warning >}}Make sure your role has the necessary permissions for RudderStack to load the data into the warehouse.{{< /warning >}} |
| Private Key | Generate a [private key](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-authentication) and specify it in this field. Make sure to include the delimiters. <br /><br />See the following sections in the Snowflake documentation to generate and use the key pair:<br /><br /><ul><li>[Generate private key](https://docs.snowflake.com/en/user-guide/key-pair-auth#generate-the-private-key)</li><li>[Generate public key](https://docs.snowflake.com/en/user-guide/key-pair-auth#generate-a-public-key)</li><li>[Assign public key to Snowflake user](https://docs.snowflake.com/en/user-guide/key-pair-auth#assign-the-public-key-to-a-snowflake-user)</li></ul> |
| Private Key Passphrase | Specify the password you set while encrypting the private key. Leave this field blank if your private key is not encrypted. <br /><br />{{< danger >}}The user authentication will fail if your private key is encrypted and you do not specify the passphrase.{{< /danger >}} |
| Namespace | Enter the schema name for the warehouse where RudderStack creates all tables. If not specified, RudderStack sets the namespace to the source name by default.<br /><br />{{< warning >}}You **cannot** change the namespace later.{{< /warning >}} |

#### Snowflake account ID examples

{{< customreadfile "/includes/snowflake-account-id-examples.md" >}}

### Advanced settings

| Setting | <div style="width:300px">Description</div> |
|:------------------|:-----------------| 
| Skip Tracks Table | Toggle on this setting to skip sending events to the [`tracks`]({{< ref "destinations/warehouse-destinations/warehouse-schema.md#schema" >}}) table. |
| Skip Users Table  | This destination **does not support** the [`users`]({{< ref "destinations/warehouse-destinations/warehouse-schema.md#table-users" >}}) table. |
| Merge Mode | This destination **does not support** merge mode. |
| JSON Columns | This setting lets you ingest semi-structured event data not defined by a fixed schema. Specify the required JSON column paths in the dot notation, separated by commas. <br /><br />See the [JSON Column Support]({{< ref "destinations/warehouse-destinations/json-column-support.md" >}}) guide for more information. <br /><br />{{< warning >}}Make sure to update your SDK code to use this feature correctly for snowflake streaming.{{< /warning >}} |

### Consent settings

| Setting | <div style="width:300px">Description</div> |
| :-----| :-----| 
| Consent management provider | Configure the consent management settings for the specified source by choosing the **Consent management provider** from the dropdown and entering the relevant consent category IDs. <br /><br />See [Consent Management in RudderStack]({{< ref "data-governance/consent-management/" >}}) for more information on this feature. |

## IPs to be allowlisted

{{< customreadfile "/includes/iplist.md" >}}

## Migrate from Snowflake destination

See the [Snowflake Streaming Migration Guide]({{< ref "destinations/warehouse-destinations/snowflake-streaming/migration-guide.md" >}}) for more information on how to migrate from the [Snowflake batch destination]({{< ref "destinations/warehouse-destinations/snowflake.md" >}}) to the Snowflake Streaming destination.

## FAQ

#### What is the difference between Snowflake Streaming and a traditional Snowflake warehouse?

The following table highlights the key differences between Snowflake Streaming and the traditional Snowflake warehouse:

| Feature | Snowflake Streaming | Traditional Snowflake warehouse |
| :----| :-----| :------|
| Use case | Real-time data use | Analytical and batch processing | 
| Latency | Real-time or near real-time | Higher latency (batch-oriented) |
| Data volume | Small, continuous data streams | Large, periodic batches |
| Cost efficiency | Optimized for streaming and real-time ingestion | Optimized for batch processing |

#### Why am I not seeing the `users` table in the schema for `identify` events?

This integration sends the `identify` events exclusively to the [`identifies`]({{< ref "destinations/warehouse-destinations/warehouse-schema.md#schema" >}}) table and skips the [`users`]({{< ref "destinations/warehouse-destinations/warehouse-schema.md#schema" >}}) table entirely.

#### How does Snowflake Streaming deliver data to Snowflake?

RudderStack sends event data directly to Snowflake using the [Snowpipe Streaming API](https://docs.snowflake.com/en/user-guide/data-load-snowpipe-streaming-overview). 

{{< info >}}
Unlike traditional warehouse destinations, Snowflake Streaming **does not** create staging files or load files in object storage. Data rows are streamed directly into Snowflake tables.
{{< /info >}}

#### What happens if Snowflake is unavailable?

If Snowflake is down or unreachable, RudderStack retries delivery using an exponential backoff strategy. 

Since Snowflake Streaming does not use staging files, the retry and recovery behavior differs from the retry strategy described for the traditional warehouse destinations in the [Warehouse Destinations FAQ]({{< ref "destinations/warehouse-destinations/faq.md#data-syncs-and-retries" >}}).

#### Can I replay events sent through Snowflake Streaming?

Event replay for Snowflake Streaming is only possible at the **gateway** level — the RudderStack component that first receives events from your sources. 

**You cannot trigger event replay yourself**— to replay events, [contact the RudderStack team](mailto:support@rudderstack.com).

<br />

