Bug Description
InMemoryMemoryService stores sessions in a process-global dictionary without isolating concurrent agent runs. When two agents run in parallel within the same Python process (e.g., during evals or parallel test suites), their session state intermixes, causing cross-contamination of conversation history.
Steps to Reproduce
import asyncio
from google.adk.sessions import InMemoryMemoryService
memory = InMemoryMemoryService()
async def run_agent_once(session_id, user_id):
# Create session, add events, read them back
session = await memory.create_session(
app_name="test", user_id=user_id, session_id=session_id
)
await memory.append_event(session, ...)
return await memory.get_session(...)
# Run two agents concurrently
async def main():
results = await asyncio.gather(
run_agent_once("session-1", "user-a"),
run_agent_once("session-2", "user-b"),
)
Expected Behavior
Each session should be fully isolated. Concurrent reads/writes to different session IDs should not interfere with each other.
Actual Behavior
Because InMemoryMemoryService uses a plain dict for storage (no locking or per-session copy-on-write), concurrent writes to different sessions can race on dict rehashing or key collisions. More critically, state inserted by one agent's session may be visible to another if they accidentally share a session ID or if the memory service doesn't enforce user-scoped isolation.
Impact
- Eval suites running agents in parallel produce flaky, non-deterministic results
- Session data leaks between users in multi-tenant deployments
- Debugging is extremely difficult — the bug only manifests under concurrency
Proposed Fix
Add asyncio.Lock per session ID, or use an asyncio-safe store like a ContextVar-scoped dict. Consider a warning in the InMemoryMemoryService docstring that it is not safe for concurrent use.
Bug Description
InMemoryMemoryServicestores sessions in a process-global dictionary without isolating concurrent agent runs. When two agents run in parallel within the same Python process (e.g., during evals or parallel test suites), their session state intermixes, causing cross-contamination of conversation history.Steps to Reproduce
Expected Behavior
Each session should be fully isolated. Concurrent reads/writes to different session IDs should not interfere with each other.
Actual Behavior
Because
InMemoryMemoryServiceuses a plaindictfor storage (no locking or per-session copy-on-write), concurrent writes to different sessions can race on dict rehashing or key collisions. More critically, state inserted by one agent's session may be visible to another if they accidentally share a session ID or if the memory service doesn't enforce user-scoped isolation.Impact
Proposed Fix
Add
asyncio.Lockper session ID, or use anasyncio-safe store like aContextVar-scoped dict. Consider a warning in the InMemoryMemoryService docstring that it is not safe for concurrent use.