Setting the file. One moment.
Skill 97 · Modeling Dimension Tables
Subchapter 97.4
references/dimension-catalog.mdMarkdown3 KBView on GitHub
For each dimension: how to source it, its natural key, and notes. Model each as one row per key.
| Dimension | Natural key |
|---|
| Source it by |
|---|
| Notes |
|---|
| Country | country_code (ISO-2) | Derive from properties.$geoip_country_code on events, or upload an ISO list. | Enrich with region/continent from an uploaded lookup. |
| Region / continent | country_code → region | Upload a country→region CSV (seed / warehouse source). | Conforms with the country dimension; join on country_code. |
| Timezone | timezone (IANA, e.g. Europe/Berlin) | From properties.$timezone, or a country→timezone lookup (upload). | One country can have many timezones; key on the IANA string, not the country. |
| Currency | currency (ISO-4217) | Built in — use convertCurrency(); no table needed on PostHog. | Only build a dim_currency_rate in dbt (no equivalent there) or for a non-default provider. |
| Date | date | Generate a calendar spine (date, week, month, quarter, DOW, is_weekend). | Classic conformed dimension; cheap; materialize once. |
| Plan / tier | plan_id or plan_name | Upload a plan→tier→price lookup, or sync from Stripe products. | Join to revenue facts for tier-level revenue. |
| Product | product_id | Managed revenue_analytics product view, or sync from source. | Prefer the managed view if it exists (see modeling-revenue-metrics). |
seeds/*.csv + dbt seed.plans table).
Connect via setting-up-a-data-warehouse-source, then shape the raw table into a clean aliased view.SELECT DISTINCT + argMax to pick the latest value per key. Cheapest, but only covers values that appear
in events.The natural key must be truly unique in the dimension — dedupe before saving. If a raw source has multiple
rows per key (history, per-source duplicates), collapse to one row (argMax by updated-at) or model an
explicit slowly-changing dimension. Fact tables carry the key; the dimension carries everything else.