Skip to content

Runner._get_or_create_session loads all events ignoring EventsCompactionConfig, causing linear performance degradation #4673

Closed

Description

@rusherman

Describe the bug

When EventsCompactionConfig is configured on an App, the compaction mechanism correctly summarizes old events and appends compaction events to the session. However, Runner._get_or_create_session still calls get_session without any GetSessionConfig, loading the full event history on every invocation.

This means compaction only reduces the LLM context window — it does nothing to reduce the session loading overhead. As conversations grow longer, get_session latency degrades linearly, even though compaction has already produced summaries that could make the old raw events unnecessary for the Runner.

The architectural disconnect

EventsCompactionConfig (configured on App)
    → Compacts events for LLM context ✅
    → Does NOT reduce get_session load ❌

Runner._get_or_create_session (runners.py L375)
    → Calls get_session() WITHOUT GetSessionConfig
    → Loads ALL events every time
    → Latency grows linearly with conversation length

The GetSessionConfig class already supports num_recent_events and after_timestamp filtering, and all session service implementations (InMemorySessionService, DatabaseSessionService, VertexAiSessionService) honor these parameters. But the Runner never uses them.

To Reproduce

  1. Create an App with EventsCompactionConfig:
app = App(
    name="my_app",
    root_agent=agent,
    events_compaction_config=EventsCompactionConfig(
        compaction_interval=5,
        overlap_size=1,
        summarizer=LlmEventSummarizer(llm=my_llm),
    ),
)
  1. Use DatabaseSessionService (PostgreSQL) or any persistent session service
  2. Have a multi-turn conversation (10+ rounds)
  3. Observe that get_session becomes progressively slower on each new invocation

Real-world numbers

In our production setup with a 6-stage sequential pipeline agent (Science Navigator), each conversation turn generates ~480 events (streaming chunks, tool calls, tool responses, text finals). After 10 turns:

  • ~4,800 events accumulated per session
  • get_session takes 70+ seconds (via HttpSessionService → PostgreSQL DatabaseSessionService)
  • Compaction events exist in the session but the Runner still loads all 4,800 raw events

Expected behavior

When EventsCompactionConfig is configured, the Runner should be aware that compacted summaries exist and avoid loading the full event history. Possible approaches:

  1. Runner should pass GetSessionConfig to get_session — After compaction has run, the Runner knows which events are summarized. It should only load the compaction event(s) + recent un-compacted events.

  2. EventsCompactionConfig should inform session loading — The compaction config could derive appropriate GetSessionConfig parameters (e.g., only load events after the last compaction timestamp).

  3. At minimum, expose GetSessionConfig via RunConfig — As proposed in Allow limiting num. of Session events fetched when calling Runner.run_async #3562 and PR feat(runners): Add get_session_config property to RunConfig #3662, allow users to control how many events are loaded. But ideally the framework should do this automatically when compaction is configured.

Environment

  • ADK version: 1.26.0
  • Python: 3.12
  • Session service: DatabaseSessionService (PostgreSQL, accessed via HTTP microservice)
  • Agent type: Multi-stage SequentialAgent with ParallelAgent sub-stages

Related issues

Analysis

The root cause is that compaction and session loading are designed as two independent systems:

  1. Compaction (in apps/compaction.py) runs post-invocation and appends summary events
  2. Session loading (in runners.py) runs pre-invocation and loads everything

There is no feedback loop between them. Even after compaction has run successfully, the next invocation still loads all original events + the compaction event.

PR #3662 would help as a workaround (letting users manually set num_recent_events), but the ideal fix is for the Runner to automatically leverage compaction metadata to optimize session loading — making EventsCompactionConfig a true end-to-end optimization rather than just an LLM context optimization.

Activity

  1. added
    core[Component] This issue is related to the core interface and implementation
    on Mar 2, 2026
  2. added theissue type on Mar 2, 2026
  3. added 2 commits that reference this issue on Mar 3, 2026
    40d638f
    edbea2f
  4. llalitkumarrr commented on Mar 4, 2026

    @llalitkumarrr
    Collaborator

    Hello @rusherman ,

    Thank you for raising this issue, #4693 seems have a fix for this issue. This is PR is under review and will be merged once all checks are passed.

    We request you to have a look at this and see if this fixes your issue. Thank you for your patience.

  5. self-assigned this
    on Mar 4, 2026
  6. added a commit that references this issue on Mar 5, 2026
    85a814e
  7. rusherman commented on Mar 5, 2026

    @rusherman
    Author

    Thanks @llalitkumarrr for the quick response!

    I've reviewed PR #4693 — the approach of adding get_session_config to RunConfig and threading it through all Runner entry points (run_async, run_live, rewind_async, run_debug) is exactly the workaround I was hoping for. This gives us explicit control over session loading, which should immediately resolve the performance degradation in our production setup.

    A couple of notes:

    1. This PR solves the immediate problem — We can now set num_recent_events to limit loaded events when compaction is active. In our case with ~4,800 events per session, this should bring get_session latency back to sub-second.

    2. Follow-up suggestion: As mentioned in the issue, the ideal long-term fix would be for the Runner to automatically derive GetSessionConfig from EventsCompactionConfig (e.g., only load events after the last compaction timestamp). This would make compaction a true end-to-end optimization without requiring users to manually tune num_recent_events. Happy to discuss or contribute if there's interest in a follow-up PR.

    Looking forward to this being merged! 🎉

  8. llalitkumarrr commented on Mar 6, 2026

    @llalitkumarrr
    Collaborator

    Hello @rusherman ,

    Thank you for taking the time to check the linked PR. It is currently under review and will be merged once all checks pass.
    Regarding your suggestions for improvement, we always appreciate community contributions. If you are interested, please feel free to raise a new PR with your proposed improvements.

  9. added a commit that references this issue on Mar 10, 2026
    eff724a
  10. added a commit that references this issue on Aug 11, 2026
    dc5be8f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

core[Component] This issue is related to the core interface and implementation

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions