Streaks Overview
This guide explains how Phoenix streaks are modeled so you can design engagement mechanics before touching the Admin API. It focuses on the configuration shape you submit when creating a streak definition.
1. Mental Model
- Streak – a named engagement tracker scoped to a tenant. Each streak owns a configuration document that defines which events qualify, what condition must be met within each time window, and what rewards unlock at milestones.
- Time window – the period during which a user must satisfy the streak condition (e.g., daily, weekly, rolling 24-hour). Missing a window resets the consecutive count to zero.
- User streak – an individual user's progress for a specific streak definition, including their consecutive count and current window progress.
Once a configuration is active, every ingested event is evaluated against its rules. Matching events update the user's window progress; when the window condition is satisfied, the consecutive count increments.
2. Lifecycle & Status
| Status | Meaning | Typical Use |
|---|---|---|
active | Streak is processing events and tracking user progress normally. | Default after creation. |
paused | Frozen state—no window advancement, no breaks, no event processing. | Maintenance windows or holiday pauses. |
archived | Soft delete—no processing, but historical data preserved for reporting. | Sunset legacy streaks without losing user data. |
Switching back to active re-enables processing immediately for future events.
3. Configuration Snapshot
Every streak config follows this top-level structure:
{
"event_types": ["user.login"],
"expression": null,
"window": {
"type": "calendar",
"period": "daily",
"timezone": "America/New_York",
"reset_time": "00:00"
},
"condition": {
"type": "count",
"min": 1
},
"milestones": [
{ "threshold": 7, "reward_item_id": null, "repeatable": false },
{ "threshold": 30, "reward_item_id": "a1b2c3d4-...", "repeatable": false }
],
"at_risk_seconds": 3600
}Each section is detailed below.
4. Event Types & Filtering
Event Types
Specify which events count toward the streak. Supports exact matches and wildcard patterns:
"user.login"– exact match"game.*"– matchesgame.started,game.completed, etc."*"– matches all events (use with caution)
Expression Filters (Optional)
For advanced filtering, add an expression that evaluates event attributes:
{
"expression": {
"and": [
{
"condition": {
"field": "attrs.platform",
"operator": "eq",
"value": "mobile"
}
},
{
"condition": {
"field": "attrs.session_duration",
"operator": "gte",
"value": 300
}
}
]
}
}Supported operators:
- Equality:
eq,ne - Comparison:
gt,gte,lt,lte - Membership:
in,not_in - Existence:
exists - Text:
contains,starts_with,ends_with
If expression is omitted or null, all events matching the event_types qualify.
5. Time Windows
| Type | Description | Configuration Fields |
|---|---|---|
calendar | Fixed boundaries aligned to calendar periods (daily/weekly/monthly). | period, timezone, reset_time |
rolling | Sliding window from the user's last qualifying activity. | duration_seconds |
Calendar Windows
{
"type": "calendar",
"period": "daily",
"timezone": "UTC",
"reset_time": "00:00"
}period:daily,weekly, ormonthlytimezone: IANA timezone (e.g.,America/Los_Angeles,Europe/London)reset_time: Time of day when windows reset (HH:MM format)
Weekly windows reset on Sunday; monthly windows reset on the 1st.
Rolling Windows
{
"type": "rolling",
"duration_seconds": 86400
}Rolling windows give users flexibility—they have 24 hours (or your configured duration) from their last qualifying event to satisfy the next window.
6. Window Conditions
The condition defines what a user must accomplish within each window to maintain their streak.
| Type | Description | Example Use Case |
|---|---|---|
count | Number of qualifying events | "Log in at least once per day" |
sum | Sum of a numeric field across events | "Earn 100 points per week" |
distinct | Count of unique values in a field | "Play 3 different game modes" |
Count Condition
{
"type": "count",
"min": 1
}Sum Condition
{
"type": "sum",
"field": "attrs.points_earned",
"min": 100
}Distinct Condition
{
"type": "distinct",
"field": "attrs.game_mode",
"min": 3
}7. Milestones & Rewards
Milestones unlock when a user reaches specific consecutive streak counts:
{
"milestones": [
{ "threshold": 7, "reward_item_id": null, "repeatable": false },
{
"threshold": 30,
"reward_item_id": "uuid-of-reward-item",
"repeatable": false
},
{
"threshold": 100,
"reward_item_id": "uuid-of-special-reward",
"repeatable": true
}
]
}| Field | Description |
|---|---|
threshold | Consecutive count required to unlock (must be positive) |
reward_item_id | Optional UUID linking to your rewards system |
repeatable | If true, milestone can be earned again after the streak breaks |
When a user hits a milestone, Phoenix emits a streak.milestone_reached event that your systems can consume to grant rewards.
8. At-Risk Notifications
The optional at_risk_seconds field triggers a warning before a window closes:
{
"at_risk_seconds": 3600
}When the window is about to end and the user hasn't satisfied the condition, Phoenix emits a streak.at_risk event. Use this to send push notifications encouraging users to complete their streak before it breaks.
9. Streak Events
Phoenix emits real-time events as streaks progress:
| Event Type | When It Fires |
|---|---|
streak.incremented | User satisfied the window condition; count increased |
streak.broken | Window closed without condition satisfied; count reset |
streak.milestone_reached | User hit a milestone threshold |
streak.at_risk | Window ending soon without condition satisfied |
Subscribe to these events via NATS to trigger notifications, update UIs, or sync with external systems.
10. Best Practices Checklist
- Choose window types that match user behavior—daily for habitual actions, weekly for larger commitments.
- Start with simple
countconditions before addingsumordistinctcomplexity. - Use meaningful milestone thresholds (7, 14, 30, 100) that feel achievable yet rewarding.
- Configure
at_risk_secondsto give users enough time to react (1–4 hours before window close). - Test streak configurations in a staging tenant with short windows before production.
- Document each streak's purpose for your support and marketing teams.
With these concepts in mind, proceed to Create Streak for API-specific instructions on provisioning streak definitions.
Querying Results
Use the Query Gateway to pull leaderboard standings for UI surfaces, analytics, or partner APIs. This guide covers the REST endpoints, authentication, pagination, window selection, and historical snapshots.
Create Streaks
This guide teaches you how to provision, update, and retire streak definitions via the Admin Gateway. It assumes you already understand the configuration model from `streak-overview.md`.