Skip to content

Progress

The progress extension enables workers to report real-time progress updates during job execution. Clients can poll or stream progress for user-facing feedback.

Progress supports two complementary representations:

A float between 0.0 and 1.0, representing percentage completion:

Terminal window
PUT /ojs/v1/jobs/01961234-5678-7abc/progress
{
"progress": 0.75
}

Values outside the range are clamped. Progress SHOULD be monotonically increasing—backends MAY reject decreasing values.

An arbitrary JSON object for application-specific detail:

Terminal window
PUT /ojs/v1/jobs/01961234-5678-7abc/progress
{
"progress": 0.6,
"detail": {
"phase": "uploading",
"files_processed": 120,
"files_total": 200,
"current_file": "report-q1.pdf"
}
}
Terminal window
GET /ojs/v1/jobs/01961234-5678-7abc
{
"id": "01961234-5678-7abc-def0-123456789abc",
"state": "active",
"progress": 0.6,
"progress_detail": {
"phase": "uploading",
"files_processed": 120,
"files_total": 200
}
}

For real-time updates without polling:

Terminal window
GET /ojs/v1/jobs/01961234-5678-7abc/progress/stream
event: progress
data: {"progress": 0.6, "detail": {"phase": "uploading", "files_processed": 120}}
event: progress
data: {"progress": 0.8, "detail": {"phase": "uploading", "files_processed": 160}}
event: complete
data: {"progress": 1.0, "state": "completed"}

Progress updates act as implicit heartbeats. Each progress update resets the heartbeat timeout clock, allowing long-running jobs to avoid stall detection without sending separate heartbeat calls.

Backends SHOULD accept at least 1 progress update per second.

Progress updates can include checkpoint data for resumable jobs. If a job fails and is retried, the checkpoint is passed to the next attempt:

Terminal window
PUT /ojs/v1/jobs/01961234-5678-7abc/progress
{
"progress": 0.5,
"checkpoint": {
"last_processed_id": 5000,
"batch_offset": 50
}
}

On retry, the handler receives the last checkpoint and can resume from where it left off rather than restarting from the beginning.

For workflows, progress is computed from constituent steps:

Workflow TypeAggregation
Chaincompleted_steps / total_steps (current step progress interpolated)
GroupAverage of all step progresses
Batchcompleted_steps / total_steps
Terminal window
GET /ojs/v1/workflows/wf_01961234-5678-7abc
{
"workflow_id": "wf_01961234-5678-7abc",
"type": "group",
"progress": 0.65,
"steps": [
{ "job_id": "...", "progress": 1.0, "state": "completed" },
{ "job_id": "...", "progress": 0.8, "state": "active" },
{ "job_id": "...", "progress": 0.15, "state": "active" }
]
}