---
title: Progress and streams
description: Report typed progress and consume bounded live output.
pagination: false
sidebar:
  icon: radio
---

Report bounded progress from a task so callers can follow the run without holding its execution open.

> **Before you begin**
>
> Use an existing [task/job with its selected provider installed and
> bound](/docs/modules/jobs/quickstart) before running this example. Core task declarations do not
> install the provider's native SDK.

Progress is an observation channel, not a second source of truth. Define its shape and emit snapshots from
the task:

```ts title="examples/commerce/src/services/orders/tasks/export-orders.task.ts"
/** Produces demonstration CSV through the ordinary order helper and emits validated progress around the durable export. */
import { defineTask } from "@relkit/app/tasks";
import { z } from "@relkit/app/schema";
import { exportOrderCsv } from "../helpers/fake-business.js";

const exportOrders = defineTask({
  id: "orders.export-orders",
  version: "1",
  execution: "durable",
  input: z.object({ orderIds: z.array(z.string()) }),
  output: z.object({ csv: z.string(), exported: z.number().int().nonnegative() }),
  progress: z.object({
    completed: z.number().int().nonnegative(),
    total: z.number().int().positive(),
  }),
  handler: async ({ orderIds }, context) => {
    await context.progress.emit({ completed: 0, total: orderIds.length });
    const csv = exportOrderCsv(orderIds);
    await context.progress.emit({ completed: orderIds.length, total: orderIds.length });
    return { csv, exported: orderIds.length };
  },
});

export default exportOrders;
```

Progress and stream items are limited to 64 KiB. Keep payloads small, include a sequence or cursor when consumers need ordering, and store durable results in the task output or application database.

Streams may be live, durable, or unavailable depending on the binding. A reconnect can observe a gap when retention has expired; reset the UI from the latest run snapshot instead of replaying untrusted client state. Provider capability output is authoritative for the selected environment.

Progress does not authorize a client to read a private run. Apply the same ownership and field-level redaction rules to progress and stream payloads as to the final output.

{/* Generated by apps/docs/scripts/generate.ts. Do not edit. */}

**Reference and source**

- [`@relkit/jobs` API](/docs/api/jobs)
- [`@relkit/client` API](/docs/api/client)

- [`examples/commerce/src/services/orders/tasks/export-orders.task.ts`](https://github.com/rel-kit/relkit/blob/main/examples/commerce/src/services/orders/tasks/export-orders.task.ts)
