Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

Dev guideRecipesAPI ReferenceChangelog
Dev guideAPI ReferenceRecipesChangelogUser GuideGitHubDev CommunityOptimizely AcademySubmit a ticketLog In
Dev guide

Agent notifications

Optimizely Agent provides an endpoint that sends notifications to subscribers using Server-Sent Events. This is Agent's equivalent of Notification Listeners found in the Optimizely Feature Experimentation SDKs.

For details on the notification types, what causes them to be triggered, and the data they provide, see Set up notification listener documentation for the Go SDK.

Configuration

By default, the notifications endpoint is disabled. To enable it, update theconfig.yaml file.

# config.yaml
api:
    enableNotifications: true

Or, enable it by configuring an environment variable.

# set an env. variable
export OPTIMIZELY_API_ENABLENOTIFICATIONS=1

Usage

Send a GET request to /v1/notifications/event-stream to subscribe.

curl -N -H "Accept:text/event-stream" -H "X-Optimizely-Sdk-Key:<YOUR SDK KEY>"\
  http://localhost:8080/v1/notifications/event-stream

This connection remains open, and any notifications triggered by other requests received by Agent are pushed as events to this stream. Try sending requests to /v1/activate or /v1/track to see notifications being triggered.

Filter query parameter

To subscribe only to a particular category of notifications, add a filter query parameter. For example, to subscribe only to Decision notifications

# filter on decision notifications
curl -N -H "Accept:text/event-stream" -H "X-Optimizely-Sdk-Key:<YOUR SDK KEY>"\
  http://localhost:8080/v1/notifications/event-stream?filter=decision

When the Agent is operating in High Availability (HA) mode, you need to enable notification sync to get notifications from the nodes in an HA configuration. A PubSub system (Redis) is now used to ensure consistent retrieval of notification events across all nodes in an HA configuration.

The following is an example of how you can enable the notification sync with Redis:

## synchronization should be enabled when features for multiple nodes like notification streaming are deployed
synchronization:
    pubsub:
        redis:
            host: "localhost:6379"
            password: ""
            database: 0
    ## if notification synchronization is enabled, then the active notification event-stream API
    ## will get the notifications from available replicas
    notification:
        enable: true
        default: "redis"

Example

For a runnable Python example, see examples/notifications.py in GitHub.

Notification sync: Redis Streams vs Redis Pub/Sub

High Availability mode

When the Agent is operating in High Availability (HA) mode, you need to enable notification sync to get notifications from all nodes in an HA configuration. Agent uses Redis to ensure consistent retrieval of notification events across all nodes.

Agent automatically detects your Redis version and chooses the best notification system:

  • Redis >= 5.0 – Uses Redis Streams (persistent, batched delivery with acknowledgment).
  • Redis < 5.0 – Uses Redis Pub/Sub (simple, fire-and-forget).
  • Detection fails – Falls back to Redis Pub/Sub (safe default).

Configuration

## synchronization should be enabled when features for multiple nodes like notification streaming are deployed
synchronization:
    pubsub:
        redis:
            host: "localhost:6379"
            auth_token: ""  # Use auth_token, redis_secret, or password
            database: 0

            ## Optional: Redis Streams tuning (only applies if Redis >= 5.0 detected)
            ## Uncomment to override defaults. Leave commented for recommended defaults.
            # batch_size: 10           # Messages per batch (default: 10)
            # flush_interval: 5s       # Max wait before sending batch (default: 5s)
            # max_retries: 3           # Retry attempts on failure (default: 3)
            # retry_delay: 100ms       # Initial retry delay (default: 100ms)
            # max_retry_delay: 5s      # Max retry delay with backoff (default: 5s)
            # connection_timeout: 10s  # Redis connection timeout (default: 10s)

    ## if notification synchronization is enabled, then the active notification event-stream API
    ## will get the notifications from available replicas
    notification:
        enable: true
        default: "redis"  # Agent auto-detects best option based on Redis version

What happens at startup

Agent connects to Redis, runs INFO server command, and checks Redis version:

  • Redis 7.x, 6.x, 5.x → Uses Redis Streams
  • Redis 4.x, 3.x, 2.x → Uses Redis Pub/Sub
  • Detection fails → Falls back to Redis Pub/Sub (still works, just simpler)

Log examples

Redis Streams detected:

INFO Auto-detecting Redis version to choose best notification implementation...
INFO Redis Streams supported - will use Streams for notifications redis_version=6

Redis Pub/Sub fallback:

INFO Auto-detecting Redis version to choose best notification implementation...
INFO Redis Streams not supported - will use Pub/Sub for notifications redis_version=4 min_required=5

Notification sync: Redis Streams and Redis Pub/Sub

Agent automatically chooses between two Redis notification systems based on your Redis version:

FeatureRedis Pub/SubRedis Streams
DeliveryFire-and-forgetPersistent with acknowledgment
Message lossPossible if subscriber offlineNo loss (messages queued)
Consumer groupsNoYes (load balancing)
Automatic retriesNoYes (with exponential backoff)
Message batchingNoYes (configurable)
Redis version2.0+ required5.0+ required
SelectionAuto-detected (< 5.0)Auto-detected (>= 5.0)
Best forSimple, low-traffic setupsProduction, high-traffic deployments

Recommendation

Use Redis 5.0+ for production deployments requiring reliable message delivery. Agent will automatically use Redis Streams for optimal performance.

How auto-detection works

When Agent starts with default: "redis" configured, the following occurs:

  1. Connects to Redis using provided host and credentials.
  2. Runs version check using INFO server command.
  3. Parses version (for example, redis_version:6.2.5).
  4. Chooses implementation
    • Major version >= 5 → Redis Streams.
    • Major version < 5 → Redis Pub/Sub.
    • Detection fails → Redis Pub/Sub (safe fallback).

No configuration changes needed when upgrading Redis

  • Upgrade Redis 4.x → 6.x
  • Restart Agent
  • Automatically switches to Streams (no config change needed!)

Redis Streams configuration options

Basic setup (recommended for most users)

synchronization:
  pubsub:
    redis:
      host: "localhost:6379"
      auth_token: "your-redis-token"
      database: 0

  notification:
    enable: true
    default: "redis"  # Auto-detects and uses Streams if Redis >= 5.0

With custom tuning (optional)

If you need to tune performance for your traffic patterns, you can override these defaults:

synchronization:
  pubsub:
    redis:
      host: "localhost:6379"
      auth_token: "your-redis-token"
      database: 0

      # All parameters below are OPTIONAL - only set if you need to override defaults
      # These only apply when Agent detects Redis >= 5.0 (Streams mode)
      batch_size: 10           # How many messages to group together (default: 10)
      flush_interval: 5s       # Max time to wait before sending batch (default: 5s)
      max_retries: 3           # Number of retry attempts on failure (default: 3)
      retry_delay: 100ms       # Initial retry wait time (default: 100ms)
      max_retry_delay: 5s      # Maximum retry wait time (default: 5s)
      connection_timeout: 10s  # Redis connection timeout (default: 10s)

  notification:
    enable: true
    default: "redis"

📘

Note

These batching parameters are ignored if Agent detects Redis < 5.0 (Pub/Sub mode). Pub/Sub doesn't support batching.

If using notifications API (/v1/notifications/event-stream), in the server section of config.yaml increase these timeouts to prevent SSE disconnects:

readTimeout: 5s -> readTimeout: 300s (or appropriate higher value) writeTimeout: 10s -> readTimeout: 300s (or appropriate higher value)

How batching works (Redis Streams only)

When Agent detects Redis >= 5.0 and uses Streams, it groups notifications into batches for efficiency.

Without batching (Redis Pub/Sub - Redis < 5.0)

Decision 1 → PUBLISH immediately
Decision 2 → PUBLISH immediately
Decision 3 → PUBLISH immediately

With batching (Redis Streams - Redis >= 5.0)

Decision 1 → Add to batch (wait)
Decision 2 → Add to batch (wait)
Decision 3 → Add to batch (wait)
... 10 decisions collected OR 5 seconds elapsed ...
→ XADD all 10 messages to stream at once
📘

Note

Each message is still stored individually in the stream. Batching only affects the write operation to Redis, not the message structure. Subscribers read messages one at a time.

Notification message structure

When subscribers read from the stream, each notification contains a type and message payload.

Decision notification (triggered by /v1/decide)

{
  "type": "decision",
  "message": {
    "Type": "flag",
    "UserContext": {
      "ID": "user_123",
      "Attributes": {}
    },
    "DecisionInfo": {
      "flagKey": "my_flag",
      "enabled": true,
      "variationKey": "variation_a",
      "ruleKey": "experiment_123",
      "experimentId": "12345",
      "variationId": "67890",
      "variables": {
        "color": "blue",
        "size": "large"
      },
      "reasons": [
        "User \"user_123\" meets audience conditions."
      ]
    }
  }
}

Track notification** (triggered by /v1/track)

{
  "type": "track",
  "message": {
    "Type": "track",
    "UserContext": {
      "ID": "user_123",
      "Attributes": {
        "browser": "chrome"
      }
    },
    "EventInfo": {
      "eventKey": "purchase",
      "tags": {
        "revenue": 4200,
        "category": "electronics"
      }
    }
  }
}

Datafile update notification** (triggered by webhook or polling)

{
  "type": "datafile-update",
  "message": {
    "Type": "datafile-update",
    "Revision": "42",
    "ProjectId": "123456789"
  }
}

All notification types are synced across Agent instances when Redis is enabled.

Authentication options

Agent supports flexible Redis authentication field names (to avoid triggering security scanners).

redis:
  host: "localhost:6379"
  # Choose ONE of these (in order of priority):
  auth_token: "token123"      # Recommended (highest priority)
  # OR
  redis_secret: "secret456"   # Alternative field name
  # OR
  password: "pass789"         # Legacy field name (still supported)

Environment variables (fallback)

  • REDIS_PASSWORD – General fallback
  • REDIS_PUBSUB_PASSWORD – Sync-specific

Requirements

  • Redis Streams (auto-selected) – Requires Redis 5.0 or later.
  • Redis Pub/Sub (auto-fallback) – Works with Redis 2.0+.

Performance tuning guide

📘

Note

These tuning parameters only apply when Agent detects Redis >= 5.0 (Streams mode).

Low-latency (quick decisions, low volume)

batch_size: 5
flush_interval: 500ms

Messages sent faster but more frequent Redis writes.

High-throughput (many decisions, can tolerate slight delay)

batch_size: 100
flush_interval: 5s

Fewer Redis writes, better throughput, but notifications delayed up to 5 seconds.

Balanced (default - recommended for most cases)

# Just use defaults - donnot specify these parameters.
# batch_size: 10
# flush_interval: 5s

Upgrade Redis version

When you upgrade your Redis server (for example, from Redis 4.x to Redis 6.x), Agent automatically switches to using Redis Streams on the next restart.

Advanced configuration

For detailed information on Redis Streams including monitoring, troubleshooting, and migration from Redis Pub/Sub, see docs/redis-streams.md in the Agent GitHub repository.