Concepts & architecture
This page explains the core concepts behind Quarkus Flow, its internal architecture, and how it maps to the CNCF Serverless Workflow Specification.
The Build-Time Engine Paradigm
Unlike traditional workflow engines that parse XML or YAML at runtime and rely on heavy database polling, Quarkus Flow leans entirely into the Quarkus "Ahead-of-Time" (AoT) philosophy.
Build-Time Discovery
When you compile your application, the Quarkus Flow extension scans for classes extending Flow or for YAML definitions in your resources. It parses the fluent Java DSL (or YAML) and compiles it directly into a WorkflowDefinition CDI bean.
Fast Runtime Execution
Because the workflow definition is already compiled and injected, the runtime engine does not need to parse models or use reflection. It simply executes the task sequence. This results in incredibly fast startup times and a minimal memory footprint, making it ideal for serverless environments.
Specification Alignment
Quarkus Flow uses the CNCF Serverless Workflow specification as its foundational vocabulary. When you write a flow using the Java DSL, you are programmatically generating a CNCF-compliant model.
-
Workflow (Flow): The overarching container representing the process.
-
Task: A distinct step in the workflow (e.g., executing a function, waiting for an event, or evaluating a condition).
-
Transition: The defined path moving the execution from one Task to another.
-
Context (Data): The JSON payload (or Java object) that is passed, transformed, and enriched as it moves through the Tasks.
Core Engine Mechanics
Execution & Threading
Quarkus Flow is designed to be non-blocking. When a workflow hits a wait task (like a timer or waiting for a message), the execution thread is released back to the Quarkus worker pool. The workflow state is serialized and persisted. Once the resume condition is met, a new thread picks up the state and continues execution.
Event Filtering
A major strength of the engine is its ability to route asynchronous events to the correct, paused workflow instance.
When a workflow enters an event-waiting (listen) state, it defines an Event Filter. This allows you to describe exactly how you want to filter incoming events directly within the listen task. You can filter based on the CloudEvent type, specific CloudEvent extensions, or the underlying CloudEvent data. When a message arrives via your messaging broker (like Kafka) that matches your defined filter criteria, the engine routes the payload directly to the correct execution and wakes it up.
Agentic AI Topology
Quarkus Flow treats LangChain4j Agents as native task workers. Conceptually, an AI orchestration is not a separate engine; it is integrated directly into the standard workflow lifecycle.
-
LLM Calls as Tasks: Requesting a generation from an LLM is treated as call task. The workflow passes the current context to the prompt and waits for the response.
-
Structured Outputs: Because the workflow context is typed, LLM responses can be mapped directly into pure Java Records, ensuring the workflow continues with strictly structured data.
-
Human-in-the-Loop (HITL): For agentic loops requiring human oversight, the workflow can be designed to transition to a paused event-wait task. The AI’s output is held in the context until a human explicitly emits a continuation event (often via a REST endpoint or event), demonstrating the synergy between standard event correlation and AI guardrails.
Integration Points
The engine relies on the broader Quarkus ecosystem to do the heavy lifting for external communications:
-
HTTP & OpenAPI: Uses RESTEasy Reactive to perform non-blocking HTTP calls. (See Call HTTP services).
-
Messaging: Uses SmallRye Reactive Messaging to consume and emit CloudEvents to brokers like Kafka or RabbitMQ. (See Use messaging).
-
AI & LLMs: Uses the Quarkus LangChain4j extension to inject AI services directly into tasks. (See Agentic workflows).
What’s next?
-
To see these concepts in action, head to Getting Started.
-
For a quick reference of the DSL methods mapping to these tasks, see the Java DSL Cheatsheet.