--- title: "Google ADK memory: sessions, state and Memory Bank" description: "Google ADK offers session state, MemoryService and Vertex AI Memory Bank. What each stores, and how to add temporal memory through a function tool." canonical: https://past.dev/integrations/google-adk last-updated: 2026-10-17 --- # Add memory to Google ADK agents Source: https://past.dev/integrations/google-adk Google ADK separates session state from memory. State is a key-value scratchpad with user and app scope prefixes. MemoryService is a searchable cross-session archive, and Vertex AI Memory Bank implements it with LLM-extracted user memories. A function tool that calls past.dev over HTTP adds timestamped source ingestion and grouped recall documents with dated excerpts. ## Google ADK memory scope The [Agent Development Kit](https://adk.dev/) documents short-term and long-term layers separately. [Session state](https://adk.dev/sessions/state/) is a key-value scratchpad with scope prefixes: unprefixed keys belong to the current session, `user:` keys follow a `user_id` across sessions, `app:` keys are shared across users, and `temp:` keys are discarded when the invocation ends. Whether state persists depends on the configured session service. [MemoryService](https://adk.dev/sessions/memory/) is the long-term layer: a searchable archive drawing on many past sessions, exposed to agents through the `load_memory` and `preload_memory` tools. Documented implementations are `InMemoryMemoryService` (keyword matching, no persistence), `VertexAiMemoryBankService`, and `VertexAiRagMemoryService` (vector retrieval over stored conversations). Memory operates per user, keyed by `user_id` and `app_name`. - State is a plain key-value map. Writing `user:plan` replaces the value, so it holds the current plan and no record of previous plans. - Memory is scoped to one user in one app. A fact that concerns a whole team has no documented home beyond `app:` state, which is again a key-value map. - Neither state nor the memory interface documents event-time fields, validity windows or supersession links. ## Memory Bank, and what a temporal store adds [Memory Bank](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/memory-bank/overview) is the managed option on Vertex AI Agent Engine. It uses generative models to extract memories from conversations, stores long-term user preferences and facts, consolidates related memories, and returns them to the agent in later sessions. For a per-user personalization layer inside Google Cloud, that is the documented path. past.dev covers a different shape of requirement. Ingest accepts the source's original timestamp, stable id, author identity, and audience slug. Recall requires an identity and returns ranked documents with occurrence dates and source excerpts. past.dev runs as a managed service or, on an Enterprise agreement, in your own cloud. | Dimension | Memory Bank (documented) | past.dev | | --- | --- | --- | | Stored unit | LLM-generated memories: user preferences and facts | Facts with event time, validity windows and supersession links | | Scope | Per user and app | Per project key, shared by any agent that holds it | | Updates | Related memories are consolidated | Superseded fact closed; both values stay queryable | | Recall result | Fetched memories | Grouped documents with dates and source excerpts | | Deployment | Managed on Vertex AI Agent Engine | Managed, or [your own cloud](/enterprise) on an Enterprise agreement | ## The integration: two function tools, two endpoints ADK wraps a plain Python function as a `FunctionTool` when you add it to an agent's `tools` list, building the declaration from the signature, type hints and docstring ([function tools](https://adk.dev/tools-custom/function-tools/)). A parameter typed `ToolContext` is injected by ADK and kept out of the declaration the model sees. Its `user_id` is the `user_id` that your application passes to `runner.run_async`. So the integration is two functions that call past.dev over HTTP. ```python import os, requests from google.adk.tools import ToolContext BASE = "https://api.past.dev/api/v1" HEADERS = {"Authorization": f"Bearer {os.environ['PAST_API_KEY']}"} def remember_fact(text: str, happened_at: str, tool_context: ToolContext) -> dict: """Store timestamped source text, readable by the whole project, authored by the current user.""" return requests.post(f"{BASE}/ingest", headers=HEADERS, json={ "content": text, "timestamp": happened_at, "identity": tool_context.user_id, }).json() def recall_memory(question: str, tool_context: ToolContext) -> dict: """Return ranked documents with source excerpts for the current user.""" return requests.post(f"{BASE}/recall", headers=HEADERS, json={ "query": question, "identity": tool_context.user_id, }).json() ``` Add `remember_fact` and `recall_memory` to the `tools` list and cover them in the agent's instruction: store durable facts with their original timestamps, recall before answering questions about people, decisions or history. Run the agent with the signed-in user's id as `user_id`. > **Identity** > > The application sets the identity. The model never chooses it. Recall returns what the identity in the request may read, so take the identity from the signed-in user in code, and keep it out of every value that the model fills. Recall returns ranked documents with dates and source excerpts. The application decides whether those documents support an answer, contain a disagreement, or are insufficient; HTTP failures are handled separately. ## Or connect the MCP server ADK's `McpToolset` connects to a remote server with `StreamableHTTPConnectionParams` from `google.adk.tools.mcp_tool.mcp_session_manager`, and goes into the agent's `tools` list ([MCP tools](https://adk.dev/tools-custom/mcp-tools/)). The project's end-user MCP server then gives the agent `recall`, `answer` and `who_am_i`, plus `remember` while the project's write toggle is on, with no tool code to write. 1. Turn on the project's end-user MCP server on **Build › MCP server** in the console. 2. Mint an access link there, or with the account server's `create_mcp_access_link` tool. The link has the form `https://api.past.dev/mcp//link/`. It is one URL that is one identity, and the server answers it with no sign-in step. 3. Keep the link in a secret store, such as the `PAST_MCP_URL` environment variable that the code below reads. The secret in its path is the credential. ```python import os from google.adk.agents import LlmAgent from google.adk.tools.mcp_tool import McpToolset from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams root_agent = LlmAgent( model=model, # any model ADK supports name="assistant", instruction="Call recall before you answer questions about people, decisions or history.", tools=[ McpToolset( connection_params=StreamableHTTPConnectionParams(url=os.environ["PAST_MCP_URL"]), ), ], ) ``` Every call through the link runs as its identity, with that identity's audiences. Mint one link per install, so that a revoked link stops one agent only. When the agent serves several people, mint one link per end user, and connect each request with the link of the user who makes it. Never share one link between users. `remember` writes to the identity's own private audience, and only that identity recalls it. Send data that the whole project must recall through the ingest call. The [end-user server documentation](/docs/mcp/serving-your-own-users) describes the tools, the links and revocation. ## Choosing per requirement - Scratchpad for the current task: session state, with `temp:` for values that should end with the invocation. - Per-user personalization memories inside Google Cloud: Memory Bank through `VertexAiMemoryBankService`. - Timestamped source history, ranked documents with dated source excerpts, identity scoping, or a deployment you host yourself: the function tool above. The [quickstart](/docs/memory-api/quickstart) shows how to ingest, wait until ingestion completes, and recall. The [benchmarks](/benchmarks) document how recall is measured. [Facts that change over time](/guides/facts-that-change-over-time) covers the general temporal model in depth. ## Frequently asked questions ### What is the difference between ADK session state and Memory Bank? Session state is a key-value scratchpad for the current conversation, with user and app prefixes for wider scope. Memory Bank is a managed Vertex AI service that extracts long-term user memories from conversations and makes them searchable across sessions. ### Do I need Vertex AI to add memory to a Google ADK agent? No. ADK function tools are plain Python functions, so an agent can call any HTTP memory service. Memory Bank is one documented option and runs on Google Cloud; an external memory API works from any deployment. ### Can a Google ADK agent remember what was true on a past date? Session state and memory retrieval return present values. A temporal memory API keeps validity windows and superseded values, so the agent can ask what was true on a specific date and cite dated evidence. ## Related - [Memory for the OpenAI Agents SDK](https://past.dev/integrations/openai-agents-sdk) - [Memory for the Vercel AI SDK](https://past.dev/integrations/vercel-ai-sdk) - [Memory for LangGraph](https://past.dev/integrations/langgraph) - [Event time](https://past.dev/glossary/event-time) - [Memory for Strands Agents](https://past.dev/integrations/strands-agents) - [Quickstart](https://past.dev/docs/memory-api/quickstart)