Skip to content

Race condition: background compaction causes stale session ValueError on next request #5194

@thequantumquirk

Description

@thequantumquirk

Description

When EventsCompactionConfig is enabled on an App, the compaction runs as a fire-and-forget asyncio.create_task at the end of each invocation in runners.py (line ~436):

asyncio.create_task(
    _run_compaction_for_sliding_window(
        self.app, session, self.session_service
    )
)

This causes a race condition with DatabaseSessionService.append_event, which checks:

if storage_session.update_timestamp_tz > session.last_update_time:
    raise ValueError("The last_update_time provided in the session object ... is earlier than the update_time in the storage_session ... Please check if it is a stale session.")

Steps to reproduce

  1. Configure an App with EventsCompactionConfig and use DatabaseSessionService
  2. Send enough messages to trigger compaction (compaction_interval invocations)
  3. Send the next message shortly after compaction fires

What happens

  1. Agent finishes a turn → all events appended → session.last_update_time set to DB's update_time (e.g. 14:26:43)
  2. Compaction fires as background task → calls session_service.append_event() for the summary event → DB update_time becomes 14:26:51
  3. Next user message arrives → runner uses same in-memory session object with last_update_time = 14:26:43
  4. append_event fails the stale check: 14:26:51 > 14:26:43ValueError

The background task updates the DB timestamp but the in-memory session object is never refreshed.

Expected behavior

Compaction should not cause subsequent requests to fail. Either:

  • The compaction task should update session.last_update_time after its DB write (it does via line 687, but the caller's reference to the session may already be stale by the time the next request picks it up)
  • Or the session should be re-fetched from DB at the start of each invocation
  • Or the stale check should account for compaction events

Environment

  • google-adk==1.18.0
  • DatabaseSessionService (PostgreSQL)
  • Python 3.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions