Learn how to think about Appizer's event-driven architecture and data model.
Core Concepts
Events Are Everything
In Appizer, everything is an event. User actions, system events, and custom metrics are all tracked as events.
// User action
appizer.track({ event: 'button_clicked', userId: 'user_123' })
// System event
appizer.track({ event: 'payment_processed', userId: 'user_123' })
// Custom metric
appizer.track({ event: 'api_latency', properties: { ms: 145 } })
Users Are Identities
Users are identified by a unique ID and can have traits (properties) attached to them.
appizer.identify({
userId: 'user_123',
traits: {
email: 'user@example.com',
plan: 'pro',
signupDate: '2024-01-15'
}
})
Key Principle: One user can have multiple identities (anonymous → authenticated) that get merged.
Properties Add Context
Events and users can have properties that add context for segmentation and analysis.
appizer.track({
event: 'purchase_completed',
userId: 'user_123',
properties: {
amount: 99.99,
currency: 'USD',
product: 'Pro Plan',
paymentMethod: 'credit_card'
}
})
Data Flow Mental Model
Think of Appizer as a pipeline:
Capture
Events are captured from your application via SDK or API
Process
Events are validated, enriched, and stored in real-time
Analyze
Events become queryable data for analytics and segmentation
Act
Use analytics to trigger actions (notifications, campaigns)
Identity Resolution
Anonymous Users
Before a user signs up, track them with an anonymous ID:
const anonymousId = generateUUID()
appizer.track({
event: 'page_view',
anonymousId: anonymousId,
properties: { page: '/pricing' }
})
Identified Users
When a user signs up, identify them:
appizer.identify({
userId: 'user_123',
traits: {
email: 'user@example.com',
name: 'John Doe'
}
})
Aliasing
Link the anonymous ID to the user ID:
appizer.alias({
userId: 'user_123',
previousId: anonymousId
})
Result: All anonymous events are now attributed to user_123.
Event Properties vs User Traits
Event Properties
- Temporary: Specific to that event occurrence
- Variable: Can change with each event
- Example: Purchase amount, page URL, button name
appizer.track({
event: 'page_view',
properties: {
page: '/products',
referrer: 'google.com',
loadTime: 1.2
}
})
User Traits
- Persistent: Stored on the user profile
- Stable: Represent user characteristics
- Example: Email, plan, signup date
appizer.identify({
userId: 'user_123',
traits: {
email: 'user@example.com',
plan: 'enterprise',
industry: 'technology'
}
})
Segmentation Mental Model
Think of segments as dynamic groups based on conditions:
// Segment: High-value users
{
filters: [
{ property: 'plan', operator: 'equals', value: 'enterprise' },
{ property: 'totalSpent', operator: 'greaterThan', value: 1000 }
]
}
Segments update in real-time as user traits and events change.
Time-Based Thinking
Event Timestamps
Every event has a timestamp (auto-generated or custom):
appizer.track({
event: 'purchase',
userId: 'user_123',
timestamp: '2024-01-15T10:30:00Z' // Optional
})
Time Windows
Analytics queries use time windows:
appizer.analytics.query({
startDate: '2024-01-01',
endDate: '2024-01-31',
event: 'purchase'
})
Best Practices
Think in Events, Not Pages
Instead of: "Track page views"
Think: "Track user journey events"
// Good: Specific events
appizer.track({ event: 'pricing_page_viewed' })
appizer.track({ event: 'demo_requested' })
appizer.track({ event: 'trial_started' })
// Less useful: Generic page views
appizer.track({ event: 'page_view', properties: { url: '/pricing' } })
Properties Should Be Queryable
Only include properties you'll use for segmentation or analysis:
// Good: Queryable properties
appizer.track({
event: 'purchase',
properties: {
amount: 99.99,
plan: 'pro',
billingCycle: 'annual'
}
})
// Avoid: Non-queryable data
appizer.track({
event: 'purchase',
properties: {
fullTransactionLog: '...' // Too detailed
}
})
User Traits Should Be Stable
Update traits when they change, not on every event:
// Good: Update when changed
appizer.identify({
userId: 'user_123',
traits: { plan: 'enterprise' } // User upgraded
})
// Avoid: Redundant updates
appizer.identify({
userId: 'user_123',
traits: { email: 'same@email.com' } // No change
})
Common Patterns
Funnel Tracking
Track each step of a conversion funnel:
appizer.track({ event: 'funnel_step_1_viewed' })
appizer.track({ event: 'funnel_step_2_started' })
appizer.track({ event: 'funnel_step_3_completed' })
Feature Usage
Track feature adoption and usage:
appizer.track({
event: 'feature_used',
properties: {
feature: 'advanced_analytics',
action: 'report_generated'
}
})
Error Tracking
Track errors for monitoring:
appizer.track({
event: 'error_occurred',
properties: {
errorType: 'ValidationError',
errorMessage: 'Invalid email format',
context: 'signup_form'
}
})