Concurrent sessions

A session is one model call in flight: from the moment odnoga admits it to the moment the response is finished. It is not a user, not an API key and not a request per minute — ten thousand calls a day that never overlap use one session.

Your organisation has a pool of them. Every workspace draws from the same pool.


The two ceilings, and which one bit

There are exactly two, and the lower one binds:

CeilingWhat it isWhere it comes from
Organisation poolEvery in-flight call across all your workspacesYour plan, plus any sessions you bought or were granted
Workspace limitIn-flight calls in one workspaceOptional. Unset means the workspace shares the whole pool

A workspace limit can never be set above the pool — it is a way of stopping one workspace starving the others, not a way of getting more.

Both are on every successful response, so you never have to discover them through failures:

x-ratelimit-limit-concurrency: 16
x-ratelimit-remaining-concurrency: 11
x-ratelimit-limit-concurrency-tenant: 100
x-ratelimit-remaining-concurrency-tenant: 74

The -tenant pair appears when your workspace draws on a shared organisation pool.


What happens at the ceiling

By default odnoga does not break your product to protect its own ceiling. A call past your pool is served, and the response tells you:

HTTP/1.1 200
x-odnoga-pool-exceeded: 1
x-odnoga-pool-exceeded-scope: tenant
Warning: 199 - "Served over your concurrent session ceiling of 16. Nothing was refused.
                Add sessions under Finance if this is normal for you."

Treat that header as a signal, not an error: nothing failed, and nothing extra was charged. It means you are regularly running wider than what you pay for, and it is worth either slowing the client or adding sessions. Your organisation's admins see the same thing counted per day under Finance → Concurrent sessions, and are emailed the first time it happens each day.

If you would rather be refused than served over your ceiling — a hard budget, a regulated workload — ask support to enforce it for your organisation, and you will get the 429 below instead.

When a call is refused

A refused call is rejected before any vendor is contacted, so you are never charged for it:

HTTP/1.1 429
Retry-After: 2
{ "error": { "type": "rate_limit_error",
             "code": "tenant_concurrency_limit",
             "message": "All 16 concurrent sessions in your organisation are in use…" } }

The code tells you which ceiling bound, and the two need opposite responses:

codeWhat it meansWhat to do
workspace_concurrency_limitThis workspace's own allocation is full, and the organisation has roomRaise or remove the workspace allocation
tenant_concurrency_limitThe whole organisation is fullSlow down, or add sessions
capacity_unavailableodnoga is at capacity, not youRetry after the Retry-After. Nothing on your side will fix it, and nothing you buy will either.

The message names which of your workspaces is holding the sessions, so a noisy neighbour is visible rather than something to guess at.


Sizing a worker pool

Don't guess and don't discover the limit through 429s. Read it once at startup and cap your own concurrency one below it:

const r = await fetch(`${API_HOST}/functions/v1/airouter-native/v1/messages`, { … });
const limit = Number(r.headers.get('x-ratelimit-limit-concurrency-tenant')
                  ?? r.headers.get('x-ratelimit-limit-concurrency'));
const workers = Math.max(1, limit - 1);   // leave one for interactive traffic

The MCP tool account.limits returns both ceilings with live in-flight counts, so an agent can pace itself without a probe request.

Two things that are not concurrency, and have their own limits: requests per minute and tokens per minute. A 429 with code: "rpm" or "tpm" means those — adding sessions will not help.


How many you have, and getting more

Tenant admin → Finance → Concurrent sessions shows the pool, what each workspace is using, the busiest moment in the last 30 days, and where each session came from: included with your plan, granted by odnoga, or purchased.

Look at the busiest moment before buying. If you peak at 5 of 100 you have a routing or batching problem, not a capacity one, and more sessions will change nothing. If you peak at your ceiling and see tenant_concurrency_limit in your logs, buying is the fix.

Extra sessions are added to your existing odnoga subscription as a per-unit line, prorated by Stripe — no second invoice, and you can remove them the same way.


What a session is not a promise of

The pool is an entitlement on a shared platform, not reserved hardware — the same model as every cloud you already use. It means your organisation may run up to that many calls at once; it does not reserve machines that sit idle when you do not. odnoga holds itself to a published contention policy and keeps capacity ahead of demand. capacity_unavailable is what you see in the rare case that stops being true — it is a ceiling odnoga keeps on itself so one caller cannot take the platform down for everybody else, and it is the one limit no setting relaxes.

If your workload genuinely cannot tolerate contention — a regulated batch window, a contractual latency floor — ask about guaranteed sessions. Those are reserved one-for-one, priced accordingly, and never oversubscribed.


Related