Camunda is a platform for modeling and running business processes. Its Workflow Engine supports BPMN, while its Decision Engine supports DMN. Our experience described here focuses on the Workflow Engine and the way we have used it to coordinate microservices and human work.
How We Use Camunda Workflow Engine
Our main use case combines two common responsibilities:
- Orchestrating calls between independent microservices
- Managing tasks that must be completed by people
In one project, several small services each handle a narrow responsibility and know as little as possible about one another. Imagine separate services for users, orders, and invoices. When an invoice must be created, the invoice service does not directly call the user and order services. Instead, Camunda coordinates the process.
At the invoice step, the workflow retrieves the customer data, retrieves the order data, and then calls the invoice service with the information it needs. The process model shows the order of these actions and the conditions under which each one runs.
Service Tasks for Microservice Orchestration
Camunda represents automated work as a service task. Service tasks can be implemented as internal Java delegates or as external tasks that independent workers poll and execute.
We have mainly used internal service tasks. Keeping the implementations close to the workflow code makes them easier to discover and maintain in our project. An internal task is implemented by a Java class that uses the required interface and is referenced by the task in the BPMN diagram.
Camunda can also call REST endpoints directly from a workflow. We chose Java delegates instead because a consistent implementation style makes the codebase easier to understand and test.
User Tasks for Human Work
A user task represents work that a person must complete. Continuing the order example, preparing and consolidating an order for shipment is a human task rather than an automated service call.
Our back-office application receives new tasks through a RabbitMQ queue and displays them to employees. Through the Workflow Engine REST API, tasks can be claimed, released, postponed, completed, and queried.
This removes the need for employees to track ownership manually. A person claims a task, performs the work, and marks it complete. Camunda then advances the process to the next step. Candidate users and groups can be configured so that each type of task appears only to the appropriate people.
Events, Timers, and Gateways
BPMN provides timers, messages, conditional gateways, boundary events, and other elements for controlling process behavior. These can be used to send reminders, wait for external events, branch according to business rules, or skip tasks that are not required.
A simplified order workflow might look like this:
Benefits of Using Camunda
Business Processes Become Visible Early
A process can be drawn before the full implementation exists. That gives business and technical stakeholders a shared view of the flow and makes missing steps, unclear responsibilities, and bottlenecks easier to identify.
Finding those problems before development begins saves both time and money. The BPMN diagram also gives non-technical stakeholders a concrete way to explain and review how the application should behave.
Once implementation starts, the process model becomes living documentation. Because the engine executes the same diagram, the documentation is less likely to drift away from reality.
New Steps Are Easier to Add
Adding a new activity usually begins with updating the business flow. After the process is correct conceptually, the team adds the corresponding BPMN elements and implements any service-task logic.
This does not remove the need for careful design, but it gives changes a visible structure and keeps the end-to-end process understandable.
Useful Features Are Built In
Camunda includes many capabilities that would otherwise require custom development:
- Timers and messages for controlling process execution
- Automatic retries for failed service tasks
- Java APIs for application integration
- Human-task management
- REST APIs for external systems and operational tools
- Process-instance and incident visibility
The REST API documentation has been particularly useful. We use the API both for integration and for troubleshooting process instances that do not move through the workflow as expected.
Cockpit Helps With Operations
Camunda Cockpit shows deployed process versions, active instances, current steps, and incidents. It provides many of the same operational actions available through the REST API.
When a process fails, Cockpit often provides enough context to identify the problem without searching through large volumes of logs. That shortens incident investigation and makes the workflow state visible to the support team.
Camunda also offers an enterprise edition with more advanced operational and analytical features. We have not needed it because the community edition has met our requirements.
Camunda Challenges and Trade-Offs
The main challenge is process versioning. Deploying an updated BPMN model creates a new process definition, but existing process instances normally continue running in the version where they started.
Suppose we add a service task that saves payment details between the payment and invoice steps:
After deployment, the system has both the old and new process versions. Orders can then be in several different situations.
New Process Instances
An order that has not started a process yet is the simplest case. When its process begins, Camunda uses the latest deployed version.
Old Instances Before the Changed Step
An order may still be running in the previous process version and may not yet have completed the payment step. If it continues without migration, it will skip the newly added “Save payment details” task because that step does not exist in its version.
Camunda supports process-instance migration, but migration plans are not always simple or worth the operational risk. In this example, accepting that the customer may need to enter payment details again on a future order can be safer than migrating active instances.
Old Instances After the Changed Step
Migration becomes harder when an instance is already beyond the place where the new task was inserted. Moving it backwards could repeat completed business actions and create a mismatch between the workflow state and reality.
For that reason, we generally avoid migrating active instances unless the business impact makes migration necessary. Older process versions eventually disappear naturally after their remaining instances finish.
Code Must Support Older Process Versions
Camunda versions BPMN diagrams, but it does not automatically preserve old versions of Java delegate code. A delegate that appears unused in the latest process may still be required by an older process instance.
Imagine removing the “Save payment details” task and deleting its delegate. The latest workflow no longer needs the class, but active instances in the previous deployment still do. Removing it too early can cause those instances to fail.
Our approach is to mark such delegates as deprecated rather than deleting them immediately. We periodically review older deployments, remove those with no active instances, and then delete the code that is genuinely no longer used.
The broader lesson is that every process change must be evaluated against active historical versions. Teams usually become comfortable with this over time, but it is easy to overlook at the beginning.
When Does Camunda Make Sense?
Camunda is not automatically the right choice for every application. A simple monolith with no human tasks and no meaningful process flow may gain little from a workflow engine.
It becomes more valuable when a system has:
- A clear business process with several stages
- Human tasks that need assignment and tracking
- Multiple services that must be coordinated
- Timers, retries, messages, and conditional paths
- A need for operational visibility into long-running work
Our project had both microservices and strict process flows with user tasks, so Camunda was a good fit. We would use it again when a future project's requirements justify the added platform and process-versioning complexity.
