Skip to content

DynamoDB aput_writes runs many writes sequentially #766

Description

@ltoniazzi

Package

langgraph-checkpoint-aws

Checked other resources

  • I added a descriptive title to this issue
  • I searched the LangChain documentation with the integrated search
  • I used the GitHub search to find a similar issue and didn't find it
  • I am sure this is a bug and not a question or request for help

Example Code

import random
from langgraph_checkpoint_aws import DynamoDBSaver
import asyncio
from time import time

TABLE_NAME = "test-langgraph" # Replace with your DynamoDB table name
REGION_NAME = "eu-central-1" # Replace with your AWS region

thread_id = str(random.randint(1, 1_000_000))

inputs_aput_writes = {
    "config": {
        "tags": [],
        "metadata": {
            "thread_id": thread_id,
            "user_id": "mock-id"
        },
        "callbacks": None,
        "recursion_limit": 25,
        "configurable": {
            "checkpoint_ns": "",
            "thread_id": thread_id,
            "user_id": "mock-id",
            "checkpoint_id": "1f0c530b-1ed7-6d1e-bfff-a40ab47d5463"
        }
    },
    "writes": [
        ('user_id', 'mock-id'),
        ('language', 'en'),
        ('thread_id', thread_id),
        ('timestamp', '251119_101538082238'),
        ('data', 'good data'),
        ('branch:to:parse_listing_qualifications', None)
    ],
    "task_id": "576d569d-52df-e0bf-c0ad-5606841615f8",
    "task_path": '~__pregel_pull, __start__'
}


dynamo_db_saver = DynamoDBSaver(
    table_name=TABLE_NAME,
    region_name=REGION_NAME,
)

async def main():
    t0 = time()
    await dynamo_db_saver.aput_writes(**inputs_aput_writes)

    print("Time to run aput_writes: {:.4f} seconds".format(time() - t0))
    
if __name__ == "__main__":

    asyncio.run(main())

Error Message and Stack Trace (if applicable)

Time to run aput_writes: 1.0175 seconds

Description

Explanation

The async method aput_writes runs put_writes in run_in_executor (here) to be async.

But then:

  • put_writes here unpacks writes here,
  • with each graph state update in a different iteration of the loop
  • then executed sync in put_single_write_item here,
  • which then calls dynamodb sync client here

This means that if I have N graph state updates, then aput_writes will perform N*2 sequential/sync put_item, which defeats the purpose of having fast writes with DynamoDB. (*2 because once for metadata and once for values)

Comparisons

  • Postgres saver: writes are unpacked but executed concurrently with await cur.executemany(query, params) (here)
  • AgentCore Saver: (sync implementation) writes are not unpacked, and executed in a single write event (here)

Question

Can we either make the writes happen concurrently with async or have them batched in a single write (which maybe could be difficult due to size limitations?

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdynamodb

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions