SELECT *), partition and cluster your tables, and reference the partition/cluster keys in your queries.
Deduplicating your data
Streamkap writes to BigQuery via the Storage Write API and guarantees at-least-once delivery. Rows are appended — retries can write the same change more than once — so a table can hold duplicate rows for the same key. This is expected; you get the current state by deduplicating at query time with a view, and optionally trim stored duplicates with a scheduled cleanup. Streamkap stamps every row with metadata columns you can order by to find the latest version of each record:_streamkap_source_ts_ms— when the change occurred at the source_streamkap_offset— always increases, so it breaks ties when two changes share the same source timestamp
Latest-record view
Expose the deduplicated, current state as a view. Replace the{ ... } placeholders:
The view scans the whole table each time. For large, high-churn tables, also run the scheduled cleanup below so queries (and the view) scan fewer rows.
Scheduled cleanup (optional)
For high-volume tables, schedule a query to delete superseded rows, keeping only the latest per key:Datasets
Use a separate dataset
Create a dedicated dataset for Streamkap to avoid conflicts with existing data. For the dataset location, multi-region offers better redundancy at some cost to latency/query performance; single-region is faster. With single-region datasets you can add table snapshots and scheduled exports to improve redundancy.Tables
Set a partition key
Partition by a time unit (hour, day, month, year) rather than a number — BigQuery is built for analyzing data over time, and time-unit partitioning lets you set partition expiration to drop old data automatically. If there’s no natural date/timestamp in your data, partition on the Streamkap change-event timestamp (_streamkap_source_ts_ms). See Choose Daily, Hourly, Monthly or Yearly Partitioning.
For database sources, the change-event timestamp is the snapshot time for the initial backfill, and the actual change time thereafter. Keep this in mind when partitioning on it.
Expire old partitions automatically
For high-volume tables, set Partition Expiration in Days on the destination to drop partitions older than a given age — BigQuery deletes the expired partitions for you, so storage and query scans stay bounded. It applies to any time-unit partitioning (DAY, HOUR, MONTH, YEAR); fractional days are allowed for sub-day expiration with HOUR partitioning. Leave it blank to keep all partitions, and note it has no effect when Time Partitioning is NONE (a non-partitioned table has nothing to expire).