State: let / vars / persist
Three state blocks, three purposes.
let: base-url: "${config.endpoint}" # immutable, evaluated once at start greeting: "Hello, ${user.name}!"
vars: counter: !int 0 # mutable, transient (lost after run) buffer: !str-list
persist: cursor: !str # mutable, survives across runs last-sync: !str # auto-loaded at start, auto-saved on successWhich block to use
Section titled “Which block to use”| Block | Mutable? | Lifetime | Use for |
|---|---|---|---|
let: | No | One run, evaluated once at start | Anything computed once at flow start. |
vars: | Yes | One run, transient | Loop accumulators, transient bookkeeping. |
persist: | Yes | Across runs | Pagination cursors, last-seen timestamps, watermark IDs. |
persist: values are auto-loaded at the start of each run and auto-saved when the flow completes successfully. They live under activity/persistence/ in the storage tree.
Assigning state
Section titled “Assigning state”Assign with $name: syntax in steps:, or batch with set::
output: counter: !int
steps: - $counter: "${= counter + 1}" # single assignment - set: # batch — committed atomically cursor: "${products.last-id}" last-sync: "${= str(_run-id)}" seen-count: "${= seen-count + len(products.rows)}"
- return: counter: "${counter}"Prefer set: over multiple $var: lines when updating several variables at once — it commits them atomically.
A worked cursor example
Section titled “A worked cursor example”A flow that pages through a source and remembers where it left off between runs:
using: - zenvara/http
persist: cursor: !str ""
output: items: !any
steps: - $page: invoke: http.get with: Url: "https://api.example.com/items?after=${cursor}" - set: cursor: "${page.body.next-cursor}"
- return: items: "${page.body}"Dotted access into body works here because the response carries a JSON Content-Type — http.* auto-parses in that case. Against a non-JSON API, reach into it with path() instead: "${= path(page.body, \"$['next-cursor']\")}".
The next run picks up from the stored cursor automatically. Pair persist: with the delta: transformer for change-detection pipelines.