Session limits & resume
Wall-clock caps, the ending-soon warning, and continuing a conversation in a new session.
Sessions don't run forever. A wall-clock cap protects you from runaway costs (a forgotten tab, a voicemail system that never hangs up) and lets the platform bound resources. The SDK tells you the effective cap, warns before it fires, and gives you a resume path when a conversation legitimately needs more time.
Setting a cap
The wire protocol accepts a requested cap per run (max_session_seconds, 60–14400). The server enforces the minimum of your request and its own limits — you can shorten a session, never extend one. Swift exposes the request directly:
var config = SessionConfig()
config.maxSessionSeconds = 900 // 15 minutesTypeScript and Python sessions currently run under the server's default cap. In every SDK, the effective value is reported on the ready event — read it from there rather than assuming a request was granted:
session.on('ready', ({ maxSessionSeconds }) => {
scheduleWrapUpTimer(maxSessionSeconds);
});case RealtimeReady():
print(f"cap: {event.max_session_seconds}s")The shutdown sequence
As the deadline approaches, the server pushes warnings, then ends the session:
session-ending-soon— carriesseconds_remainingand areasonslug. This is your window to have the agent wrap up naturally, save state, or offer continuation.session-ended— the server's deliberate goodbye, withreason(e.g.max_session_duration).- The stream finishes with the terminal session-ended item, as on every exit path.
A good voice UX treats session-ending-soon as a conversational event, not just a log line — inject a wrap-up cue via send_text or surface a "continue?" affordance in the UI.
Resuming a conversation
resume_session_id starts a new session that continues a prior one's conversation:
first = await agent.start()
# … session ends (cap, network, user closed the app) …
again = await agent.start(resume_session_id=first.session_id)
# the agent remembers the conversationUnder the hood the server does whichever is possible: native resumption when the upstream model session is still warm, or seeded continuation (replaying the transcript into a fresh model session) when it isn't. Either way the agent picks up with context; either way it does not re-speak its greeting — greetings belong to first contact.
resume_session_id is an experimental session param: it works today, but its shape may change without a protocol-version bump. Pin your SDK version if you build a core flow on it.
Resume is per-conversation continuity, not durable memory: it stitches one user's interrupted conversation back together. Long-term memory across days and sessions belongs in your own store, injected via instructions, a SessionStart hook, or session state capture.
Related limits
Wall-clock caps interact with the platform's metering: concurrent-session and usage limits are account-level and documented in Limits. Transport-level drops within a session's lifetime are a different topic — see Reconnects.