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

# Sticky sessions

> We support session persistence (AKA sticky sessions) with a customizable TTL, defaulting to 15 minutes.

## Using sticky sessions

| Key        | Value                                                                                                                                                                          | TTL                                                  | Examples         |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- | ---------------- |
| session    | Any unique identifier of up to 255 characters (regardless of character encoding); Massive will make best efforts to route requests in the same session to the same egress node | Default: 15 minutes (customizable with `sessionttl`) | session42, 1234  |
| sessionttl | Customizable session TTL in minutes, up to 240 minutes                                                                                                                         | Default: 15 minutes                                  | 30, 60, 120, 240 |

You can inject a session identifier, like a unique representation of your app or active task, to specify that multiple requests should originate from a single egress node (if available):

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-37:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

### Session TTL Behavior

* Session TTL defaults to 15 minutes but can be customized using the `sessionttl` parameter up to 240 minutes (4 hours).
* **Important**: Sessions use static TTL - they expire at creation time + TTL and are not extended by subsequent requests.
* For example, to set the TTL to 30 minutes:

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-37-sessionttl-30:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

### Session Rotation

When a session identifier is specified and found, the server will perform a request via the same node unless:

* TTL is expired (sessions expire exactly at creation time + TTL)
* The request limit per minute for the node is exceeded (only for strict mode)
* The node has gone offline (except in norotate mode)
* Error limit is reached (in flex mode)

If the session identifier is not found or the conditions above are not met, a new session is created with the specified ID and attached to a new node.

## Session Modes

| Key         | Value                        | Description                         |
| ----------- | ---------------------------- | ----------------------------------- |
| sessionmode | `strict`, `flex`, `norotate` | Controls session behavior on errors |

### Strict Mode (Default)

By default, sessions operate in **strict mode** where any error immediately invalidates the session and triggers rotation to a new node. This ensures clean IP rotation on failures but may change IPs more frequently.

Example of using undefined `sessionmode`, which defaults to `sessionmode-strict`:

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-123:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

Example with `sessionmode-strict` explicitly defined:

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-123-sessionmode-strict:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

### Flex Mode

Sessions can operate in **flex mode** where sessions persist through errors up to a configurable limit. In this mode:

* Sessions continue through errors up to the error limit (default: 15)
* Error count resets to 0 on successful requests
* Provides better IP stability during transient failures
* May retry failing nodes multiple times

<Info>
  **Note:** The default error limit is 15. After 15 consecutive errors, a new node is assigned to the sticky session. You can customize this with the `sessionerr` parameter.
</Info>

Example with `sessionmode-flex`:

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-123-sessionmode-flex:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

### No-Rotate Mode

Sessions can operate in **norotate mode** where node errors cause immediate failure instead of rotation. This is useful when IP consistency is critical and you would rather fail than silently switch IPs. Note that TTL expiry still creates a new session (same as other modes).

* Returns **502** on tunnel errors (node responds with an error) or **503** when the node has gone offline
* The `sessionerr` parameter is ignored in norotate mode — any error fails immediately

<Warning>
  **Consistent auth strings required:** Session parameters (including `sessionmode`) are re-parsed from the auth string on every request. If you omit `sessionmode-norotate` on a subsequent request using the same session ID, the session silently falls back to **strict** mode and may rotate to a new node on failure. Always include `sessionmode-norotate` in every request for the session.
</Warning>

Example with `sessionmode-norotate`:

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-123-sessionmode-norotate:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

## Additional Parameters

| Key        | Value          | Description                                             | Default |
| ---------- | -------------- | ------------------------------------------------------- | ------- |
| sessionerr | Number (1-100) | Maximum consecutive errors before rotation in flex mode | 15      |

### Customizing Error Limit

In flex mode, you can customize how many errors are allowed before rotation:

```bash theme={null}
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-session-123-sessionmode-flex-sessionerr-5:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
```

This example allows up to 5 consecutive errors before rotating to a new node.

## Best Practices

1. **Plan TTL appropriately**: Since sessions use static TTL (not extended by activity), set an appropriate duration for your use case
2. **Choose the right mode**: Default strict mode ensures immediate rotation on any error; use flex mode if you need IP stability; use norotate mode if you need IP consistency on node errors (TTL expiry still rotates)
3. **Monitor error rates**: Adjust `sessionerr` based on your tolerance for retries (default is 15)
4. **Session ID naming**: Use descriptive session IDs to help with debugging and monitoring

<Accordion title="Advanced: Parameter Timing and Mutability">
  ### Parameters Applied at Session Creation/Rotation Only

  The following parameters are only applied when a session is created or rotated, not on existing sessions:

  * `sessionttl` - TTL duration
  * `sessionerr` - Error limit for flex mode
  * Geographic parameters (`subdivision`, `zipcode`, etc.)

  This means changing these parameters on subsequent requests with the same session ID will have no effect until the session rotates to a new node.

  ### Parameters Re-parsed on Every Request

  `sessionmode` is evaluated on every request, not just at session creation (see the [norotate warning](#no-rotate-mode) above).

  ### Session-Breaking Parameters

  <Warning>
    **Critical**: Changing `country` or `city` parameters creates a NEW session with a different identity, breaking session continuity. These are part of the session token itself.
  </Warning>

  Unlike other parameters that are ignored until rotation, `country` and `city` are part of the session's unique identifier. Changing them creates an entirely different session:

  ```bash theme={null}
  # First request creates session with US/NewYork
  curl -x https://network.joinmassive.com:65535 \
       -U '{PROXY_USERNAME}-session-test-country-US-city-NewYork:{API_KEY}' \
       https://cloudflare.com/cdn-cgi/trace

  # This creates a DIFFERENT session - not the same as above!
  curl -x https://network.joinmassive.com:65535 \
       -U '{PROXY_USERNAME}-session-test-country-US-city-LosAngeles:{API_KEY}' \
       https://cloudflare.com/cdn-cgi/trace
  ```

  ### Parameters Always Processed

  Some parameters are processed on every request regardless of session state:

  * `subaccount` - For billing and tracking
  * `httpredirect` - For HTTP to HTTPS redirect behavior

  These parameters take effect immediately on each request.
</Accordion>
