withsoon

Chapter

6 / 10

Fact + dimension ERD

See the trusted tables, columns, and joins in one schema canvas

Hover any table or field to understand what it means, how it gets built, and how it joins into facts, marts, and features.

Fact-dimension ER diagram

Hover any table or column to inspect meaning, joins, and the row object used to build that table.

58%
profile / accountcontent_idapp_versionsession rollupgeodevicecontent_idevent_dateevent_timemarket / ISPsession_iddaily aggregatetitle contextuser feature entitygenre joinfreshness signalscontent entitysurface contextmodel lineageexperiment / variantDIMENSIONdim_useruser_skBIGINTuser_idBIGINTemail_hashVARCHAR(64)subscription_planVARCHAR(20)country_codeCHAR(2)is_currentBOOLEANDIMENSIONdim_geographygeo_skBIGINTcountry_codeCHAR(2)regionVARCHAR(50)timezoneVARCHAR(50)regulatory_regionVARCHAR(50)DIMENSIONdim_devicedevice_categoryVARCHAR(20)device_brandVARCHAR(50)os_familyVARCHAR(20)supports_4kBOOLEANEVENT FACTfact_playback_eventplayback_event_idVARCHAR(64)session_idVARCHAR(64)profile_idBIGINTcontent_idBIGINTevent_typeVARCHAR(20)position_secondsINTEGERevent_sequenceINTEGERbitrate_kbpsINTEGERDIMENSIONdim_contentcontent_idBIGINTparent_content_idBIGINTcontent_typeVARCHAR(20)primary_genreVARCHAR(50)duration_secondsINTEGERDIMENSIONdim_app_versionapp_version_skBIGINTapp_versionVARCHAR(20)release_channelVARCHAR(20)build_dateDATEsupported_featuresVARCHAR(255)CORE FACTfact_watch_sessionwatch_session_idVARCHAR(64)user_idBIGINTprofile_idBIGINTcontent_idBIGINTdevice_id_hashVARCHAR(64)session_start_tsTIMESTAMPsession_end_tsTIMESTAMPtotal_watch_secondsINTEGERunique_content_seconds_watchedINTEGERcompletion_pctDECIMAL(5,2)pause_countINTEGERseek_countINTEGERbuffering_secondsINTEGERavg_bitrate_kbpsINTEGERcountry_codeCHAR(2)device_typeVARCHAR(20)app_versionVARCHAR(20)event_dateDATEQOE FACTfact_qoe_eventqoe_event_idVARCHAR(64)session_idVARCHAR(64)content_idBIGINTisp_nameVARCHAR(80)cdn_nodeVARCHAR(80)startup_time_msINTEGERrebuffer_duration_msINTEGERerror_codeVARCHAR(40)DIMENSIONdim_timetime_idINTEGERhour_of_daySMALLINTminute_bucketSMALLINTprime_time_flagBOOLEANDIMENSIONdim_datedate_idINTEGERfull_dateDATEweek_of_yearSMALLINTfiscal_quarterSMALLINTBROWSE FACTfact_browse_impressionbrowse_impression_idVARCHAR(64)profile_idBIGINTcontent_idBIGINTpage_idVARCHAR(50)row_idVARCHAR(80)position_in_rowSMALLINTvisible_duration_msINTEGERartwork_variantVARCHAR(40)GOLD MARTrpt_content_daily_metricswatch_hoursDECIMAL(18,2)start_countBIGINTfinish_countBIGINTcompletion_rateDECIMAL(5,2)FEATUREfeature_user_genre_affinityuser_idBIGINTgenreVARCHAR(50)affinity_scoreDECIMAL(8,4)feature_tsTIMESTAMPFEATUREfeature_content_popularitycontent_idBIGINTpopularity_scoreDECIMAL(8,4)feature_tsTIMESTAMPDIMENSIONdim_experimentexperiment_skBIGINTexperiment_nameVARCHAR(80)variantVARCHAR(40)owner_teamVARCHAR(80)start_dateDATEDIMENSIONdim_recommendation_modelmodel_skBIGINTmodel_nameVARCHAR(80)model_versionVARCHAR(40)feature_snapshotVARCHAR(80)deployed_atTIMESTAMPRECOMMENDATION FACTfact_recommendation_impressionrec_impression_idVARCHAR(64)profile_idBIGINTcontent_idBIGINTmodel_idVARCHAR(64)rankSMALLINTmodel_scoreDECIMAL(8,4)experiment_idVARCHAR(64)row_idVARCHAR(80)

Hover inspector

fact_watch_session

Core fact

Grain

One row per user-profile-content-device-session

Partition

event_date

Bucket

user_id or content_id depending workload

Use case

Official watch-time, completion, binge, QoE, and recommendation features.

Prepared by

Built from playback heartbeats, pause, seek, and QoE signals after Flink sessionization, deduplication, and late-event correction merges.

Table meaning

Why is completion_pct based on unique content coverage instead of total watch seconds?

Official watch-time, completion, binge, QoE, and recommendation features.

Row object shape

class FactWatchSessionRow {
watch_session_id: string;
user_id: number;
profile_id: number;
content_id: number;
device_id_hash: string;
session_start_ts: string;
static fromEventStream(events: CanonicalEvent[]): FactRow { ... }
attachDimensionKeys(lookups: DimensionLookups): void { ... }
validateRequiredKeys(): boolean { ... }
emitWarehouseRow(): Record<string, unknown> { ... }
}
Interview answer

Explain the model by grain first

Start from the session fact, then show which dimensions explain it and which marts or features it feeds later.

Interview answer

I start with the grain of the core fact, usually one trusted playback session per profile-title-device. Then I explain which dimensions add stable context such as content, geography, device, app version, and experiment treatment. After that I show which lower-level facts still exist for debugging, like playback events or QoE incidents, and which downstream tables are derived from the trusted fact, like daily content marts and recommendation or feature tables. The point is to separate raw event history, trusted analytical facts, reusable dimensions, and business-owned marts so every consumer reads the same truth at the right level.

Last reviewed June 2026 Β· By Prasoon Parashar

Numbers are interview assumptions, not real Netflix internal figures.

Was this tab useful?