JourneysBranching

Branching

Branching tiles split a journey into multiple paths, letting you personalize the customer experience based on their attributes, behavior, or randomization. This page covers all branching strategies available in SignalSmith journeys.

Branch Types

SignalSmith supports three types of branches:

TypeUse CaseDeterministic?
ConditionRoute based on traits, events, or audience membershipYes — same data produces the same path
Percentage SplitA/B testing and holdout groupsYes — same customer ID always takes the same branch
RandomEqual distribution across N pathsYes — uses customer ID for consistent assignment

Condition Branches

Condition branches evaluate one or more rules and route the customer to the first matching branch. An else branch handles customers who match no conditions.

How Conditions Are Evaluated

Conditions are evaluated top-to-bottom at the moment the customer reaches the branch tile. The customer takes the first branch whose condition evaluates to true.

Branch Tile
├── Condition 1: lifetime_value > 500     → VIP Path
├── Condition 2: lifetime_value > 100     → Standard Path
└── Else (default)                        → Nurture Path

If a customer has a lifetime value of 300, they match Condition 2 and take the Standard Path. If their lifetime value is 600, they match Condition 1 and take the VIP Path. If their lifetime value is 50, they match neither and take the Else path.

Condition Types

Trait-Based Conditions

Evaluate a customer’s trait values using comparison operators:

OperatorDescriptionExample
equalsExact matchplan = "enterprise"
not_equalsNot equalstatus != "churned"
greater_thanNumeric greater thanlifetime_value > 500
less_thanNumeric less thandays_since_signup < 30
greater_than_or_equalNumeric >=engagement_score >= 80
less_than_or_equalNumeric <=support_tickets &lt;= 2
containsString containsemail contains "@company.com"
not_containsString does not containemail not_contains "test"
starts_withString prefix matchname starts_with "Dr."
is_setTrait has a value (not null)phone is_set
is_not_setTrait is null or missingphone is_not_set
inValue is in a listcountry in ["US", "CA", "UK"]
not_inValue is not in a listcountry not_in ["CN", "RU"]

Event-Based Conditions

Evaluate whether a customer has performed a specific event within a time window:

  • Has performedperformed "purchase" in last 7 days
  • Has not performednot performed "login" in last 30 days
  • Event countcount of "page_view" in last 24 hours > 5
  • Event propertylast "purchase" where amount > 100

Event conditions query the events store in real time at the moment of evaluation.

Audience-Based Conditions

Check whether a customer is a member of a specific audience:

  • Is member of — Customer is currently in the audience
  • Is not member of — Customer is not currently in the audience

This is useful for cross-referencing journey members against other segments (e.g., “Is this customer also in the ‘Enterprise Accounts’ audience?”).

Compound Conditions

You can combine multiple conditions within a single branch using AND/OR logic:

Branch 1: (lifetime_value > 500) AND (country in ["US", "CA"])
Branch 2: (lifetime_value > 500) AND (country NOT in ["US", "CA"])
Else: default path

Nested groups are supported for complex logic:

Branch 1: (plan = "enterprise") OR ((lifetime_value > 1000) AND (tenure_months > 12))

Percentage Splits

Percentage splits randomly assign customers to branches based on specified allocations. This is the primary mechanism for A/B testing within journeys.

Configuration

Define two or more branches, each with a percentage:

BranchPercentageUse
Branch A80%New email template
Branch B20%Control (existing template)

Percentages must sum to exactly 100%. You can define up to 10 branches.

How Assignment Works

Customer assignment is deterministic based on a hash of the customer ID and the branch tile ID. This means:

  • The same customer always takes the same branch, even if the journey is paused and resumed
  • If a customer re-enters the journey, they take the same branch again
  • Different branch tiles produce independent assignments (a customer in branch A of one split may be in branch B of another)

This determinism is important for A/B test integrity — you don’t want the same customer receiving both the test and control treatments.

Best Practices for A/B Testing

  • Use a control group — Always include a holdout group that receives the existing treatment for comparison
  • Track conversion per branch — Use different exit labels per branch to measure performance
  • Run for statistical significance — Allow enough customers through each branch before drawing conclusions
  • Avoid nesting percentage splits — Nested splits create complex interactions. Use a single multi-way split instead.

Time-Based Branches

Time-based branches route customers based on temporal conditions. While not a separate tile type, these are condition branches that use time-related traits or expressions.

Day of Week

Route customers based on the current day:

Branch 1: day_of_week in ["Saturday", "Sunday"] → Weekend messaging
Else: Weekday messaging

Time of Day

Route based on the customer’s local time (if timezone is available):

Branch 1: local_hour >= 9 AND local_hour < 17 → Business hours
Branch 2: local_hour >= 17 AND local_hour < 22 → Evening
Else: Overnight (perhaps skip or wait)

Relative Timing

Route based on how long the customer has been in the journey or since a specific event:

Branch 1: hours_since_entry < 24 → Fast responder
Else: Slow responder

Multi-Level Branching

You can chain branches to create decision trees:

Entry
  └── Branch (Country)
        ├── US
        │   └── Branch (LTV)
        │         ├── High → VIP US treatment
        │         └── Low → Standard US treatment
        ├── EU
        │   └── Branch (GDPR consent)
        │         ├── Consented → EU marketing
        │         └── Not consented → EU minimal
        └── Else
            └── Global default treatment

While powerful, deep nesting makes journeys harder to understand and maintain. Consider using sub-journeys to encapsulate complex branch trees.

Branch Analytics

Each branch tracks:

MetricDescription
Customers enteredTotal customers who took this branch
Percentage actualActual distribution (may differ slightly from configured percentage for small samples)
Conversion ratePercentage of customers who reached a “converted” exit tile
Average timeAverage time customers spend in this branch before exiting
Drop-offNumber of customers who exited via timeout or exit criteria rather than completing the branch

These metrics are available in the Execution & Monitoring dashboard and can be exported for deeper analysis.

Common Patterns

Win-Back with Escalation

Branch (Days inactive)
├── 7-14 days  → Gentle reminder email
├── 14-30 days → Stronger re-engagement with incentive
├── 30-60 days → Final attempt with large discount
└── 60+ days   → Mark as churned, exit

Channel Preference Routing

Branch (Preferred channel)
├── Email       → Send email
├── SMS         → Send SMS
├── Push        → Send push notification
└── Else        → Send email (default)

Geographic Personalization

Branch (Region)
├── North America → English content, USD pricing
├── Europe        → Localized content, EUR pricing, GDPR-compliant
├── APAC          → Localized content, time-zone adjusted sending
└── Else          → Global default content