Repository Public
1In the Live API, a session refers to a persistent2connection where input and output are streamed continuously over the same3connection (read more about [how it works](https://ai.google.dev/gemini-api/docs/live)).4This unique session design enables low latency and supports unique features, but5can also introduce challenges, like session time limits, and early termination.6This guide covers strategies for overcoming the session management challenges7that can arise when using the Live API.89## Session lifetime1011Without compression, audio-only sessions are limited to 15 minutes,12and audio-video sessions are limited to 2 minutes. Exceeding these limits13will terminate the session (and therefore, the connection), but you can use14[context window compression](https://ai.google.dev/gemini-api/docs/live-api/session-management#context-window-compression) to extend sessions to15an unlimited amount of time.1617The lifetime of a connection is limited as well, to around 10 minutes. When the18connection terminates, the session terminates as well. In this case, you can19configure a single session to stay active over multiple connections using20[session resumption](https://ai.google.dev/gemini-api/docs/live-api/session-management#session-resumption).21You'll also receive a [GoAway message](https://ai.google.dev/gemini-api/docs/live-api/session-management#goaway-message) before the22connection ends, allowing you to take further actions.2324## Context window compression2526To enable longer sessions, and avoid abrupt connection termination, you can27enable context window compression by setting the [contextWindowCompression](https://ai.google.dev/api/live#BidiGenerateContentSetup.FIELDS.ContextWindowCompressionConfig.BidiGenerateContentSetup.context_window_compression)28field as part of the session configuration.2930In the [ContextWindowCompressionConfig](https://ai.google.dev/api/live#contextwindowcompressionconfig), you can configure a31[sliding-window mechanism](https://ai.google.dev/api/live#ContextWindowCompressionConfig.FIELDS.ContextWindowCompressionConfig.SlidingWindow.ContextWindowCompressionConfig.sliding_window)32and the [number of tokens](https://ai.google.dev/api/live#ContextWindowCompressionConfig.FIELDS.int64.ContextWindowCompressionConfig.trigger_tokens)33that triggers compression.3435### Python3637 from google.genai import types3839 config = types.LiveConnectConfig(40 response_modalities=["AUDIO"],41 context_window_compression=(42 # Configures compression with default parameters.43 types.ContextWindowCompressionConfig(44 sliding_window=types.SlidingWindow(),45 )46 ),47 )4849### JavaScript5051 const config = {52 responseModalities: [Modality.AUDIO],53 contextWindowCompression: { slidingWindow: {} }54 };5556## Session resumption5758To prevent session termination when the server periodically resets the WebSocket59connection, configure the [sessionResumption](https://ai.google.dev/api/live#BidiGenerateContentSetup.FIELDS.SessionResumptionConfig.BidiGenerateContentSetup.session_resumption)60field within the [setup configuration](https://ai.google.dev/api/live#BidiGenerateContentSetup).6162Passing this configuration causes the63server to send [SessionResumptionUpdate](https://ai.google.dev/api/live#SessionResumptionUpdate)64messages, which can be used to resume the session by passing the last resumption65token as the [`SessionResumptionConfig.handle`](https://ai.google.dev/api/live#SessionResumptionConfig.FIELDS.string.SessionResumptionConfig.handle)66of the subsequent connection.6768Resumption tokens are valid for 2 hr after the last sessions termination.6970### Python7172 import asyncio73 from google import genai74 from google.genai import types7576 client = genai.Client()77 model = "gemini-3.8-live"7879 async def main():80 print(f"Connecting to the service with handle {previous_session_handle}...")81 async with client.aio.live.connect(82 model=model,83 config=types.LiveConnectConfig(84 response_modalities=["AUDIO"],85 session_resumption=types.SessionResumptionConfig(86 # The handle of the session to resume is passed here,87 # or else None to start a new session.88 handle=previous_session_handle89 ),90 ),91 ) as session:92 while True:93 await session.send_client_content(94 turns=types.Content(95 role="user", parts=[types.Part(text="Hello world!")]96 )97 )98 async for message in session.receive():99 # Periodically, the server will send update messages that may100 # contain a handle for the current state of the session.101 if message.session_resumption_update:102 update = message.session_resumption_update103 if update.resumable and update.new_handle:104 # The handle should be retained and linked to the session.105 return update.new_handle106107 # For the purposes of this example, placeholder input is continually fed108 # to the model. In non-sample code, the model inputs would come from109 # the user.110 if message.server_content and message.server_content.turn_complete:111 break112113 if __name__ == "__main__":114 asyncio.run(main())115116### JavaScript117118 import { GoogleGenAI, Modality } from '@google/genai';119120 const ai = new GoogleGenAI({});121 const model = 'gemini-3.8-live';122123 async function live() {124 const responseQueue = [];125126 async function waitMessage() {127 let done = false;128 let message = undefined;129 while (!done) {130 message = responseQueue.shift();131 if (message) {132 done = true;133 } else {134 await new Promise((resolve) => setTimeout(resolve, 100));135 }136 }137 return message;138 }139140 async function handleTurn() {141 const turns = [];142 let done = false;143 while (!done) {144 const message = await waitMessage();145 turns.push(message);146 if (message.serverContent && message.serverContent.turnComplete) {147 done = true;148 }149 }150 return turns;151 }152153 console.debug('Connecting to the service with handle %s...', previousSessionHandle)154 const session = await ai.live.connect({155 model: model,156 callbacks: {157 onopen: function () {158 console.debug('Opened');159 },160 onmessage: function (message) {161 responseQueue.push(message);162 },163 onerror: function (e) {164 console.debug('Error:', e.message);165 },166 onclose: function (e) {167 console.debug('Close:', e.reason);168 },169 },170 config: {171 responseModalities: [Modality.AUDIO],172 sessionResumption: { handle: previousSessionHandle }173 // The handle of the session to resume is passed here, or else null to start a new session.174 }175 });176177 const inputTurns = 'Hello how are you?';178 session.sendClientContent({ turns: inputTurns });179180 const turns = await handleTurn();181 for (const turn of turns) {182 if (turn.sessionResumptionUpdate) {183 if (turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle) {184 let newHandle = turn.sessionResumptionUpdate.newHandle185 // ...Store newHandle and start new session with this handle here186 }187 }188 }189190 session.close();191 }192193 async function main() {194 await live().catch((e) => console.error('got error', e));195 }196197 main();198199## Receiving a message before the session disconnects200201The server sends a [GoAway](https://ai.google.dev/api/live#GoAway) message that signals that the current202connection will soon be terminated. This message includes the [timeLeft](https://ai.google.dev/api/live#GoAway.FIELDS.google.protobuf.Duration.GoAway.time_left),203indicating the remaining time and lets you take further action before the204connection will be terminated as ABORTED.205206### Python207208 async for response in session.receive():209 if response.go_away is not None:210 # The connection will soon be terminated211 print(response.go_away.time_left)212213### JavaScript214215 const turns = await handleTurn();216217 for (const turn of turns) {218 if (turn.goAway) {219 console.debug('Time left: %s\n', turn.goAway.timeLeft);220 }221 }222223## Receiving a message when the generation is complete224225The server sends a [generationComplete](https://ai.google.dev/api/live#BidiGenerateContentServerContent.FIELDS.bool.BidiGenerateContentServerContent.generation_complete)226message that signals that the model finished generating the response.227228### Python229230 async for response in session.receive():231 if response.server_content.generation_complete is True:232 # The generation is complete233234### JavaScript235236 const turns = await handleTurn();237238 for (const turn of turns) {239 if (turn.serverContent && turn.serverContent.generationComplete) {240 // The generation is complete241 }242 }243244## What's next245246Explore more ways to work with the Live API in the full247[Capabilities](https://ai.google.dev/gemini-api/docs/live) guide,248the [Tool use](https://ai.google.dev/gemini-api/docs/live-tools) page, or the249[Live API cookbook](https://colab.research.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_LiveAPI.ipynb).