Connect by JBRH Open Connect

Session resumption

A session is the model's side of a live call, and it can end while the call is still up: the server sends a going-away notice, a process restarts, a connection drops. Session resumption reconnects and hands the model back the conversation it already had, so the caller hears a pause instead of a new voice asking who they are. Connect uses it on the realtime voice path.

Status
Reference What this means
Audience
both, developer
Channels
phone
In the app
#/calls
Last verified
Product version
6.3.2

What ends a session nobody hung up#

A realtime speech-to-speech API holds one long-lived bidirectional connection per call. That connection is not the call. The telephone leg can be perfectly healthy while the model's session ends underneath it, and the four usual reasons have nothing to do with the caller.

CauseWhat the client seesIs the audio still up?
The provider is draining or rebalancing a hostA going-away frame, sometimes with a grace periodYes — the caller is still there
The session's own duration capA close at a fixed elapsed timeYes
Accumulated context exceeded what the session may carryA close, or an error on the next turnYes
The network droppedA socket error with no frame at allYes

In every one of those the correct behaviour is the same, and it is not retrying the request: there is no request to retry, there is a conversation to continue. That is what separates resumption from the ordinary retry of a failed HTTP call.

What a resumption handle carries#

A provider that supports resumption issues the client an opaque handle during the session and refreshes it as the conversation grows. On reconnect the client presents the handle instead of a fresh system prompt, and the server restores the state the handle points at.

Carried
The conversation turns the server had already committed — what the caller said, what the model said back, and any notes the client injected as context.
Usually carried
The system instructions and the tool definitions, because they were part of the session the handle names.
Not carried
Audio in flight at the moment of the cut. A half-spoken sentence is gone, and the model may say the whole thing again.
Not carried
Anything the client held only in its own memory — a turn clock, a pending timer, a watchdog — which the client has to rebuild itself.

Does Connect use session resumption?#

Used, on the realtime engine. Before it, a long call was cut at the provider's session limit and the ending was attributed to nobody in particular. Session resumption together with a sliding-window context compression lets the plugin reconnect when the server says it is going away and carry the conversation over, so the session cap became the session's problem rather than the call's.

The ceiling a caller can actually reach is Connect's own: MAX_CALL_SECONDS, thirty minutes. That number is a product decision about how long a business wants an automated line held open, not a limit inherited from a model.

Resumption is not the only reconnection rule on that path. A model session that refuses to *start* is opened once more on the same model and once on the fallback model before the call is given up, and model_session_restarted goes on the call record, so a review can see that a restart happened rather than infer it from a gap.

The turn-based carrier path has no session to resume. There the unit of work is one webhook, and the protections are different: a request a call cannot lose is retried through a deploy restart or a proxy 502, and a 4xx is treated as an answer and never retried.

Reconnecting changes what the bill looks like#

One call can hold several sessions. Cost metering that reads only the session it happens to be holding at the end will bill the survivor and silently forget the rest — which is what happened here until merge_usage was written to add every session a call held. The arithmetic matters because a live call is billed on audio tokens at roughly four times the same model's text rate on input, so a half-forgotten session is not a rounding error.

The same applies to duration. A call that reports no tokens at all — a session that died before reporting anything is one way to get there — is still charged from its own wall-clock duration at the published per-minute rate, never at zero.

What resumption does not fix#

  • The pause is real. Reconnecting takes time, and a caller mid-sentence hears silence. Carrying state back does not make the gap disappear.
  • Repetition at the seam. The last committed turn is what comes back, so a sentence that was being spoken when the cut happened may be restarted.
  • Client-side state. Presence tracking, the response watchdog and the language tracker live in the worker, not in the session, and have to be re-established or they resume in the wrong state.
  • A refused session. Resumption assumes there was a session. A model that will not open one at all is a different failure, handled by the fallback rule rather than by a handle.

Questions#

Does the caller know the session was resumed?

Only as a pause. There is no announcement and no second greeting — the point of carrying the conversation is that the voice picks up knowing who it is talking to and what has been agreed. The event is recorded on the call so a later review can attribute a long gap correctly instead of blaming latency.

Is a resumed call charged twice?

No. Usage from every session a call held is merged into one figure for that call. The failure worth knowing about is the opposite one: before merging existed, only the last session's usage was counted, so a reconnect made a call look cheaper than it was.

Can a call outlive the model's session limit?

Yes, on the realtime engine — that is the reason resumption is there. The limit a caller meets is the thirty-minute product ceiling, not the model's session length.