Skip to main content
Coding agents and chat apps send many requests that belong to one logical session — one conversation, one agent task. GoModel detects that session and uses it in two places:
  • Sticky load balancing — a load-balanced virtual model routes every request of a session to the target that served it first, which keeps provider prompt caches warm and model behavior consistent mid-conversation.
  • Sticky API-key selection — when one provider has several keys, every request in a detected session uses the same key, preserving provider prompt-cache affinity.
  • Threaded audit logs — the dashboard’s Audit Logs page groups a session’s requests into one thread: the latest request as the row, with an expander that unfolds the older requests beneath it.
Session keeping works with zero configuration. Defaults fit most setups; the options below exist for the rare cases they don’t.

How a session is identified

The first matching signal wins:
  1. Session headers — a built-in registry covers the headers known tools send, plus gateway conventions:
  2. Body fields — for clients that mark sessions in the request body: Anthropic metadata.user_id (Claude Code embeds its session UUID there, both current and legacy formats are parsed), session_id (OpenRouter convention), litellm_session_id, prompt_cache_key (Zed and other OpenAI clients that reuse a cache key per conversation), and /v1/responses conversation references.
  3. Automatic detection — chat and responses requests with no explicit signal are grouped by their conversation opening: the model, system context, tools, and the messages through the first user turn. Follow-up requests resend that prefix unchanged, so an agent that simply replays its history (Aider, Cline, Continue, …) still gets a stable session id (auto-…) with no client changes.
Body-based signals and automatic detection read request bodies up to 1 MiB (chunked requests included); larger bodies fall back to header signals. Client-provided session ids are scoped by user path, including UUID-shaped values, so one tenant cannot collide with another by reusing the same id.

Sticky load balancing

When a request carries a session and resolves through a virtual model with several targets, the first request picks a target via the redirect’s strategy (round_robin or cost) and later requests stick to it. If the pinned target becomes unavailable or saturated, the strategy picks again and the session re-pins — a session is never glued to a dead target, and the all-saturated honest-429 behavior is unchanged. Affinity is on by default and can be disabled per redirect:
The same flag is available in the dashboard’s virtual model editor (“Session keeping”) and on the admin API (session_affinity on PUT /admin/virtual-models). Pins are in-memory per instance (like rate-limit counters): after a restart or on another replica, the next request of a session simply re-pins. Idle sessions expire after 6 hours. API-key affinity is deterministic rather than stored, so the same ordered key set selects the same key across replicas and restarts. Disable it per provider with session_sticky_keys: false, <PROVIDER>[_SUFFIX]_SESSION_STICKY_KEYS=false, or the dashboard’s Session-sticky API keys checkbox. Requests with no detected session remain round robin.

Threaded audit logs

Audit entries record the session id (session_id), and the Audit Logs page groups them by default (“Group by session” toggle). Each thread shows its latest request with a count badge; the expander on the left unfolds the older requests. GET /admin/audit/sessions serves the thread list; GET /admin/audit/log?session_id=… returns one session’s entries.

Configuration

Everything is on by default.
Or in config.yaml:
Credential-bearing headers (Authorization, API-key headers, …) are rejected as session sources, since the session id is persisted on audit and usage records. When to change the defaults: set SESSION_AUTO_DETECT=false if you only want explicitly-tagged sessions grouped; set session_affinity: false on a redirect when you prefer strict load spreading over cache affinity (for example pure round-robin capacity balancing across identical deployments).
Last modified on August 1, 2026