RudderStack Schema Reference

Reference for the warehouse tables that store Reverse ETL sync state, snapshots, and failure data.

On every Reverse ETL sync, RudderStack writes tables into a dedicated schema in your warehouse so you can audit what was extracted, what changed, and what failed. Create this schema before you set up a Reverse ETL source — see the permissions section of your warehouse source documentation.

WarehouseSchema name
Snowflake_RUDDERSTACK
BigQueryrudderstack_
Other warehouses_rudderstack
warning
Do not rename this schema.

What gets written depends on the sync mode and whether you enable a cursor column. Configure how long tables and logs are retained in Sync Observability Settings.

Table families

Table naming patternCreated whenContents
SNAPSHOT_<connectionId>_<syncRunId>Mirror, or Upsert without a cursor columnFull set of in-scope rows for that sync in source schema, plus RUDDER_OPERATION_TYPE (insert, update, delete, or unchanged)
FAILED_KEYS_<connectionId>_<syncRunId>Mirror, UpsertPrimary-key columns of failed records (for example CONTEXT_TRAITS_EMAIL and _RUDDER_ID), plus RUDDER_OPERATION and RUDDER_INVALID
AGGR_FAIL_KEYS_<connectionId>_<syncRunId>Mirror, Upsert_RUDDER_ID and numeric CODE (HTTP status). Join to FAILED_KEYS_* on _RUDDER_ID
CURSOR_<connectionId>_<syncRunId>Upsert with a cursor columnOne row: CHECKPOINT = high-watermark of the cursor column
SYNC_DATA_<connectionId>_<syncRunId>Upsert with a cursor columnDelta rows since the last checkpoint (first sync = full load). Includes RUDDER_OPERATION_TYPE, RUDDER_SNAPSHOT_ID, and RUDDER_SNAPSHOT_RUN_AT
SYNC_LOGAny mode, when sync logs are enabledPer-record, per-sync log across connections (see Sync log table)
info
Older workspaces may also show legacy names such as SNAPSHOT_<hash>_<epoch>, SYNC_DATA_<hash>, or FAILED_RECORDS_<hash>. The current convention is <TABLE_TYPE>_<connectionId>_<syncRunId>.

Table name format

Example: SNAPSHOT_2WRS3TRTNKIGHHLDKHXIJTWLU7C_D0F3FOFMJ6M0GOGO5HHG

SegmentMeaningWhere to find it
SNAPSHOTTable type
2WRS3TRTNKIGHHLDKHXIJTWLU7CConnection IDSettings tab of the Reverse ETL connection
D0F3FOFMJ6M0GOGO5HHGSync run IDSpecific sync in the Syncs view
Reverse ETL connection sync run ID

Behavior by sync mode

ModeWarehouse tablesPoint-in-time history
MirrorSNAPSHOT_*, FAILED_KEYS_*, AGGR_FAIL_KEYS_*Full in-scope population per retained sync
Upsert (no cursor column)Same as MirrorFull in-scope population per retained sync
Upsert with cursor columnCURSOR_*, SYNC_DATA_* (no SNAPSHOT_*)Delta rows only — not a full population snapshot
warning
Cursor/incremental mode and snapshot tables are mutually exclusive. If you need to reconstruct the full population at a past sync, use Mirror or Upsert without a cursor column, and raise snapshot retention as needed.

Retention

Two independent settings on each connection (Settings > sync observability):

SettingUnitDefault (typical)Effect
Snapshot table retentionNumber of syncs5Keeps the N most recent successful snapshots per connection; older SNAPSHOT_* / FAILED_KEYS_* tables are dropped
Sync log retentionDays30Deletes SYNC_LOG rows older than N days

Point-in-time lookback is bounded by these settings. Raising retention extends your audit window and increases warehouse storage and table count in the schema.

Source data vs destination payload

SNAPSHOT_* and SYNC_DATA_* capture rows as extracted from the source warehouse — before transformation or mapping applied on the way to the destination. They show what RudderStack decided to send, in the source schema. They do not show the exact post-transformation payload delivered to the destination.

Failure tables

TableWhat you getWhat you don’t get
FAILED_KEYS_*Keys of failed recordsError code or message
AGGR_FAIL_KEYS_*Numeric HTTP status (for example 400) per _RUDDER_IDHuman-readable destination error
SYNC_LOG.error_reasonSame class of status detail when logs are enabledFull per-record destination message

Detailed destination errors (for example, “invalid email”) appear as sampled examples in the RudderStack dashboard — one sample per error type per sync — not as full per-record messages in the warehouse.

Sync log table

When you enable sync logs, RudderStack writes a single SYNC_LOG table. Column names may appear uppercased depending on your warehouse.

ColumnDescription
connection_idConnection ID for the sync run
sync_run_idUnique identifier for the sync run
primary_keyValue of the primary key column selected for the sync
operationOperation on the row: insert, update, or delete
statussucceeded or failed
error_reasonFailure detail when status is failed (typically a numeric HTTP status code, not a full destination message)
sync_started_atSync start time in UTC
sync_finished_atSync finish time in UTC
warning
Storing sync logs in your warehouse incurs additional costs.

Snapshot table

For Mirror and Upsert (no cursor), each sync writes a SNAPSHOT_<connection_id>_<sync_run_id> table. It contains in-scope source rows (excluding invalid rows such as duplicate or null primary keys) and the change type for each row.

ColumnDescription
rudder_operation_typeinsert, update, delete, or unchanged relative to the last synced data
Mapped source columnsColumns selected in the sync mappings
warning
Storing snapshot tables in your warehouse incurs additional costs.

Example queries

Replace placeholders with your connection ID, sync run IDs, primary key column, and column name. Schema name may be _rudderstack, _RUDDERSTACK, or rudderstack_ depending on your warehouse.

Trace a primary key across syncs

SELECT *
FROM _rudderstack.sync_log
WHERE primary_key = '<primary_key>'
  AND connection_id = '<connection_id>';

Join failed sync log rows to a snapshot

SELECT *
FROM _rudderstack.sync_log sl
LEFT JOIN _rudderstack.snapshot_<connection_id>_<sync_run_id> sn
  ON sl.primary_key = sn.<primary_key>
WHERE sl.sync_run_id = '<sync_run_id>'
  AND sl.status = 'failed';

Find rows whose value changed between two snapshots

Use this when you need contacts (or other records) that had a given value in an earlier sync but not in a later one — for example, to remediate downstream data after a bad source query.

SELECT earlier.<primary_key>, earlier.<column_name>
FROM _rudderstack.snapshot_<connection_id>_<earlier_sync_run_id> earlier
WHERE earlier.<column_name> = '<value>'
  AND NOT EXISTS (
    SELECT 1
    FROM _rudderstack.snapshot_<connection_id>_<later_sync_run_id> later
    WHERE later.<primary_key> = earlier.<primary_key>
      AND later.<column_name> = earlier.<column_name>
  );

Empty failure tables

RudderStack creates FAILED_KEYS_* and AGGR_FAIL_KEYS_* for each applicable sync even when no records fail. Empty tables are expected. Retention cleanup removes older ones according to your snapshot table retention setting.

Questions? We're here to help.

Join the RudderStack Slack community or email us for support