Convex Wearables
Reference

Data Model

Tables, indexes, and deduplication rules used by the component.

Core tables

TableDescriptionKey indexes
connectionsOAuth tokens and provider links per userby_user, by_user_provider, by_status
dataSourcesUser + provider + device/source combinationsby_user_provider, by_user_provider_device, by_connection
eventsWorkouts and sleep sessionsby_user_category_time, by_external_id, by_source_start_end
dataPointsRaw time-series samplesby_source_type_time, by_type_time
timeSeriesRollupsBucketed historical time-series aggregatesby_source_type_bucket, by_source_type_bucket_size, by_source_bucket, by_type_bucket
dailySummariesPrecomputed daily aggregatesby_user_category_date, by_user_date
syncJobsSync workflow recordsby_user, by_user_provider, by_user_status, by_status
oauthStatesTemporary OAuth PKCE stateby_state
backfillJobsLong-running historical data import trackingby_connection, by_status
TableDescriptionKey indexes
timeSeriesPolicyRulesDefault rules and preset rulesby_set, by_set_scope
timeSeriesPolicyAssignmentsPer-user preset assignmentby_user, by_preset
timeSeriesPolicySettingsGlobal maintenance settingsby_key
timeSeriesSeriesStatePer-source series maintenance cursorby_source_series, by_next_maintenance, by_user

Deduplication rules

Events

Events are deduplicated at two levels:

  1. externalId when the provider gives a stable identifier
  2. dataSourceId + startDatetime + endDatetime as a second guardrail

Data points

Raw data points are deduplicated by:

  • dataSourceId
  • seriesType
  • recordedAt

Rollups

Rollups are upserted by:

  • dataSourceId
  • seriesType
  • bucketMs
  • bucketStart

Query strategy

The component separates raw rows and rollups so that:

  • recent high-fidelity data can stay raw
  • older dense history can become cheaper rollup buckets
  • reads can choose the best available representation for the requested time range

For details on how tiers are resolved, see Storage Policies.

On this page