Skip to Content
StreamsEvents Warehouse

Event Warehouse

Write collected events to your data warehouse for long-term storage and analysis.

Overview

When a forwarding rule targets a warehouse source (BigQuery, Snowflake, Databricks, ClickHouse, Redshift), events are batched, serialized, uploaded to staging, and bulk-loaded into per-event-type tables. Every event carries its originating source identity, consent state, and is partitioned on its event timestamp for efficient time-range queries.

Configuration

  1. Navigate to Streams > Forwarding
  2. Click Create Forwarding Rule
  3. Select the event source and choose a warehouse source as the target
  4. Configure the warehouse settings:
    • Schema name (default: zeotap_events) — target dataset/schema
    • Custom table name (optional) — override the auto-derived table name
    • Partition column (default: timestamp) — column used for day-partitioning/clustering
  5. Click Save

Table Naming

Zeotap creates one table per event type. The table name depends on whether the forwarding rule is scoped to a specific source and whether a custom table name is configured.

Event TypeSource PrefixTable Name
tracknonetracks
identifynoneidentifies
pagenonepages
screennonescreens
groupnonegroups
track”Web App”web_app_tracks
identify”Mobile App”mobile_app_identifies
purchase (custom)nonepurchases
app.install (custom)noneapp_installs

Source prefixes are derived from the event source (write key) name: lowercased, non-alphanumeric characters replaced with underscores, and truncated to a safe length. Custom event types are pluralized idempotently (names already ending in s are left alone).

To override the auto-naming, set Custom Table Name on the forwarding rule. This is useful when downstream consumers expect a specific table name.

Table Schema

Every event table has the same columns regardless of warehouse dialect:

ColumnTypeDescription
idstringMessage ID (unique per event)
workspace_idstringWorkspace identifier
write_key_idstringWhich event source sent this event
write_key_namestringHuman-readable source name for quick inspection
user_idstringIdentified user ID
anonymous_idstringAnonymous user ID
eventstringEvent name (for track)
propertiesJSON / VARIANTEvent properties
traitsJSON / VARIANTUser traits (for identify)
contextJSON / VARIANTEvent context (page, device, campaign, etc.)
timestamptimestampWhen the event occurred (client-provided)
received_attimestampWhen Zeotap received the event
sent_attimestampWhen the client sent the event
group_idstringGroup ID (for group events)
namestringPage/screen name
categorystringPage/screen category
server_ipstringClient IP address
consent_stringstringIAB TCF v2 consent string
us_privacystringIAB CCPA US Privacy string (e.g., 1YNN)
consent_categoriesJSON / VARIANTGranted consent categories as a JSON object

Partitioning and Clustering

New event tables are partitioned (or clustered, depending on the warehouse) on the timestamp column so time-range queries scan only the relevant partitions:

WarehouseStrategy
BigQueryDay-partitioned on timestamp via TimePartitioning
SnowflakeCLUSTER BY (timestamp) after table creation
DatabricksCLUSTER BY (timestamp) on Delta tables
ClickHouseMergeTree table ordered on timestamp
RedshiftSORTKEY (timestamp) on table creation

You can override the partition/clustering column per forwarding rule by setting Partition Column in the rule config. This is useful when you have a custom event timestamp field that better reflects your query patterns.

Note: BigQuery cannot retroactively partition existing tables. If you need to change the partition column or enable partitioning on a pre-existing table, you must drop and recreate it.

Every event row carries structured consent context extracted from context.consent:

  • consent_string — IAB TCF v2 consent string or your own consent string
  • us_privacy — IAB CCPA US Privacy string
  • consent_categories — JSON object of granted categories (e.g., {"analytics": true, "marketing": false})

This lets you query consent-aware cohorts directly in SQL:

-- Count users who opted out of marketing SELECT COUNT(DISTINCT user_id) FROM web_app_tracks WHERE JSON_EXTRACT(consent_categories, '$.marketing') = false AND timestamp >= '2026-01-01';

Schema Evolution

  • The column list is fixed — new event properties are stored inside the properties JSON column
  • Query JSON columns using your warehouse’s JSON functions (JSON_EXTRACT, ->, ::variant)
  • Custom event types automatically get their own table on first event arrival

API Reference

See Events API for warehouse configuration endpoints.

Next Steps

Last updated on