Skip to content

Targeting Rules

Targeting rules determine which users receive which flag value at evaluation time. Each rule is a constraint evaluated against the context attributes you provide at runtime.

How Targeting Works

When an SDK evaluates a flag, it processes in this order:

  1. Flag enabled? — if the flag (or strategy) is disabled, return false
  2. Context constraints — all must match (AND logic)
  3. Segments — at least one must match (OR logic)
  4. If both constraints and segments are present — either passing grants access (OR)
  5. Percentage rollout — deterministic distribution via MurmurHash32
  6. Default — if nothing is configured, return false
flowchart TD
    Start[Start evaluation] --> CheckEnabled{Flag enabled?}
    CheckEnabled -->|No| ReturnFalse[Return false]
    CheckEnabled -->|Yes| HasConstraints{Constraints present?}
    HasConstraints -->|Yes| EvalConstraints[Evaluate all constraints<br/>AND logic]
    HasConstraints -->|No| HasSegments{Segments present?}
    EvalConstraints --> ConstraintsOk{All match?}
    ConstraintsOk -->|No| HasSegments
    ConstraintsOk -->|Yes| Rollout[Percentage rollout]
    HasSegments -->|Yes| EvalSegments[Evaluate segments<br/>OR logic]
    HasSegments -->|No| Rollout
    EvalSegments --> SegmentsOk{Any segment matches?}
    SegmentsOk -->|No| ConstraintsOk
    SegmentsOk -->|Yes| Rollout
    Rollout --> ReturnTrue[Return true]

Context Attributes

The evaluation context is a set of key-value pairs your application sends at runtime. All values are strings.

AttributeExampleDescription
userId"user-12345"Unique user identifier (used for rollout hashing)
sessionId"sess-abc"Session identifier (fallback for rollout hashing)
country"DE"ISO 3166 country code
plan"enterprise"Subscription tier
appVersion"2.4.1"Application version (semver comparison)

Providing Context

Java:

java
MozhnoContext context = MozhnoContext.builder()
    .userId("user-12345")
    .addProperty("country", "DE")
    .addProperty("plan", "enterprise")
    .build();

boolean enabled = client.isEnabled("premium_features", context);

JavaScript:

js
const context = {
  userId: "user-12345",
  country: "DE",
  plan: "enterprise",
};

const enabled = client.isEnabled("premium_features", context);

Constraint Operators

Each constraint compares a context field against one or more values using an operator:

OperatorDescriptionExample
inValue is in a listcountry in ["DE", "FR", "ES"]
not_inValue is NOT in a listcountry not_in ["US", "CA"]
eqEqual (numeric for contextType: number)plan eq "enterprise"
neNot equalplan ne "free"
gtGreater thanappVersion gt "2.0.0"
gteGreater than or equalage gte "18"
ltLess thanpriority lt "5"
lteLess than or equalretries lte "3"
containsSubstring matchemail contains "@example.com"

Context Types

The contextType determines how values are compared:

TypeComparisonExample
string (default)String comparisoncountry in ["DE"]
numberNumeric (double)age gte "18"
timeISO8601 datetimeeventDate gt "2026-01-01T00:00:00Z"
semverSemantic versioningappVersion gte "2.1.0"

Semantic version comparison correctly handles "2.10.0" > "2.9.0".

Combining Constraints

Within a single strategy, all constraints use AND logic — every constraint must match for the flag to be enabled:

json
{
  "constraints": [
    {"field": "country", "operator": "in", "values": ["DE", "FR"]},
    {"field": "plan", "operator": "eq", "values": ["enterprise"]}
  ]
}

This means: country is DE or FR AND plan is enterprise.

Multiple constraints on the same (field, operator) are merged — any matching value passes that constraint (OR within a constraint group).

Using Segments in Targeting

A segment is a reusable set of constraints. Reference segments in a strategy rather than repeating rules:

  • Within a segment: All constraints must match (AND logic)
  • Across segments: At least one segment must match (OR logic)
  • Constraints + segments: Either passing grants access (OR between them)

Tip: Segments are evaluated at flag evaluation time against the provided context. Changes to a segment immediately affect all flags that reference it.

Percentage Rollout

When percentage rollout is configured:

hash = MurmurHash32(flagKey + userId) % 100
if hash < percentage → enabled

The same user always gets the same result for the same flag. If userId is absent, sessionId is used instead. 100% rollout enables the flag for everyone; 0% disables it.

Next Steps

Released under the AGPL v3.0 License.