Advanced Topics

Streaming

Opt-in chunked responses for large datasets and real-time updates

Every endpoint can respond in two modes: buffered (the default) and streaming. Streaming returns results incrementally as they're produced; buffered returns the whole response at once. You choose the mode per request — it's never triggered automatically.

Streaming is opt-in. Request it with the stream query parameter or an Accept: application/stream+json header.

Selecting the response mode

The mode is resolved in this order:

PriorityMethodExample
1stQuery parameter?stream=true
2ndAccept headerAccept: application/stream+json
3rdDefaultnone → buffered

To force buffered mode, pass ?stream=false.

When streaming matters

Streaming only changes behavior on endpoints that return multiple items (lists, logs, event streams). Single-entity reads and simple mutations behave identically either way. Good candidates:

  • Large file / directory listings
  • Workflow execution logs (including the live log endpoint)
  • Server-sent event endpoints (e.g. workflow signals)

Enabling streaming

Add stream=true to any API request:

# File listings
curl "http://localhost/api/artifact/?stream=true"

# Workflow logs
curl "http://localhost/api/workflow/logs/?stream=true"

The web console streams live, list-heavy views automatically: file-manager browsing/search/bulk-ops/archives, workflow live logs and status/metrics, and system status lists (bridges, proxies, shell sessions, health checks).

CLI commands that stream:

dxflow artifact list /large-directory     # large directory listings
dxflow workflow logs my-workflow --live   # live log endpoint
dxflow ping                               # connectivity testing
dxflow bridge list                        # bridge connections

Response format

Both modes return the same JSON array of typed chunks. A status chunk is always first; an optional total chunk follows; entity chunks carry the data.

Chunk kindPayload structureExample
status{code: number, message: string}{code: 200, message: "OK"}
total{value: number}{value: 1500}
entityobject{id: 1, name: "item"}
entity:{tag}object (tagged){id: 1, name: "item"} under kind: "entity:logs"

The entity:{tag} form labels content in mixed-type responses.

[
  { "kind": "status", "payload": { "code": 200, "message": "OK" } },
  { "kind": "total", "payload": { "value": 1500 } },
  { "kind": "entity", "payload": { "name": "file1.txt", "size": 1024, "type": "file" } },
  { "kind": "entity", "payload": { "name": "file2.txt", "size": 2048, "type": "file" } }
]

In streaming mode each chunk arrives as it's produced; in buffered mode the whole array arrives at once. Either way you parse the same structure.

Errors use the same format:

[
  { "kind": "status", "payload": { "code": 404, "message": "File not found" } }
]

Troubleshooting

SymptomChecks
Streaming seems slowStable connection? High server load? Compare with ?stream=false.
Response appears incompleteClient may not support chunked encoding — test with curl or a modern browser; fall back to ?stream=false.
Streaming not workingConfirm the endpoint returns multiple items; verify HTTP-library compatibility; test directly with curl.