> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hightouch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Write events to your warehouse

> Configure an event storage destination so Hightouch can write event data to your warehouse.

## Overview

To write event data collected by Hightouch Events to your warehouse, you must configure an **event storage destination**.

An event storage destination defines:

* **Where** events are written (Snowflake, BigQuery, Redshift, etc.)
* **How** event tables and schemas are created
* **How** event properties and context fields are stored

Once configured, Hightouch automatically creates and manages event tables in your warehouse as new events and fields are received.

> [!NOTE]
>
> Event storage is **optional but strongly recommended** if you want to use
> events for analytics, modeling, or warehouse-based activation.

> [!TIP]
>
> You can also use Hightouch Events in a [**streaming‑only**
> mode](https://docs.hightouch.com/events/event-streaming.md) to forward events directly to downstream tools
> without writing them to the warehouse.

## Supported event storage destinations

Hightouch supports the following event storage destinations:

* [Snowflake](#snowflake)
* [BigQuery](#bigquery)
* [Redshift](#redshift)
* [Databricks](#databricks)
* [Microsoft Fabric](#microsoft-fabric)
* PostgreSQL
* [Amazon S3](#amazon-s3)

Each destination supports the same core event schema, with destination-specific configuration options.

## Destination-specific prerequisites

Most event storage destinations only need the credentials you provide on the **Connect destination** step. The destinations below also need specific warehouse or IAM grants. Set these up before you connect the destination, so Hightouch can create tables and load events on the first sync.

### Snowflake

Hightouch creates the schema if it doesn't already exist, creates tables, and adds columns as your event schema evolves. It stages rows as CSV files in cloud storage, then loads them with `COPY INTO` and merges them into the final table.

If you're setting up a new Hightouch service account, use the [service account template](https://docs.hightouch.com/destinations/snowflake#service-account-setup). It includes the `CREATE SCHEMA` and `CREATE TABLE` grants that event storage needs. If you already have a Hightouch service account from before you added Snowflake as an event storage destination, confirm it includes both grants.

### BigQuery

Hightouch creates the dataset if it doesn't already exist, creates tables, and adds columns as your event schema evolves. It stages rows as JSON files in a Hightouch-managed Cloud Storage bucket, then loads and merges them into the final table. Hightouch grants your service account read access to those staged files automatically, so you don't need to configure separate Cloud Storage permissions.

Use [full access](https://docs.hightouch.com/destinations/google-bigquery#grant-full-access) (`bigquery.user`, `bigquery.dataViewer`, and `bigquery.dataEditor`) when you use BigQuery as an event storage destination. The [limited access](https://docs.hightouch.com/destinations/google-bigquery#grant-limited-access) custom role is scoped to datasets and tables you specify up front, so it doesn't cover creating a new dataset for event storage.

> [!NOTE]
>
> When you connect the destination, choose the **Dataset location** that matches
> the region you want your event data stored in. Hightouch stages files in the
> same location.

### Redshift

Hightouch connects with a username and password (a dedicated Hightouch user is recommended) and supports SSH tunneling for private clusters. It creates the schema if it doesn't already exist, creates tables, and adds columns as your event schema evolves. It stages rows as CSV files in a Hightouch-managed S3 bucket using temporary credentials, then loads them with `COPY` and merges them into the final table.

Grant your Hightouch user the following on the schema this destination writes to:

```sql theme={null}
GRANT USAGE, CREATE ON SCHEMA your_schema TO hightouch_user;
```

If `your_schema` doesn't already exist, either create it yourself first or also grant schema creation at the database level:

```sql theme={null}
GRANT CREATE ON DATABASE your_database TO hightouch_user;
```

> [!NOTE]
>
> Hightouch owns the tables it creates, so no separate `INSERT` or `ALTER` grant
> is required for those tables. If you pre-create the schema or tables yourself
> instead, grant `SELECT` and `INSERT` explicitly. Redshift's `ALTER` privilege
> only applies to tables managed through AWS Lake Formation, so you'll need to
> add new columns to pre-created tables yourself as your event schema evolves.

### Databricks

Hightouch creates the schema if it doesn't already exist, creates tables, and adds columns as your event schema evolves. It stages rows as Avro files in a Hightouch-managed S3 or Azure Blob Storage location using temporary credentials, then loads them with `COPY INTO` and merges them into the final table.

Grant the schema-level permissions in [Connect to Databricks](https://docs.hightouch.com/destinations/databricks#connect-to-databricks) on a schema you've pre-created. If you'd rather have Hightouch create the schema automatically on first sync, also grant `CREATE SCHEMA` on the catalog.

### Microsoft Fabric

Hightouch writes events to Microsoft Fabric using the [service principal](https://docs.hightouch.com/sources/fabric.md#service-principal-creation) you provide when you connect the destination. Before you add a Microsoft Fabric event storage destination, grant that service principal the SQL permissions it needs in your Fabric warehouse.

> [!NOTE]
>
> Microsoft Fabric event storage requires a **Fabric Data Warehouse**. A
> Lakehouse's SQL analytics endpoint is read-only and can't accept the writes
> Hightouch needs to load events.

Events collect into Hightouch, stage as Parquet files in Azure Blob Storage, then load into your warehouse with `COPY INTO`. Hightouch also creates staging tables and alters the target table as your event schema evolves. From the Fabric workspace SQL console, run the following, replacing `your_service_principal` with your service principal's name and `your_schema` with the schema this destination writes to (set on the [**Schema settings** tab](#schema-settings-tab) after setup):

```sql theme={null}
-- Required to load staged events with COPY INTO
GRANT ADMINISTER DATABASE BULK OPERATIONS TO [your_service_principal];
GRANT INSERT TO [your_service_principal];
-- Required because Hightouch creates staging tables and manages the target schema
GRANT CREATE TABLE TO [your_service_principal];
GRANT ALTER ON SCHEMA::[your_schema] TO [your_service_principal];
```

Hightouch checks whether `your_schema` exists at the start of every sync and creates it automatically if it doesn't. If the schema doesn't exist yet, either create it yourself first or also grant schema creation:

```sql theme={null}
GRANT CREATE SCHEMA TO [your_service_principal];
```

> [!NOTE]
>
> Grant these permissions to the service principal explicitly. Testing the
> connection with a personal or work account instead can succeed without these
> grants, because that account inherits broader permissions in the Fabric
> workspace. This can hide a missing grant until Hightouch runs a sync using the
> service principal.

These grants are specific to Microsoft Fabric as an event storage destination. If you also use Microsoft Fabric as a Hightouch source, see [Microsoft Fabric source setup](https://docs.hightouch.com/sources/fabric.md#lightning-engine-setup). That connection uses different grants.

If your Fabric workspace restricts inbound connections by IP, also confirm Hightouch's IP addresses are allowlisted for your workspace region. See [Networking](https://docs.hightouch.com/security/networking#ip-addresses).

#### You do not have permission to use the bulk load statement

You may see this error if the service principal is missing the grants above:

```text theme={null}
Error loading data into cdp_events_raw.{staging_table} from Azure Blob Storage:
You do not have permission to use the bulk load statement.
```

Run the grants above for your service principal, then retry the sync.

### Amazon S3

Unlike the other event storage destinations, Amazon S3 doesn't involve any schema or table management. Hightouch writes raw event files directly to your bucket. See [Connect to Amazon S3](https://docs.hightouch.com/destinations/s3.md#connect-to-amazon-s3) for the required IAM permissions.

## Step-by-step: Set up an event storage destination

### 1. Add a destination

1. In the left navigation, go to **`Event Collection → Event destinations`**
2. Click **`Add destination`**

   ![Add event destination button](https://mintcdn.com/hightouch-3c037897/L_vQfA0JQEpeGUUo/images/events/storage/add-event-destination.png?fit=max\&auto=format\&n=L_vQfA0JQEpeGUUo\&q=85\&s=eec6541523666163b87a20c67684cbe4)

### 2. Select a destination type

On the **Select a destination** step:

1. Under **Event storage**, choose your warehouse (for example, **Snowflake**)
2. Click the destination tile to continue

   ![Select event storage destination](https://mintcdn.com/hightouch-3c037897/L_vQfA0JQEpeGUUo/images/events/storage/select-destination.png?fit=max\&auto=format\&n=L_vQfA0JQEpeGUUo\&q=85\&s=3f34a5a0be2242ca00a61ffed429e0e8)

### 3. Connect the destination

On the **Connect destination** step, enter the required warehouse credentials.

For example, for Snowflake, you’ll configure:

* **Account identifier**
* **Warehouse**
* **Database**
* **Authentication method** (RSA key recommended)

You’ll also upload credentials and validate that Hightouch can connect successfully.

For credential and permission setup, see the destination-specific guides:

> [!WARNING]
>
> The destination docs linked below cover both credential setup and
> **model-based sync configuration**.
>
> For **event destinations**, only the credential/permission setup applies. Skip
> sections like **Sync configuration**, **Add sync**, and any model mapping or
> sync mode instructions.

* [Snowflake](https://docs.hightouch.com/destinations/snowflake#connect-to-snowflake)
* [BigQuery](https://docs.hightouch.com/destinations/google-bigquery#connect-to-google-adh-via-bigquery)
* [Redshift](#redshift)
* [Databricks](https://docs.hightouch.com/destinations/databricks#connect-to-databricks)
* [Microsoft Fabric](#microsoft-fabric)
* [PostgreSQL](https://docs.hightouch.com/destinations/postgres.md#connect-to-postgresql)
* [Amazon S3](https://docs.hightouch.com/destinations/s3.md#connect-to-amazon-s3)

If your destination needs additional warehouse or IAM grants beyond credentials, see [Destination-specific prerequisites](#destination-specific-prerequisites) above.

![Connect Snowflake destination](https://mintcdn.com/hightouch-3c037897/L_vQfA0JQEpeGUUo/images/events/storage/connect-destination.png?fit=max\&auto=format\&n=L_vQfA0JQEpeGUUo\&q=85\&s=48646cc51e58ddaf7ef999830ec8d643)

Click **`Continue`** once the connection details are complete.

### 4. Finalize the destination

On the **Finalize** step:

1. Review the destination details
2. Click **`Finish`**

Once finalized, the destination becomes available for event storage.

## What happens after setup

After your event storage destination is created and used in an event sync:

* Hightouch begins writing incoming events to your warehouse
* Schemas and tables are created automatically (see: [**Warehouse schema**](https://docs.hightouch.com/events/warehouses/schema.md))
* New event fields are added as columns as they appear

You can manage this behavior using the destination’s **Configuration** and **Schema settings** tabs.

## Configuration after initial setup

Navigate to:

**`Event Collection → Event destinations → [Select destination]`**

### Configuration tab

The **Configuration** tab contains the core warehouse connection settings, including:

* Account and authentication details
* Warehouse, database, and role configuration
* Credentials and key management

Use this tab if you need to:

* Rotate credentials
* Update authentication methods
* Change the warehouse or database used for writes

![Event destination configuration tab](https://mintcdn.com/hightouch-3c037897/L_vQfA0JQEpeGUUo/images/events/storage/configuration-tab.png?fit=max\&auto=format\&n=L_vQfA0JQEpeGUUo\&q=85\&s=03da93911d3808c6695527c367a54713)

### Schema settings tab

The **Schema settings** tab controls how Hightouch writes event data into your warehouse.

From here, you can configure:

* **Schema name**\
  Customize the schema Hightouch uses. By default, this is derived from the event source name.

* **Per-event tables**\
  When enabled, Hightouch creates a separate table for each `track` event type.\
  When disabled, all track events are written to a shared `tracks` table.

* **Convert properties and context fields to columns**\
  When enabled, event properties and context fields are written as individual columns.\
  When disabled, they are stored as JSON.

* **Write Page and Screen events to the Tracks table**\
  Useful if you want all user interactions in a single table.

![Event destination schema settings](https://mintcdn.com/hightouch-3c037897/L_vQfA0JQEpeGUUo/images/events/storage/schema-settings.png?fit=max\&auto=format\&n=L_vQfA0JQEpeGUUo\&q=85\&s=cdc668aa0ee3cd9348bf2e61a1160bfa)

These settings apply to all events written to this destination.

## Validating event storage

After setup, you should:

1. Send test events from an event source
2. Confirm tables and schemas appear in your warehouse
3. Verify event fields match your tracking spec

You can also inspect events in the debugger before they’re written to storage.

→ See [**Warehouse schema**](https://docs.hightouch.com/events/warehouses/schema.md) for a full breakdown of tables and columns.

## Enable, disable, and run event warehouse syncs

Manage your event warehouse syncs from **Event Collection → Event syncs**.

* **Enable or disable a sync** — open the sync and use the **Enabled** toggle in the header. A disabled sync stops running.
* **Run a sync on demand** — select **Run** on the sync's page.
* **Manage syncs in bulk** — select one or more syncs in the list to reveal the **Actions** dropdown, then choose **Run**, **Disable**, or **Enable** to apply it to every selected sync.

> [!WARNING]
>
> Events received while a sync is disabled are dropped, along with any queued
> events that haven't been delivered yet. They can't be recovered when you
> re-enable the sync.

## Next steps

* Understand how events are written to your warehouse: [Warehouse schema](https://docs.hightouch.com/events/warehouses/schema.md)
* Review retries, failures, and archived events: [Error handling](https://docs.hightouch.com/events/warehouses/error-handling.md)
* Forward events to downstream tools: [Event streaming](https://docs.hightouch.com/events/event-streaming.md)
