CircleCI no_output_timeout: poll a Sume video job without a kill

CircleCI kills a run step after 10 silent minutes. Print a status line on every poll, raise no_output_timeout, and keep one Sume Idempotency-Key per workflow.

4 min readSume
All posts

A CircleCI run step stops when it prints nothing for 10 minutes, because that is the default of no_output_timeout. A Sume video job can sit in queued longer than that on a small plan, so a quiet poll loop is killed while the job keeps running and billing. Fix it two ways: print one line on every poll, and set no_output_timeout above your longest expected wait. Then derive the Sume Idempotency-Key from the CircleCI workflow id, so a rerun of the job never pays twice.

This post reflects CircleCI's configuration reference and Sume's jobs and admission docs, all read on 2026-10-11.

What does no_output_timeout do?

CircleCI describes it as the elapsed time a command can run without output. The default is 10 minutes, and the value is a string with a unit suffix such as 20m or 5s. The overall job limit is separate and depends on the plan.

A poll loop that only prints on completion looks idle to CircleCI. A loop that echoes the status each time resets the clock, so the echo is the real fix and the longer timeout is the safety margin.

CircleCI limits that matter for a long render, read 2026-10-11
LimitValueSource
no_output_timeout default10 minutesCircleCI configuration reference
Maximum job runtime, Free plan1 hourCircleCI configuration reference
Maximum job runtime, Performance plan3 hoursCircleCI configuration reference
Maximum job runtime, Scale plan5 hoursCircleCI configuration reference

Why can a Sume job wait that long?

Sume admits paid generation queue-first. When your workspace is at its concurrency limit, a valid submit still returns a job in queued, and workers move it to processing when a slot opens. queued is a normal state, not a failure. Statuses completed, failed and canceled are terminal.

Sume's docs say to poll with backoff and not to submit the original paid request again just because a local process timed out. That second rule is why the key below matters.

What does the step look like?

The step submits once with an Idempotency-Key built from CIRCLE_WORKFLOW_ID, then polls GET /v1/jobs/{id}/status. A /v1/videos response carries the job id in id. The exit codes let the next step tell success (0), a terminal failure (1) and a give-up (2) apart.

version: 2.1
jobs:
  render:
    docker: [{image: cimg/base:stable}]
    steps:
      - run:
          name: Submit once, poll until terminal
          no_output_timeout: 20m
          command: |
            set -euo pipefail
            KEY="build-${CIRCLE_WORKFLOW_ID}-promo"
            ID=$(curl -fsS https://api.sume.com/v1/videos \
              -H "Authorization: Bearer $SUME_API_KEY" \
              -H "Idempotency-Key: $KEY" \
              -H "Content-Type: application/json" \
              -d '{"model":"sume/auto","prompt":"Product spin, studio light"}' \
              | jq -r .id)
            for i in $(seq 1 120); do
              S=$(curl -fsS "https://api.sume.com/v1/jobs/$ID/status" \
                -H "Authorization: Bearer $SUME_API_KEY" | jq -r .status)
              echo "job $ID: $S"
              case "$S" in
                completed) exit 0 ;;
                failed|canceled) exit 1 ;;
              esac
              sleep $(( i < 6 ? 5 * i : 30 ))
            done
            exit 2

What happens when the job is rerun?

Rerunning a workflow from failed keeps the same workflow id, so the same key goes out with the same body. Sume treats that as an exact retry. Reusing a key with a different body returns 409 idempotency_conflict, so change the key suffix when you change the prompt.

If the loop ends with exit code 2, the job is still alive on Sume. Read its status again rather than submitting a new one; a cancelled CI run does not cancel the Sume job, as covered in GitHub Actions cancel-in-progress and Sume jobs.

Should CI poll at all?

For a single clip, polling is simple and fine. For a batch, a webhook receiver avoids holding a runner for minutes. A shell version of the loop with its own exit codes is in Poll a Sume job from a CI step with curl and jq.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume