> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inworld.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Traffic Splitting

> Split traffic across multiple model variants

Routers allow you to distribute traffic across different model variants within a route based on percentage weights. This is ideal for A/B testing, gradual migrations, or splitting traffic across multiple providers.

## How it Works

Routes are defined directly on the Router. Within each route, you can define multiple **variants** with weights. When a route is selected (either through conditional routing or as the default route), the router selects a variant based on weights.

**Important**: Weights must sum to exactly 100 within each route. They are not normalized - each route's variants are weighted independently. For example, if Route A has variants with weights \[70, 30] and Route B has variants with weights \[80, 20], these are independent - Route A's weights don't affect Route B's weights.

### Example Configuration

```bash theme={"system"}
curl --request POST \
  --url https://api.inworld.ai/router/v1/routers \
  --header 'Authorization: Basic <your-api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "routers/ab-test-router",
    "routes": [
      {
        "route": {
          "route_id": "ab-test-route",
          "variants": [
            {
              "variant": {
                "variant_id": "variant-a",
                "model_id": "openai/gpt-5"
              },
              "weight": 80
            },
            {
              "variant": {
                "variant_id": "variant-b",
                "model_id": "anthropic/claude-opus-4-6"
              },
              "weight": 20
            }
          ]
        },
        "condition": {
          "cel_expression": "true"
        }
      }
    ],
    "defaultRoute": {
      "route_id": "default",
      "variants": [
        {
          "variant": {
            "variant_id": "default-variant",
            "model_id": "openai/gpt-5"
          },
          "weight": 100
        }
      ]
    }
  }'
```

<Note>
  Model IDs are specified as strings in the format `"provider/model"` (e.g., `"openai/gpt-5"`).
</Note>

<Warning>
  **Weights must sum to exactly 100 within each route.** They are not normalized and are independent per route. For example:

  * Route 1 with variants \[70, 30] ✓ (sums to 100)
  * Route 2 with variants \[80, 20] ✓ (sums to 100)
  * Route 1 with variants \[70, 20] ✗ (sums to 90, will fail validation)

  Each route's weights are calculated independently - a weight of 70 in one route does not relate to weights in other routes.
</Warning>

## User Stickiness

If you specify a `user` field in your request, the router ensures the same user always gets the same variant (sticky routing):

```bash theme={"system"}
curl --request POST \
  --url https://api.inworld.ai/v1/chat/completions \
  --header 'Authorization: Bearer <your-api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "inworld/ab-test-router",
    "messages": [{"role": "user", "content": "Hello"}],
    "user": "user-123"
  }'
```

## Use Cases

### 1. A/B Testing

Send 90% of traffic to your stable model (GPT-5) and 10% to a new candidate (Claude Opus 4) to compare performance and user satisfaction in production.

### 2. Provider Redundancy

Split traffic 50/50 between two different providers of the same model (e.g., Llama 3 on Groq vs. Llama 3 on Together AI) to mitigate provider-specific rate limits.

### 3. Gradual Migration

When moving to a new model version, start with a 1% weight and slowly increase it as you verify the new model's output quality.

### 4. Conditional Weighted Routing

Combine conditional routing with weighted variants to route based on metadata, then split traffic within that route:

```json theme={"system"}
{
  "route": {
    "route_id": "premium-tier",
    "variants": [
      {
        "variant": {
          "variant_id": "gpt5",
          "model_id": "openai/gpt-5"
        },
        "weight": 70
      },
      {
        "variant": {
          "variant_id": "claude",
          "model_id": "anthropic/claude-opus-4-6"
        },
        "weight": 30
      }
    ]
  },
  "condition": {
    "cel_expression": "tier == \"premium\""
  }
}
```

See [Conditional Routing](/router/capabilities/conditional-routing) for more details on using CEL expressions.
