| Audience | Data or analytics engineers, platform admins |
| Prerequisites |
|
Before configuring your schema in Customer Studio, plan which data to expose and how to structure it. The decisions on this page determine what marketers can target, filter on, and sync to destinations.
What you'll learn
After reading this article, you'll know how to:
- Choose the right grain for your parent model
- Decide where data belongs: parent model, related model, event model, trait, or merge column
- Decide when a value should be a trait vs. upstream logic
- Structure a starter schema and expand it over time
- Name models and columns so marketers can self-serve
- Avoid common anti-patterns that lead to confusing audience behavior
Overview
The schema is the contract between data teams and marketers. It determines what data marketers can access in the audience builder, what they can filter on, and what they can sync to destinations. A clean, well-named schema makes Customer Studio self-serve. A messy one turns every audience into a data-team request.
In Customer Studio, you'll define three types of models:
- Parent model: The base entity audiences are built from (for example,
Users) - Related models: Additional context joined to the parent (for example,
Households) - Event models: Timestamped behaviors (for example,
Product Viewed)
Together, these models and their relationships form your data schema — a map of what marketers can filter on when building audiences.

Coordinate with business teams
Before building your schema, align with marketers or campaign owners on what they need to target and filter on. Start with one or two high-priority use cases rather than designing for everything at once. Good first use cases include:
- Suppression audiences (for example, exclude recent purchasers from ad spend)
- Re-engagement windows (for example, users inactive for 30+ days)
- Lifecycle stage audiences (for example, trial users who haven't activated)
Use these use cases to decide which tables to expose, which relationships to define, and how to name models and columns so marketers can find what they need without asking for help.
Choose the right grain
Your parent model's grain — what one row represents — is your targeting grain. One row in the parent model equals one entity that can appear in an audience, be deduplicated, and be synced to a destination.
Before choosing a table, decide what one row should represent. Common choices include individual users, accounts, households, or devices. This choice shapes everything downstream:
- Audience membership is evaluated per parent row
- Sync output contains one record per qualifying parent row
- Traits and filters resolve back to the parent grain
If you set the parent model at the account grain, you can target accounts but not individual users within them. If you need both, you'll need separate parent models or a user-level grain with account data joined as a related model.
When to use multiple parent models
Some businesses need to target different entities for different use cases. A B2B company might target individual users for product adoption campaigns and accounts for renewal outreach. A marketplace might target buyers and sellers separately.
The rule of thumb: the parent model represents who you're communicating with. If that varies by use case, create separate parent models — each with its own related models, events, and traits. Each parent model powers its own independent set of audiences.
The grain doesn't always map to a person. For example, an airline that upsells passengers for each upcoming flight might set its parent model to one row per traveler per flight — not one row per traveler. That way, each flight booking gets its own campaign, and marketers can target the December trip and the February trip independently.
Common scenarios that call for multiple parent models:
- B2B companies targeting both users and accounts
- Marketplaces with distinct buyer and seller audiences
- Products with both end users and admin contacts
Start with one parent model for your highest-priority use case. Add a second only when you have a concrete campaign that requires a different targeting entity. Avoid creating extra parent models just to expose more fields — in most cases, the better solution is a related model, a through relationship, or a trait. More parent models create more audience entry points, more duplicated configuration, and more opportunities for marketers to choose the wrong one.
If a related model or event table connects to multiple parent models, share it via relationships instead of duplicating it.
Choose the right model type
Not all data belongs in the same place. Use this table to decide where a piece of data should live in your schema:
| If you need to... | Use a... | Example |
|---|---|---|
| Target an entity directly | Parent model column | region, signup_date, plan_tier |
| Filter on repeated records linked to the parent | Related model | Purchases, subscriptions, support tickets |
| Filter on timestamped behaviors | Event model | Page views, logins, cart additions |
| Collapse many rows into one value per parent row | Trait | Total spend, days since last login, most frequent category |
| Access a parent field inside a related or event model | Merge column | Show region on purchase records |
Sync field mappings draw from parent model columns, merge columns, and traits. Data on related and event models is available for audience filtering but does not appear directly in sync output. To include a value from a related model in a sync, create a trait that rolls it up to the parent or add it as a merge column.
If a marketer asks "why can't I use this field in my sync mapping?" the answer is almost always about model topology. Fields on related or event models are available for audience filtering, but sync field mappings draw from parent model columns, merge columns, and traits. To make a related-model field syncable, either add it as a merge column, create a trait that rolls it up to the parent, or restructure upstream so the value lives on the parent model directly.
When to model something as a trait
The decision table above includes traits as an option for collapsing many rows into one value per parent row. Use a trait when the value is a reusable derived attribute that marketers will filter on repeatedly — lifetime value, days since last purchase, total number of orders, or most frequent product category.
Traits are the right choice when:
- The value doesn't exist as a column on the parent model and needs to be computed from related or event data
- Multiple audiences will use the same calculation, so you want to define it once
- Marketers need the value in sync field mappings (traits on the parent model are syncable; related/event fields are not)
Keep the logic upstream instead when:
- The calculation defines a core business metric your team governs centrally (for example, official LTV or churn score)
- The computation is expensive and benefits from materialization in the warehouse
- Multiple teams outside Customer Studio need the same value
For details on creating and managing traits, see Traits.
Start with a recommended shape
You don't need to model your entire warehouse on day one. A good starting point:
- 1 parent model (for example,
Users) with common attributes flattened onto it (email, region, plan, signup date) - 2–3 high-value related models (for example, Purchases, Subscriptions)
- 1–2 event tables (for example, Page Views, Logins)
Expand the schema as use cases grow. It's easier to add models than to clean up a schema that exposes too much too early.
Name models and columns for marketers
Marketers interact with the schema through the audience builder. Names should be immediately understandable without warehouse context:
- Use plain names:
Signup datenotcreated_at,Regionnotgeo_region - Name models after what they represent, not where they come from:
Usersnotbraze_user_attributes,Purchasesnotfact_order_items - Use column aliases to rename technical column names without changing your warehouse
- Disable columns that add noise (internal IDs, ETL metadata, debugging fields)
Keep data types consistent
Mismatched data types between models cause relationship errors and confusing audience results:
- Keep primary key types consistent across models — an
integerprimary key on the parent and abigintforeign key on a related model can cause join failures - Store timestamps as UTC timestamp or datetime types, not strings
- Cast nested or JSON fields upstream where practical — the audience builder works best with flat, typed columns
Decide what belongs upstream vs. in Hightouch
If logic is business-critical, reusable, or defines a core metric, put it upstream in your warehouse (as a materialized view, dbt model, or table). Hightouch traits and computed columns work well for activation-specific calculations, but they are not a substitute for core data modeling.
Build a presentation layer first
The most successful Customer Studio implementations start with a stable, marketer-friendly schema layer in the warehouse — a set of pre-joined, pre-aggregated models (for example, dbt marts) that are purpose-built for activation. This layer should flatten heavy joins, materialize expensive logic, and present clean, well-named columns so Customer Studio doesn't have to recompute them at query time.
As a rule of thumb: flatten and materialize heavy joins upstream. Large event tables should be partitioned or clustered by timestamp. The fewer expensive joins Customer Studio has to run at query time, the faster audience previews and syncs will be.
Keep parent models lean
Expose only the columns marketers need for filtering and sync field mappings. Move less-frequently used attributes into related models. A lean parent model makes the audience builder faster and easier to navigate.
Handle JSON and nested fields upstream
JSON and nested fields are supported in Customer Studio, but they work best when cast to flat, typed columns in your warehouse presentation layer. If you need to expose nested data, be explicit about the expected shape and document the structure for marketers.
Avoid common anti-patterns
- Wrong grain on the parent model. Setting the parent at household or account grain when you need to target individuals leads to audience count confusion and inability to personalize per user.
- Exposing too much of the warehouse. Only expose the tables and columns marketers actually need. A schema with 50 models and hundreds of columns makes the audience builder harder to use, not easier.
- Naming models after their sync destination. A parent model named
Braze user attributesmakes sense for one sync but confuses everyone when you add more destinations. Name models after the entity they represent. - Skipping join key validation. Test your relationships with a small audience before building production campaigns. A misconfigured join key silently produces wrong audience counts.
What's next?
Once you've planned your data model, configure it in Customer Studio:
- Define your schema Create parent, related, and event models, configure columns, and set up relationships.
- Create traits Build reusable calculated values marketers can use in audience filters and sync field mappings.