LangGraph DeltaChannel: keep Sume artifact URLs in state, not video

LangGraph 1.2 DeltaChannel stores only the per-step delta. Even so, keep Sume media out of state: store the artifact URL and job id and fetch bytes when needed.

5 min readSume
All posts

Put the Sume job id and artifact URLs in your LangGraph state, never the media bytes. DeltaChannel makes large accumulating state cheaper to checkpoint, but a video is still the wrong thing to carry in a message list, and Sume already hands you a URL.

The LangChain Python changelog (read 2026-10-02) describes DeltaChannel, in beta in v1.2.0, as "a new channel type that stores only the incremental delta at each step rather than re-serializing the full accumulated value," with snapshot_frequency=K for periodic full snapshots. It is aimed at channels that grow, like a message list in a long thread.

What does DeltaChannel fix, and what does it not?

It fixes re-serializing the whole accumulated value at every step. A thread whose message list grows over fifty tool calls no longer rewrites the full list into each checkpoint. It does not shrink a single large value: if one step appends a base64 video, that delta is still huge, still stored, and still replayed when the state is rebuilt from deltas and the periodic snapshots.

I did not find, on the page I read, a claim about how DeltaChannel treats individual large values, so treat that as unconfirmed and measure your own checkpoints.

What does Sume give me instead of bytes?

A completed job result and webhook payloads carry artifact objects with an id, a url, a type and a content_type. The Webhooks page shows url values under https://media.sume.com/artifacts/.... Those are the small things to keep in state.

{
  "event": "job.completed",
  "request_id": "job_...",
  "job_id": "job_...",
  "status": "OK",
  "payload": {
    "artifacts": [
      {
        "id": "artf_...",
        "url": "https://media.sume.com/artifacts/...",
        "type": "image",
        "content_type": "image/png"
      }
    ]
  }
}

What should the state schema hold?

Keep four small fields per generation: the business key, the Sume job_id, the terminal status, and the list of artifact id and url pairs. Anything downstream that needs the file downloads it from the URL at the moment it needs it.

State fields for a Sume generation (read 2026-10-02, from Webhooks and Jobs and results)
FieldSourceWhy keep it
job_idSubmit response request_idRecover and re-poll after a restart
statusstatus endpoint sume_statusBranch without a second call
artifact id and urlResult or webhook payloadSmall, stable handle for the file
idempotency keyYour own item idExact-retry safety

How do I pass media to a later node that needs the file?

Pass the URL and let the node download it. A node that burns a caption onto a video, or uploads it to a social platform, needs bytes for a moment; it does not need them in a checkpoint. Download inside the node, process, upload, and return only the new URL or an id.

If the next step is another Sume call that takes a media input, give it the URL where the route accepts one. Check the live OpenAPI at https://api.sume.com/reference/json for each route's input fields rather than guessing, since the docs say that document is the schema source of truth.

Finally, size your checkpoints on a real thread. Run twenty generations and look at the stored state size per step. With URLs and ids it should grow by a few hundred bytes per item, and DeltaChannel then keeps even that growth from being rewritten at every step.

Are those URLs permanent?

The docs I read do not state an expiry for artifact URLs, so do not promise one downstream. If you must keep a file long term, download it into your own storage when the job completes and store your own URL next to the Sume one. For a full list of what a job returns, read it from GET /v1/jobs/{id}/result after result_ready, not from a checkpoint you wrote hours ago. Before you ship, read the live contract for every route you call at https://api.sume.com/reference/json, which Sume's docs name as the schema source of truth, and re-read the linked docs pages: limits, scopes and error codes change faster than blog posts do. Treat any number in this post as a snapshot dated 2026-10-02, and prefer the effective fields your own responses return, such as generation_limits, over a static table.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume