Repository Public
1<br />23In the Live API, a session refers to a persistent connection where input and output are streamed continuously over the same connection (read more about[how it works](https://ai.google.dev/gemini-api/docs/live)). This unique session design enables low latency and supports unique features, but can also introduce challenges, like session time limits, and early termination. This guide covers strategies for overcoming the session management challenges that can arise when using the Live API.45## Session lifetime67Without compression, audio-only sessions are limited to 15 minutes, and audio-video sessions are limited to 2 minutes. Exceeding these limits will terminate the session (and therefore, the connection), but you can use[context window compression](https://ai.google.dev/gemini-api/docs/live-session#context-window-compression)to extend sessions to an unlimited amount of time.89The lifetime of a connection is limited as well, to around 10 minutes. When the connection terminates, the session terminates as well. In this case, you can configure a single session to stay active over multiple connections using[session resumption](https://ai.google.dev/gemini-api/docs/live-session#session-resumption). You'll also receive a[GoAway message](https://ai.google.dev/gemini-api/docs/live-session#goaway-message)before the connection ends, allowing you to take further actions.1011## Context window compression1213To enable longer sessions, and avoid abrupt connection termination, you can enable context window compression by setting the[contextWindowCompression](https://ai.google.dev/api/live#BidiGenerateContentSetup.FIELDS.ContextWindowCompressionConfig.BidiGenerateContentSetup.context_window_compression)field as part of the session configuration.1415In the[ContextWindowCompressionConfig](https://ai.google.dev/api/live#contextwindowcompressionconfig), you can configure a[sliding-window mechanism](https://ai.google.dev/api/live#ContextWindowCompressionConfig.FIELDS.ContextWindowCompressionConfig.SlidingWindow.ContextWindowCompressionConfig.sliding_window)and the[number of tokens](https://ai.google.dev/api/live#ContextWindowCompressionConfig.FIELDS.int64.ContextWindowCompressionConfig.trigger_tokens)that triggers compression. 1617### Python1819 from google.genai import types2021 config = types.LiveConnectConfig(22 response_modalities=["AUDIO"],23 context_window_compression=(24 # Configures compression with default parameters.25 types.ContextWindowCompressionConfig(26 sliding_window=types.SlidingWindow(),27 )28 ),29 )3031### JavaScript3233 const config = {34 responseModalities: [Modality.AUDIO],35 contextWindowCompression: { slidingWindow: {} }36 };3738## Session resumption3940To prevent session termination when the server periodically resets the WebSocket connection, configure the[sessionResumption](https://ai.google.dev/api/live#BidiGenerateContentSetup.FIELDS.SessionResumptionConfig.BidiGenerateContentSetup.session_resumption)field within the[setup configuration](https://ai.google.dev/api/live#BidiGenerateContentSetup).4142Passing this configuration causes the server to send[SessionResumptionUpdate](https://ai.google.dev/api/live#SessionResumptionUpdate)messages, which can be used to resume the session by passing the last resumption token as the[`SessionResumptionConfig.handle`](https://ai.google.dev/api/live#SessionResumptionConfig.FIELDS.string.SessionResumptionConfig.handle)of the subsequent connection.4344Resumption tokens are valid for 2 hr after the last sessions termination. 4546### Python4748 import asyncio49 from google import genai50 from google.genai import types5152 client = genai.Client()53 model = "gemini-2.5-flash-native-audio-preview-12-2025"5455 async def main():56 print(f"Connecting to the service with handle {previous_session_handle}...")57 async with client.aio.live.connect(58 model=model,59 config=types.LiveConnectConfig(60 response_modalities=["AUDIO"],61 session_resumption=types.SessionResumptionConfig(62 # The handle of the session to resume is passed here,63 # or else None to start a new session.64 handle=previous_session_handle65 ),66 ),67 ) as session:68 while True:69 await session.send_client_content(70 turns=types.Content(71 role="user", parts=[types.Part(text="Hello world!")]72 )73 )74 async for message in session.receive():75 # Periodically, the server will send update messages that may76 # contain a handle for the current state of the session.77 if message.session_resumption_update:78 update = message.session_resumption_update79 if update.resumable and update.new_handle:80 # The handle should be retained and linked to the session.81 return update.new_handle8283 # For the purposes of this example, placeholder input is continually fed84 # to the model. In non-sample code, the model inputs would come from85 # the user.86 if message.server_content and message.server_content.turn_complete:87 break8889 if __name__ == "__main__":90 asyncio.run(main())9192### JavaScript9394 import { GoogleGenAI, Modality } from '@google/genai';9596 const ai = new GoogleGenAI({});97 const model = 'gemini-2.5-flash-native-audio-preview-12-2025';9899 async function live() {100 const responseQueue = [];101102 async function waitMessage() {103 let done = false;104 let message = undefined;105 while (!done) {106 message = responseQueue.shift();107 if (message) {108 done = true;109 } else {110 await new Promise((resolve) => setTimeout(resolve, 100));111 }112 }113 return message;114 }115116 async function handleTurn() {117 const turns = [];118 let done = false;119 while (!done) {120 const message = await waitMessage();121 turns.push(message);122 if (message.serverContent && message.serverContent.turnComplete) {123 done = true;124 }125 }126 return turns;127 }128129 console.debug('Connecting to the service with handle %s...', previousSessionHandle)130 const session = await ai.live.connect({131 model: model,132 callbacks: {133 onopen: function () {134 console.debug('Opened');135 },136 onmessage: function (message) {137 responseQueue.push(message);138 },139 onerror: function (e) {140 console.debug('Error:', e.message);141 },142 onclose: function (e) {143 console.debug('Close:', e.reason);144 },145 },146 config: {147 responseModalities: [Modality.AUDIO],148 sessionResumption: { handle: previousSessionHandle }149 // The handle of the session to resume is passed here, or else null to start a new session.150 }151 });152153 const inputTurns = 'Hello how are you?';154 session.sendClientContent({ turns: inputTurns });155156 const turns = await handleTurn();157 for (const turn of turns) {158 if (turn.sessionResumptionUpdate) {159 if (turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle) {160 let newHandle = turn.sessionResumptionUpdate.newHandle161 // ...Store newHandle and start new session with this handle here162 }163 }164 }165166 session.close();167 }168169 async function main() {170 await live().catch((e) => console.error('got error', e));171 }172173 main();174175## Receiving a message before the session disconnects176177The server sends a[GoAway](https://ai.google.dev/api/live#GoAway)message that signals that the current connection will soon be terminated. This message includes the[timeLeft](https://ai.google.dev/api/live#GoAway.FIELDS.google.protobuf.Duration.GoAway.time_left), indicating the remaining time and lets you take further action before the connection will be terminated as ABORTED. 178179### Python180181 async for response in session.receive():182 if response.go_away is not None:183 # The connection will soon be terminated184 print(response.go_away.time_left)185186### JavaScript187188 const turns = await handleTurn();189190 for (const turn of turns) {191 if (turn.goAway) {192 console.debug('Time left: %s\n', turn.goAway.timeLeft);193 }194 }195196## Receiving a message when the generation is complete197198The server sends a[generationComplete](https://ai.google.dev/api/live#BidiGenerateContentServerContent.FIELDS.bool.BidiGenerateContentServerContent.generation_complete)message that signals that the model finished generating the response. 199200### Python201202 async for response in session.receive():203 if response.server_content.generation_complete is True:204 # The generation is complete205206### JavaScript207208 const turns = await handleTurn();209210 for (const turn of turns) {211 if (turn.serverContent && turn.serverContent.generationComplete) {212 // The generation is complete213 }214 }215216## What's next217218Explore more ways to work with the Live API in the full[Capabilities](https://ai.google.dev/gemini-api/docs/live)guide, the[Tool use](https://ai.google.dev/gemini-api/docs/live-tools)page, or the[Live API cookbook](https://colab.research.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_LiveAPI.ipynb).