Best practice for persisting large accumulated LangGraph state without hitting ScheduleActivityTask payload size limits
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 35/100
- Issue 类型
- 文档
- 描述清晰度
- 需要澄清
- 活跃度
- 活跃
- 技术栈
- python
调研方向
Start with the LangGraphPlugin activity boundary and the workflow.execute_activity call described in the issue, then review how the Postgres-backed checkpointer and Temporal activity payload limits interact. The issue is complete when maintainers document a supported persistence pattern and clarify whether payload codecs, chunking, or streaming are appropriate for large state.
由索引模型根据 Issue 内容生成。
描述
We're running LangGraph-based agents through temporalio.contrib.langgraph.LangGraphPlugin, where each graph node executes as a Temporal Activity. The workflows accumulate state across many sequential (and some parallel) node executions — investigation-style agents with 20-30+ nodes producing tool-call transcripts, messages, etc.
Before wrapping these graphs with Temporal, we ran them directly against LangGraph's own Postgres-backed checkpointer, which persists automatically after every node (every "superstep"). Once we moved execution behind Temporal Activities, that per-node persistence went away — the nodes now run as separate Activities without a shared in-process checkpointer, so nothing writes to Postgres until we explicitly do so ourselves.
Our first attempt reintroduced persistence as a single workflow.execute_activity(persist_result_activity, args=[...full accumulated final state...]) call after ainvoke() returns, so it survives even if no client ever reconnects to read handle.result(). That worked for small/medium runs, but a larger run hit:
BadScheduleActivityAttributes: ScheduleActivityTaskCommandAttributes.Input exceeds size limit.
...which terminated the entire workflow server-side (WORKFLOW_EXECUTION_TERMINATED) — a total loss, worse than the gap we were trying to close. Individual per-node Activity payloads never approached the limit (29/29 node-Activities completed fine); only the one bulk end-of-run payload did.
Our leading fix: restore the original per-node persistence behavior — write each node's own delta to Postgres from inside that node's own Activity execution (no extra execute_activity hop needed, since the node body already runs as an Activity) — rather than shipping the whole accumulated state through Temporal in one call at the end. This keeps every persistence write proportional to a single node's output, matching what the pre-Temporal execution already did natively.
Questions for the maintainers:
- Is per-node/per-Activity persistence the idiomatic pattern here, or is there Temporal-native support for this (e.g. something LangGraphPlugin already offers) that we're missing?
- We also considered gzip-compressing the final payload before passing it as Activity args — it only raises the ceiling rather than removing it, and doesn't restore true mid-run durability (a crash just before that one activity still loses the whole run's state). Are there better-supported options for cases where a single large Activity payload is genuinely unavoidable (custom
PayloadCodec, chunking, streaming activity results)? - Any general guidance on structuring Activities around something like LangGraph, where per-node output sizes vary widely and the framework's own native checkpointing gets bypassed by the Activity boundary?
- 主要语言
- Python
- 星标
- 1.2k
- 派生
- 241
- 平均合并
- 3 天 2 小时
- 30 天内合并 PR
- 49
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
temporalio/sdk-python 的其他 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 74/100
temporalio/sdk-python#1517 · 10 条评论 ·
-
bug
难度 2/5 1-3 小时 新手友好度 68/100
temporalio/sdk-python#496 ·
-
难度 5/5 一周以上 新手友好度 25/100
temporalio/sdk-python#1890 ·
-
难度 4/5 3-5 天 新手友好度 52/100
temporalio/sdk-python#1881 · 1 条评论 ·
-
bug
temporalio/sdk-python#1817 · 1 条评论 · 已指派 1 人 ·
查看 temporalio/sdk-python 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 75/100
stephrobert/dsoxlab#238 ·
-
难度 2/5 1-3 小时 新手友好度 75/100
-
难度 2/5 1-3 小时 新手友好度 75/100
sublimehq/package_control#1780 ·
-
难度 2/5 1-3 小时 新手友好度 65/100
-
难度 2/5 1-3 小时 新手友好度 70/100
nwg-piotr/nwg-displays#145 ·