Skip to content

chore: prevent excessive database round trips - #177

Open
BobdenOs wants to merge 1 commit into
mainfrom
fix/db-ddos
Open

BobdenOs wants to merge 1 commit into
mainfrom
fix/db-ddos

Conversation

@BobdenOs

@BobdenOs BobdenOs commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

The problem

Currently on main when a user send a single simple message and the agent responds with a single simple response.

The following database round trips are made:

  1. READ cap.agent.Tasks (25x)
  2. CREATE cap.agent.Tasks (1x)
  3. UPDATE cap.agent.Tasks (22x)
  4. READ cap.agent.PushNotificationConfigs (22x)
  5. UPSERT cap.agent.Checkpoints (10x)

This undiscovered behavior is mostly caused by our dependencies and their expectations. While all the information to make a much more optimized persistency solution are available. These points are not clear as they are not the advertised APIs from the libraries. Additionally these points are drowned in ~700 line long functions.

The current flow is as follows:

  1. A2A client sends message
  2. Graph executor starts langchain agent
  3. LangChain puts the user message into a snapshot and stores it for each middleware triggered (~4x)
  4. LangChain start streaming all tokens back through the stack to the client
  5. A2A-js collects all the tokens into a task state.
    • Keeping the full state in memory.
    • Storing the full state on each token into the database.
    • Reading the full state on each token from the database.
    • Reads all notification configurations from the database on each token.
    • Tries to send the full state to all configured notification endpoints on each token.
  6. LangChain collected the final response into a snapshot and stores it for each middleware triggered (~6x)
db-ddos

Changes

This PR does not try to solve the root cause. It did some simply checks to prevent duplicate database requests from being made. A proper solution would be to move the persistency calls to more appropriate locations in the chain. Where we have more detailed stream and state information.

full traces comparison

main

[trace] - elapsed times: 
  0.00 → 2520.98 = 2520.98 ms - POST /a2a/browse/
 12.04 → 14.56  =   2.52 ms - db - READ cap.agent.Tasks
 14.87 → 15.37  =   0.49 ms - db - READ cap.agent.Tasks
 34.63 → 629.77 = 595.14 ms - CatalogService - buildGraph 
199.98 → 208.25 =   8.27 ms - CatalogService - buildTools 
208.35 → 265.79 =  57.44 ms - CatalogService - buildModel 
265.89 → 265.99 =   0.10 ms - CatalogService - buildSystemPrompt 
266.11 → 623.90 = 357.79 ms - CatalogService - buildMiddleware 
630.65 → 632.77 =   2.13 ms - db - CREATE cap.agent.Tasks
637.22 → 638.18 =   0.96 ms - db - UPDATE cap.agent.Tasks
638.85 → 639.95 =   1.10 ms - db - READ cap.agent.Checkpoints
640.36 → 642.91 =   2.55 ms - db - READ cap.agent.Tasks
647.05 → 648.33 =   1.29 ms - db - READ cap.agent.Checkpoints
650.27 → 651.91 =   1.64 ms - db - READ cap.agent.PushNotificationConfigs
659.58 → 661.34 =   1.76 ms - db - UPDATE cap.agent.Tasks
663.51 → 695.72 =  32.21 ms - db - UPSERT cap.agent.Checkpoints
696.83 → 697.60 =   0.78 ms - db - READ cap.agent.Tasks
698.24 → 699.24 =   1.00 ms - db - UPSERT cap.agent.Checkpoints
699.71 → 700.18 =   0.47 ms - db - READ cap.agent.PushNotificationConfigs
700.29 → 700.87 =   0.58 ms - db - UPSERT cap.agent.Checkpoints
701.36 → 701.96 =   0.60 ms - db - UPSERT cap.agent.Checkpoints
703.65 → 704.23 =   0.58 ms - db - UPSERT cds.outbox.Messages
1553.14 → 1553.77 =   0.64 ms - db - UPDATE cap.agent.Tasks
1554.41 → 1554.90 =   0.49 ms - db - READ cap.agent.Tasks
1555.55 → 1555.84 =   0.30 ms - db - READ cap.agent.PushNotificationConfigs
1997.21 → 1997.95 =   0.74 ms - db - UPDATE cap.agent.Tasks
1998.65 → 1999.19 =   0.54 ms - db - READ cap.agent.Tasks
1999.95 → 2000.21 =   0.26 ms - db - READ cap.agent.PushNotificationConfigs
2000.31 → 2000.60 =   0.29 ms - db - UPDATE cap.agent.Tasks
2001.10 → 2001.49 =   0.39 ms - db - READ cap.agent.Tasks
2002.13 → 2002.46 =   0.33 ms - db - READ cap.agent.PushNotificationConfigs
2002.57 → 2003.02 =   0.45 ms - db - UPDATE cap.agent.Tasks
2003.44 → 2003.78 =   0.34 ms - db - READ cap.agent.Tasks
2004.27 → 2004.51 =   0.24 ms - db - READ cap.agent.PushNotificationConfigs
2004.67 → 2005.08 =   0.40 ms - db - UPDATE cap.agent.Tasks
2005.45 → 2005.86 =   0.41 ms - db - READ cap.agent.Tasks
2006.34 → 2006.59 =   0.25 ms - db - READ cap.agent.PushNotificationConfigs
2008.60 → 2009.33 =   0.72 ms - db - UPDATE cap.agent.Tasks
2009.94 → 2010.50 =   0.56 ms - db - READ cap.agent.Tasks
2011.35 → 2011.66 =   0.31 ms - db - READ cap.agent.PushNotificationConfigs
2011.77 → 2012.27 =   0.49 ms - db - UPDATE cap.agent.Tasks
2012.86 → 2013.30 =   0.44 ms - db - READ cap.agent.Tasks
2014.04 → 2014.40 =   0.35 ms - db - READ cap.agent.PushNotificationConfigs
2014.54 → 2014.94 =   0.40 ms - db - UPDATE cap.agent.Tasks
2015.43 → 2015.79 =   0.36 ms - db - READ cap.agent.Tasks
2016.46 → 2016.74 =   0.29 ms - db - READ cap.agent.PushNotificationConfigs
2016.85 → 2017.19 =   0.33 ms - db - UPDATE cap.agent.Tasks
2017.64 → 2018.08 =   0.43 ms - db - READ cap.agent.Tasks
2018.53 → 2018.85 =   0.31 ms - db - READ cap.agent.PushNotificationConfigs
2441.52 → 2441.99 =   0.47 ms - db - UPDATE cap.agent.Tasks
2442.58 → 2443.04 =   0.45 ms - db - READ cap.agent.Tasks
2443.52 → 2443.74 =   0.23 ms - db - READ cap.agent.PushNotificationConfigs
2445.63 → 2446.30 =   0.67 ms - db - UPDATE cap.agent.Tasks
2447.58 → 2448.16 =   0.58 ms - db - READ cap.agent.Tasks
2448.79 → 2449.17 =   0.37 ms - db - READ cap.agent.PushNotificationConfigs
2449.28 → 2449.65 =   0.36 ms - db - UPDATE cap.agent.Tasks
2450.05 → 2450.53 =   0.48 ms - db - READ cap.agent.Tasks
2451.12 → 2451.39 =   0.27 ms - db - READ cap.agent.PushNotificationConfigs
2451.49 → 2451.79 =   0.30 ms - db - UPDATE cap.agent.Tasks
2452.18 → 2452.54 =   0.36 ms - db - READ cap.agent.Tasks
2453.02 → 2453.27 =   0.25 ms - db - READ cap.agent.PushNotificationConfigs
2453.37 → 2453.65 =   0.28 ms - db - UPDATE cap.agent.Tasks
2453.99 → 2454.30 =   0.31 ms - db - READ cap.agent.Tasks
2454.91 → 2455.35 =   0.44 ms - db - READ cap.agent.PushNotificationConfigs
2455.56 → 2456.16 =   0.60 ms - db - UPDATE cap.agent.Tasks
2456.72 → 2457.13 =   0.41 ms - db - READ cap.agent.Tasks
2457.71 → 2457.97 =   0.26 ms - db - READ cap.agent.PushNotificationConfigs
2458.10 → 2458.40 =   0.30 ms - db - UPDATE cap.agent.Tasks
2458.76 → 2459.15 =   0.39 ms - db - READ cap.agent.Tasks
2459.65 → 2459.93 =   0.28 ms - db - READ cap.agent.PushNotificationConfigs
2460.04 → 2460.52 =   0.48 ms - db - UPDATE cap.agent.Tasks
2461.16 → 2461.74 =   0.59 ms - db - READ cap.agent.Tasks
2462.26 → 2462.58 =   0.32 ms - db - READ cap.agent.PushNotificationConfigs
2469.30 → 2469.82 =   0.52 ms - db - UPDATE cap.agent.Tasks
2470.40 → 2470.87 =   0.47 ms - db - READ cap.agent.Tasks
2471.36 → 2471.65 =   0.29 ms - db - READ cap.agent.PushNotificationConfigs
2491.56 → 2503.59 =  12.03 ms - db - UPSERT cap.agent.Checkpoints
2504.37 → 2505.11 =   0.74 ms - db - UPSERT cap.agent.Checkpoints
2505.73 → 2506.36 =   0.63 ms - db - UPSERT cap.agent.Checkpoints
2506.91 → 2507.50 =   0.59 ms - db - UPSERT cap.agent.Checkpoints
2508.03 → 2508.58 =   0.56 ms - db - UPSERT cap.agent.Checkpoints
2509.17 → 2509.79 =   0.62 ms - db - UPSERT cap.agent.Checkpoints
2511.02 → 2512.02 =   1.00 ms - db - READ cap.agent.Checkpoints
2512.36 → 2512.83 =   0.46 ms - db - READ cap.agent.CheckpointWrites
2515.98 → 2516.43 =   0.45 ms - db - UPDATE cap.agent.Tasks
2517.01 → 2517.76 =   0.75 ms - db - READ cap.agent.Tasks
2518.45 → 2518.75 =   0.30 ms - db - READ cap.agent.PushNotificationConfigs
2518.89 → 2519.21 =   0.31 ms - db - UPDATE cap.agent.Tasks
2519.59 → 2519.92 =   0.34 ms - db - READ cap.agent.Tasks
2520.59 → 2520.85 =   0.26 ms - db - READ cap.agent.PushNotificationConfigs

PR

[trace] - elapsed times: 
  0.00 → 1656.15 = 1656.15 ms - POST /a2a/browse/
  4.41 → 5.43   =   1.02 ms - db - READ cap.agent.Tasks
  5.81 → 6.19   =   0.38 ms - db - READ cap.agent.Tasks
  7.47 → 8.44   =   0.97 ms - db - CREATE cap.agent.Tasks
 10.86 → 11.58  =   0.73 ms - db - UPDATE cap.agent.Tasks
 12.60 → 13.72  =   1.12 ms - db - READ cap.agent.Checkpoints
 14.51 → 15.33  =   0.82 ms - db - READ cap.agent.PushNotificationConfigs
 16.55 → 16.92  =   0.37 ms - db - READ cap.agent.PushNotificationConfigs
 17.20 → 18.00  =   0.81 ms - db - READ cap.agent.Checkpoints
 21.61 → 35.34  =  13.73 ms - db - UPSERT cap.agent.Checkpoints
 37.03 → 38.80  =   1.77 ms - db - UPSERT cap.agent.Checkpoints
1631.08 → 1647.67 =  16.59 ms - db - UPSERT cap.agent.Checkpoints
1649.03 → 1649.82 =   0.80 ms - db - READ cap.agent.Checkpoints
1650.43 → 1650.90 =   0.47 ms - db - READ cap.agent.CheckpointWrites
1653.97 → 1654.77 =   0.80 ms - db - UPDATE cap.agent.Tasks

Have you...

  • Added relevant entry to the change log?

@BobdenOs
BobdenOs requested review from a team as code owners October 2, 2026 21:00
@hyperspace-pr-bot

Copy link
Copy Markdown

Summary

The following content is AI-generated and provides a summary of the pull request:


Reduce redundant persistence calls during agent message handling

Category: Chore

Summary

This PR reduces excessive database round trips during A2A agent message handling by adding lightweight in-memory caching and avoiding duplicate persistence writes when state has not meaningfully changed.

Changes

  • Added task caching in CdsTaskStore to avoid repeated reads for the same task.
  • Limited task persistence to relevant lifecycle states (submitted and completed) to prevent per-token task updates during streaming.
  • Added push notification config caching per task/user in CdsPushNotificationStore, with cache invalidation on save/delete.
  • Added checkpoint deduplication in CdsCheckpointSaver by tracking message counts per thread and skipping checkpoint writes when no new messages were added.
  • Removed additional_kwargs from checkpoint messages before serialization to reduce stored payload noise.
  • Includes a minor formatting cleanup in checkpoint listing.

Impact

For a simple single-message interaction, the observed database trace is significantly reduced: repeated task reads/updates, notification config reads, and checkpoint upserts are avoided during streaming. This improves request latency and reduces unnecessary database load without changing the external behavior.

db-ddos

Have you...

  • Added relevant entry to the change log?

  • 🔄 Regenerate and Update Summary
  • ✏️ Insert as PR Description (deletes this comment)
  • 🗑️ Delete comment
PR Bot Information

Version: 1.31.69

  • File Content Strategy: Full file content
  • Summary Prompt: Default Prompt
  • Correlation ID: 4fe2be90-bea4-11f1-81b6-e545c84d7a04
  • Output Template: Repository PR Template
  • Event Trigger: pull_request.opened
  • LLM: gpt-5.5

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant