Skip to content

Job Queue

Every printable item in PrintStudio is a job. Jobs flow through a typed state machine enforced by BullMQ workers. There are 49 typed transitions across 8 states.

CREATED
VALIDATED ──────────────────────────────────────────────► CANCELLED
│ ▲
▼ │
SLICED (any state)
QUEUED
PRINTING ──────► FAILED ──────► (retry: back to QUEUED)
POST_PROCESS
READY
SHIPPED
StateDescriptionNext
CREATEDJob record created from order line itemVALIDATED, CANCELLED
VALIDATEDInventory checked, parameters verifiedSLICED, CANCELLED
SLICEDG-code generated by OrcaSlicerQUEUED
QUEUEDWaiting for printer assignmentPRINTING, CANCELLED
PRINTINGActive on a machinePOST_PROCESS, FAILED
POST_PROCESSCooling, de-supporting, finishingREADY
READYComplete, awaiting fulfilmentSHIPPED
SHIPPEDTracking number assigned
FAILEDError occurredQUEUED (retry) or CANCELLED
CANCELLEDCancelled by operator or customer

Six BullMQ queues drive state transitions:

QueueWorkerTransition
validationChecks inventory + paramsCREATED → VALIDATED
slicingRuns OrcaSlicer CLIVALIDATED → SLICED
routingAutoPilot assigns printerSLICED → QUEUED
printingSends G-code, monitors progressQUEUED → PRINTING → POST_PROCESS
post-processTimer-based cooling/finishingPOST_PROCESS → READY
shippingCreates shipment, gets trackingREADY → SHIPPED

All queues are defined in packages/core/src/queues/.

The operator dashboard at /dashboard shows the full job board. Sort by state, printer, SKU, or ETA.

Terminal window
# List all active jobs
curl http://localhost:8787/api/jobs?status=printing,queued \
-H "X-API-Key: your-api-key"
# Get a specific job
curl http://localhost:8787/api/jobs/{jobId} \
-H "X-API-Key: your-api-key"
# Manually release a queued job to a specific printer
curl -X POST http://localhost:8787/api/jobs/{jobId}/release \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{ "printerId": "printer-uuid" }'
# Cancel a job
curl -X POST http://localhost:8787/api/jobs/{jobId}/cancel \
-H "X-API-Key: your-api-key"
Terminal window
# Reprioritise a job (higher number = higher priority)
curl -X POST http://localhost:8787/api/orchestrator/reprioritize \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{ "jobId": "job-uuid", "priority": 10 }'
# Pause all automation
curl -X POST http://localhost:8787/api/orchestrator/pause \
-H "X-API-Key: your-api-key"
# Get queue health
curl http://localhost:8787/api/orchestrator/status \
-H "X-API-Key: your-api-key"

Failed jobs are automatically retried by the AutoPilot:

  • Max retries: 3 (configurable via PUT /api/orchestrator/config)
  • Backoff: exponential — 1 min, 5 min, 25 min
  • Re-routing: on each retry, the router attempts a different printer
  • Escalation: after all retries exhausted, operator is notified via OpenClaw and email

The AutoPilot runs a batch optimisation pass every 2 minutes. It groups queued jobs by material and machine type and sends compatible jobs to the same printer in sequence, reducing filament change time.