Process Orchestrator — a reactive, auditable engine for distributed business processes. Request a demo →
Home/Products/Process Orchestrator
Reactive engine · fault-tolerant · multi-tenant

The engine that runs your business processes.

Design a process as a graph of nodes —tasks, decisions, integrations, waits— and Process Orchestrator executes it step by step, keeping full traceability and reacting to failures according to the rules you declare in the diagram itself.

studio / processes / provisioning-order · v3 IN_PROGRESS
▶Start
startCOMPLETED
⇄Validate (API)
action · crawlerCOMPLETED
◷Await payment
wait · eventWAITING · ttl 120s
◆Amount > €1,000?
gatewayNEXT
☷Human review
task · inbox—
■End
end—
!Notify operations
exception →handled
// What it's for

Processes that today live in email threads, spreadsheets and scattered scripts.

Process Orchestrator turns them into executable, coordinated, auditable flows.

⚙

Automate flows

Work that today runs on email, Excel or one-off scripts, executed reliably and repeatably.

⇄

Coordinate systems

CRMs, ERPs and SaaS APIs orchestrated with no glue code in between.

◷

Wait on the real world

A signature, a confirmed payment, an IoT event — the flow resumes on its own when it lands.

▤

Audit everything

Every step is logged with who, when and why. Full traceability.

↺

Recover from errors

Automatic retries, exception connectors and TTL — without losing work.

// Execution model

Four entities. Get these and everything clicks.

From the design you draw in Studio to every concrete step the engine executes and records.

DESIGN
ProcessDefinition

The process you draw: nodes, connectors, properties. No runtime state. Versioned and immutable once published.

→
EXECUTION
ProcessInstance

One specific run of one version. It has context, state and timings. Thousands can run at once, independently.

→
CURSOR
TokenInstance

The cursor that advances through the graph. It splits at a parallel fork and merges at a join. Its state rolls up into the instance's.

→
STEP
NodeInstance

One node executed by one token, with inputs, outputs and timings. What you see in the viewer when you inspect an instance.

Reactive engine: the engine never blocks threads while waiting. State lives in the database; threads are ephemeral — a single instance holds tens of thousands of waiting processes at a time.
// Node types

The primitives you actually need in production.

Our own model: simpler than BPMN 2.0, and far more explicit about errors and timing.

▶start

Kicks off the instance. Runs exactly once.

→ COMPLETED
☷task

Human task. Creates an inbox entry and waits for someone to complete it.

WAITING → COMPLETED
⇄action

External integration (HTTP/JDBC/FTP/SaaS). Delegates to the crawler.

WAITING → COMPLETED · ERROR_HANDLED
◷wait

Waits for a real-world event or for a set amount of time.

WAITING / SCHEDULED → COMPLETED
◆gateway

Decision, fork or join. Evaluates conditions and branches the token.

→ COMPLETED
{}script

Runs an inline expression to transform context variables.

→ COMPLETED
↻loop

Iterates over a collection until it is exhausted.

→ COMPLETED
■end

Marks an end point and closes the token.

→ COMPLETED
// Error tolerance

An error isn't something to avoid. It's just another branch of the diagram.

When something fails, the state is recorded and the engine looks for the recovery branch you declared. Nothing gets lost.

connection
Happy path

The default: followed when the node finishes successfully.

exception
Something failed

An unhandled exception or an ERROR state. The node is marked handled and the token carries on down this branch.

maxRetries
Retries exhausted

For action only: the maximum number of attempts was reached. Route it, for example, to a human review queue.

expired
Patience ran out

For wait and action: the node's TTL expired and the flow takes an alternate route.

"Every recoverable failure must be modeled explicitly in the design."

Model it and the flow recovers on its own. Don't, and the token sits in error waiting for manual intervention — and an operator can always retry any node from Studio. A safety net (DLQ) catches whatever isn't even interpretable.

ERROR_HANDLED MAX_RETRIES_HANDLED TTL_EXPIRED_HANDLED ERROR TTL_EXPIRED
// TTL and cancellation

A patience limit on every node.

TTL isn't a timeout for killing long-running jobs: it's the way out of waits that drifted into limbo. On expiry, the engine cancels the in-flight work automatically.

1
action(ttl=120s)The token arrives and waits on the crawler. expires_at = now + 120s is recorded.
2
watchdog @ 30sEvery 30s it scans for expired subscriptions. It spots that the event never arrived in time.
3
cancel.actionPublishes a cancellation: the crawler job moves to CANCELLED and stops retrying.
4
expireFromWaitThe token takes the expired branch if there is one; otherwise it lands in TTL_EXPIRED.
API call to a fast system60–300 s
Waiting on a human reply (email)≈ 1 day
Infrequent event (monthly)≈ 30 days
Critical action that must never hangnever without a TTL

// TTL counts wall-clock time; max_attempts counts attempts. They are independent and they combine.

// Architecture

Not a monolithic app: services that cooperate over messaging.

Failure isolation, independent scaling and the right language for each problem. If the component calling an ERP goes down, the engine keeps going and the jobs are retried when it comes back.

engine Java · Spring

Runs processes: receives events, moves tokens, picks branches and persists state.

process-manager repository

Versioned definitions. Multi-tenant. Only the engine reads from here.

crawler Quarkus · Camel

Runs external integrations (HTTP/JDBC/FTP) on demand from the engine.

studio TypeScript · Lit

Design processes, monitor instances and manage tasks, all in the browser.

⟷   message bus · SQS / ElasticMQ — FIFO queues by correlationKey   ⟷
watcher Node.js

Wakes tokens that are sleeping on time (waits like "wait 2 days").

listener in design

Receives external webhooks and translates them into events for the engine.

db PostgreSQL

Shared durable state. The system's source of truth lives here.

guarantee at-least-once

End-to-end delivery with idempotent handlers. Effectively exactly-once.

// Operate with confidence

Publishing never breaks what's already running.

// Versioning and publishing

Immutable versions

Only one version is active per process. Live instances keep running the version they started on — swapping the graph mid-flight would be a broken promise.

v1ARCHIVED — historical, only for its own instances
v2ARCHIVED — instances that started on it stay on it
v3ACTIVE — the one that starts new instances
// Security and auditing

Bearer JWT over OAuth2 / OIDC

Standard authentication with swappable identity providers, plus per-organization isolation in the process repository.

Multi-tenant

Each organization sees only its own processes, folders and datasources. Isolation by organization_id.

Swappable identity

Amazon Cognito or ZITADEL (self-hosted), depending on the environment.

Traceability by design

Every state transition is logged with timings, attempts and errors.

// Low-code, with judgment

Visual for 95% of the work. Code-light where it pays off.

Flows are designed in a visual editor, with no engine programming. Integration with a new system is modeled once, then reused everywhere.

PROFILE · ANALYST

Process designer

Drag, connect and configure properties. Models the flow and its error branches without writing code.

100% visual
PROFILE · IT

Integrator

Defines one YAML (Camel) connector per new external system. Once per system, not per process.

code-light · 1 YAML/system
PROFILE · PLATFORM

Developer

Extends the engine through plugins (error policies, validation, observability) for advanced cases only.

code · rare cases
// Let's talk

Put your processes to work.

We'll walk you through Process Orchestrator with a real process from your business — and how Wattyo's consulting takes it to production.