Evolution of the Camunda Platform

Camunda 7 emerged in an era where enterprise systems were largely monolithic or service‑oriented, and where workflow engines were embedded directly into application runtimes. It provides a Java‑centric programming model, synchronous APIs, and a relational database as the single source of truth for workflow state. This architecture is predictable, mature, and deeply integrated with Spring Boot, Java delegates, and synchronous REST interactions.

Camunda 8 was designed for a different world: distributed microservices, event‑driven architectures, and cloud‑native deployments. Instead of a relational database, it uses a replicated log and partitioned state. Instead of synchronous Java delegates, it uses external workers communicating over gRPC. Instead of embedding the engine inside your application, the engine runs as a standalone cluster.

The result is that Camunda 8 is not a drop‑in replacement for Camunda 7. It is a different orchestration paradigm.

Architectural Differences

Engine Model

Camunda 7 uses a stateful, transactional engine embedded in the JVM. Every workflow step is executed inside the same process, and the engine relies on ACID transactions to maintain consistency. This makes it ideal for synchronous, request‑response business processes.

Camunda 8 uses Zeebe, a distributed workflow engine built around a replicated log. Workflow state is partitioned across brokers, and commands are appended to a log rather than executed inside a single JVM. This enables horizontal scalability and high throughput, but requires a shift toward asynchronous, event‑driven design.

Persistence Layer

Camunda 7 stores workflow state in a relational database such as PostgreSQL or Oracle. This allows direct SQL access, custom queries, and transactional consistency. It also introduces bottlenecks at scale, because the database becomes the limiting factor.

Camunda 8 stores workflow state in a distributed key‑value store (RocksDB) embedded inside each Zeebe broker. State is replicated across partitions, and there is no central database. This eliminates the database bottleneck but removes the ability to query workflow state directly.

Execution Model

In Camunda 7, Java delegates run inside the engine:

public class ValidateCustomerDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        String customerId = (String) execution.getVariable("customerId");
        boolean valid = validate(customerId);
        execution.setVariable("isValid", valid);
    }
}

This model is simple, synchronous, and tightly coupled to the JVM.

In Camunda 8, workers are external and communicate with the engine asynchronously:

client.newWorker()
    .jobType("validate-customer")
    .handler((jobClient, job) -> {
        String customerId = job.getVariablesAsMap().get("customerId").toString();
        boolean valid = validate(customerId);

        jobClient.newCompleteCommand(job.getKey())
            .variables(Map.of("isValid", valid))
            .send();
    })
    .open();

This decouples workflow execution from business logic, enabling polyglot workers and horizontal scaling, but requires a different operational mindset.

Operational Characteristics

Camunda 7 is typically deployed as part of a Spring Boot application or as a standalone engine with a relational database. Operations revolve around JVM tuning, database performance, and managing synchronous workloads.

Camunda 8 is deployed as a cluster of brokers, gateways, and optional components such as Operate, Tasklist, and Optimize. Operations revolve around partitioning, replication factors, cluster sizing, and managing asynchronous workloads.

This difference is not cosmetic; it fundamentally changes how teams design, deploy, and monitor workflows.

Developer Experience

Camunda 7 offers a Java‑first programming model. Developers write delegates, listeners, and service tasks directly in Java. BPMN interacts tightly with the application codebase.

Camunda 8 offers a language‑agnostic model. Workers can be written in Java, Go, Node.js, Python, or any language with a Zeebe client. BPMN becomes a contract between services rather than an embedded component.

This shift encourages microservice boundaries and event‑driven patterns.

Example: Service Task Execution

Camunda 7

A service task is executed inside the engine:

<bpmn:serviceTask id="validateCustomer" camunda:class="com.example.ValidateCustomerDelegate" />

The engine loads the class, executes it, and persists the result in the same transaction.

Camunda 8

A service task is executed by an external worker:

<bpmn:serviceTask id="validateCustomer" zeebe:taskDefinition type="validate-customer" />

The engine creates a job, a worker picks it up, processes it, and completes it asynchronously.

This decoupling is essential for scalability but requires more infrastructure.

Migration Realities and Compatibility Gaps

Camunda 8 is not a drop‑in upgrade from Camunda 7. The engines differ in execution semantics, persistence models, APIs, and operational assumptions. Migration requires re‑architecting several layers of the system.

Key incompatibilities include:

  • Java delegates do not exist in Camunda 8. All service work must be performed by external workers.
  • Synchronous REST interactions must be redesigned as asynchronous job workers.
  • BPMN elements such as multi‑instance loops, timers, and error events behave differently due to Zeebe’s log‑based execution model.
  • Direct SQL queries against workflow state are no longer possible.
  • Embedded engine patterns disappear entirely; the engine is always remote.

A typical migration path involves rewriting service tasks, redesigning error handling, replacing listeners with job workers, and rethinking transaction boundaries. For example, a Camunda 7 process that relies on a single ACID transaction across multiple service tasks must be decomposed into idempotent, retry‑safe steps in Camunda 8.

A Camunda 7 service task:

public class ChargeAccountDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        String accountId = execution.getVariable("accountId");
        BigDecimal amount = new BigDecimal(execution.getVariable("amount").toString());
        accountingService.charge(accountId, amount);
    }
}

The equivalent Camunda 8 worker must be idempotent, stateless, and resilient to retries:

client.newWorker()
    .jobType("charge-account")
    .handler((jobClient, job) -> {
        Map<String, Object> vars = job.getVariablesAsMap();
        String accountId = vars.get("accountId").toString();
        BigDecimal amount = new BigDecimal(vars.get("amount").toString());

        accountingService.charge(accountId, amount);

        jobClient.newCompleteCommand(job.getKey())
            .variables(Map.of("status", "charged"))
            .send();
    })
    .open();

This shift is not cosmetic; it changes how developers think about workflow boundaries, retries, and consistency.

Performance Characteristics and Scaling Behavior

Camunda 7 scales vertically. The engine is bound by the performance of the JVM and the relational database. Increasing throughput typically requires:

  • faster CPUs,
  • more memory,
  • database tuning,
  • connection pool optimization.

Camunda 8 scales horizontally. Zeebe partitions workflow state across brokers, and each partition processes commands independently. Throughput increases by adding brokers and partitions. This makes Camunda 8 suitable for high‑volume orchestration scenarios such as:

  • order processing pipelines,
  • IoT event workflows,
  • large‑scale microservice orchestration,
  • long‑running distributed transactions.

However, horizontal scaling introduces operational complexity. Teams must manage:

  • partitioning strategies,
  • replication factors,
  • broker failover,
  • snapshotting and log compaction,
  • gRPC connectivity between workers and brokers.

Camunda 7’s operational model is simpler but less scalable. Camunda 8’s model is more scalable but requires deeper operational maturity.

Error Handling and Reliability Differences

Camunda 7 relies on database transactions for consistency. If a delegate fails, the transaction rolls back and the engine retries. This model is intuitive but tightly couples workflow execution to the application runtime.

Camunda 8 uses a command log. Failures do not roll back state; instead, the engine records a new command representing the failure. Workers must be idempotent and capable of handling retries without relying on transactional rollbacks.

For example, a Camunda 7 boundary error event:

<bpmn:serviceTask id="charge" camunda:class="ChargeAccountDelegate">
  <bpmn:boundaryEvent id="chargeError" attachedToRef="charge">
    <bpmn:errorEventDefinition errorRef="ChargeError" />
  </bpmn:boundaryEvent>
</bpmn:serviceTask>

In Camunda 8, the worker must explicitly throw an error:

jobClient.newThrowErrorCommand(job.getKey())
    .errorCode("CHARGE_ERROR")
    .errorMessage("Insufficient funds")
    .send();

This difference affects how teams design compensating actions, retries, and failure semantics.

Use Cases Where Camunda 7 Remains the Better Fit

Despite the industry shift toward cloud‑native architectures, Camunda 7 remains the correct choice for several categories of systems:

  • monolithic enterprise applications,
  • synchronous request‑response workflows,
  • systems requiring strong ACID consistency,
  • environments where direct SQL access to workflow state is essential,
  • organizations without the operational capacity to manage distributed clusters.

Camunda 7’s embedded engine model is particularly effective when workflows must execute within the same transaction as business logic.

Use Cases Where Camunda 8 Is the Superior Choice

Camunda 8 excels in distributed, event‑driven, and high‑throughput environments:

  • microservice orchestration,
  • long‑running sagas,
  • cloud‑native deployments,
  • high‑volume asynchronous workflows,
  • systems requiring horizontal scalability.

Its external worker model enables polyglot development and decouples workflow execution from business logic, making it suitable for heterogeneous architectures.

Choosing the Right Engine

The decision between Camunda 7 and Camunda 8 is not about version numbers; it is about architectural alignment. The following considerations guide the choice:

  • If your system is monolithic, synchronous, or transaction‑heavy, Camunda 7 aligns better.
  • If your system is distributed, asynchronous, or requires horizontal scaling, Camunda 8 is the natural fit.
  • If your team relies heavily on Java delegates and embedded engine patterns, Camunda 7 minimizes disruption.
  • If your team embraces microservices, event streams, and polyglot workers, Camunda 8 provides the right abstractions.

The engines serve different architectural eras, and both remain relevant.

Summary

Camunda 7 and Camunda 8 represent two distinct workflow orchestration paradigms. Camunda 7 is a mature, embedded BPM engine optimized for synchronous, transactional workflows within monolithic or service‑oriented architectures. Camunda 8 is a distributed, cloud‑native orchestration platform built on Zeebe, designed for asynchronous microservices, event‑driven systems, and horizontal scalability. Migration between the two requires architectural redesign rather than version upgrades. The correct choice depends on system architecture, operational maturity, and workflow characteristics.

Posts created 13

Leave a Reply

Your email address will not be published. Required fields are marked *

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top