Skip to main content
Attributes store the current state of users, devices, and events. Understanding when to use attributes vs events is critical for building an effective data model that supports both analytics and personalization.

What are Attributes?

Attributes are facts that describe who a user is, what device they’re on, or what happened in an event. Think of them as the labels on a record — name, email, plan type, device model, event revenue. While events are verbs (actions), attributes are adjectives (descriptions).

The Simple Definition

If you can describe it as “This user IS X” or “This event HAS property Y,” it’s an attribute. Examples:
  • “Sarah’s email is sarah@example.com” → User attribute: email
  • “John’s plan type is Enterprise” → User attribute: plan_type
  • “This device is an iPhone 15 Pro on iOS 17” → Device attribute: model, os_version
  • “This purchase had revenue of $89.99” → Event property: revenue

Why Attributes Matter

Attributes are essential because they enable:
  1. Personalization: "Hi {{name}}, your {{plan}} trial expires in {{days_remaining}} days"
  2. Targeting: Send campaigns only to users matching specific criteria
  3. Context: Understand who’s behind each event (“This purchase was from an Enterprise customer”)
  4. Enrichment: Connect user data from your CRM, support system, or other tools
  5. Current state queries: “How many Pro plan users do we have right now?”

The Key Difference: State vs Action

Attributes store current state (one value that changes over time):
  • User’s current email: sarah@example.com → changes if they update it
  • User’s current plan: pro → changes when they upgrade to enterprise
  • Last login date: 2026-05-04 → updates every time they log in
Events record actions (immutable history):
  • Event: Updated Email at 2026-01-15 → never changes, always part of history
  • Event: Upgraded Plan at 2026-03-20 → permanent record of this action
  • Event: Logged In at 2026-05-04 10:30:15 → specific moment captured
The rule: Use attributes when you need to know “what IS true about this user right now.” Use events when you need to know “what DID this user do.”

Real-World Example

Sarah’s user attributes:
Sarah’s event history:
Notice:
  • Attributes show her current state: She’s enterprise now (not pro)
  • Events show her complete history: We can see she upgraded on March 20th
  • Together they give the full picture: Who she is + What she’s done

Attributes vs Events: The Data Modeling Decision

Events = Actions (verbs) → user.track('Upgraded Plan')
Attributes = State (adjectives) → user.plan_type = 'enterprise'

The Rule

Use attributes when:
  • You need current state: “What plan are they on right now?”
  • You need to personalize: "Hi {{name}}, your trial ends {{trial_ends_at}}"
  • It’s a fact about the user: Demographics, account info, preferences
Use events when:
  • You need to trigger workflows: “When user upgrades → send thank-you email”
  • You need analytics: “How many users upgraded this month?”
  • You need history: “When did they last log in?”
  • It’s an action: Clicked, viewed, purchased, upgraded

Common Mistake: Tracking State as Events

❌ Wrong:
Why it’s wrong: These are state updates, not user actions. You’re creating noise in your event stream. ✅ Right:
Why it’s right: Attribute stores current state for queries and personalization. Event records the action for analytics and workflow triggers.

Three Types of Attributes

1. User Attributes

User attributes are facts stored on the user profile, identified by user_id. They come in two kinds: system-defined fields (always present, set by the platform) and traits (custom key-value data you send via identify() or setProfileAttributes()).

System-Defined Fields

These fields exist on every user profile automatically:

Traits (Custom Attributes)

Anything you pass in traits via identify() or via setProfileAttributes() is stored as a custom trait and merged with existing data:
Traits are schema-less — you define the keys. All trait keys are automatically catalogued for use in queries and targeting.

2. Device Attributes

Device attributes are facts stored on a device record, identified by device_id (derived from the push token). Like user attributes, they split into system-defined fields and custom traits.

System-Defined Fields

Traits (Custom Attributes)

Custom key-value data you attach to a specific device:
Use cases:
  • Target specific app versions: “Send ‘Update Available’ push to devices on v1.x”
  • Platform-specific campaigns: “iOS-only feature announcement”
  • Notification category filtering

3. Event Properties

Event properties are the custom key-value pairs attached to individual events. Unlike user or device attributes (which describe current state), event properties are immutable — they record the details of a specific moment in time.

Anatomy of an Event with Properties

System-Defined Event Fields

Every event has these fields set automatically:

Custom Properties

The properties object is fully custom — you define the keys and values:
All property keys are automatically catalogued for use in queries and campaign conditions. Note: Event properties live on the event record (with their own retention), not on the user profile. User attributes store current state; event properties describe that specific action.

Automatic Attribute Discovery

Zixflow automatically learns what attributes exist based on the data you send - no need to define a schema upfront.

How It Works

You track an event with properties:
Zixflow automatically:
  1. Discovers all the property names (order_id, product_name, revenue, etc.)
  2. Figures out their data types (order_id is text, revenue is a number)
  3. Makes them available for querying and filtering
Now you can:
  • Segment: “Users who purchased where product_name = ‘Enterprise Plan’”
  • Analyze: “Top 10 products by revenue”
  • Filter: “Show events where payment_method = ‘credit_card’”
Benefits:No schema setup — Just start tracking, Zixflow learns automatically
Self-documenting — See what attributes you’re actually using
Type checking — Zixflow warns if data types don’t match
Easy filtering — All attributes available for querying

Reserved Attribute Names

These attribute names are reserved for system use. Don’t use them as custom attributes: User-level:
  • id, workspace_id, user_id, email, anonymous_id
  • created_at, updated_at, last_seen_at
Device-level:
  • device_id, device_token, platform, last_seen_at
If you try to set a reserved attribute:
  • System logs a warning
  • Value is ignored (not written)
  • Original system value preserved

Next: Understand how events flow through Zixflow → The Data Journey