Flows Cheatsheet

One-screen lookup. Cite: Flows, Continue Parent, Fail Parent, Get Flow Tree.

Mental model

Tree of jobs. Parent in waiting-children → runs only after all children complete.

FlowProducer — the only entry point

import { FlowProducer } from 'bullmq';
const flow = new FlowProducer({ connection });

const tree = await flow.add({
  name: 'finalize', queueName: 'pipeline', data: {},
  children: [
    { name: 'resize', data: { size: 200 }, queueName: 'images', opts: { attempts: 3 } },
    { name: 'resize', data: { size: 800 }, queueName: 'images' },
  ],
});   // atomic: all jobs or none
Node fieldNotes
name / queueNameRequired. Each node picks its own queue → cross-queue deps.
dataPayload.
optsJobsOptions minus repeat/debounce/deduplication/parent.
childrenArray of child nodes (arbitrary depth).
prefixRedis key prefix per node.
No repeat on flow nodes. Want a recurring pipeline? Schedule the producer via a Job Scheduler (Lesson 3).

Failure policies — pick ONE per fallible child

Default = orphan. A child that fails never "completes," so the parent hangs in waiting-children forever. Always set a policy on any child that can fail.
Child optBehaviorUse
continueParentOnFailure: trueParent proceeds immediately; cancel siblings with job.removeUnprocessedChildren(); inspect job.getFailedChildrenValues().Best-effort — partial results OK.
failParentOnFailure: trueParent → failed at once. Selective + recursive up the tree (if ancestors also set it).Fail-fast — mandatory step.

Inspection

const sub = await flow.getFlow({ id, queueName, depth: 1, maxChildren: 50 });
const vals = await job.getChildrenValues();      // { childKey: returnvalue }
const cnt  = await job.getDependenciesCount();  // processed/unprocessed
const pk   = job.parentKey;                     // parent's fq key (or undefined)

Removal cascades

ActionEffect
Remove parentAll children removed too.
Remove last childParent completes (no worker runs).
Any job lockedNothing removed; exception thrown.

Mental model — when to reach for flows

ShapeUse
Fan-out / fan-inN parallel children → 1 aggregate parent.
Multi-stage pipelineresize → upload → notify as a tree.
Cross-queue workCPU-bound children on one queue, light parent on another.