COPPER Performance test

COPPER workflows are 100% pure Java so there is no performance penalty when processing data or calling partner systems in comparison to plain Java because it IS just Java. COPPER simply offers a runtime environment with processing queues, processor threads and a model for handling asynchronous responses efficiently. Also, in a persistent engine, COPPER offers crash safety, i.e. if the hosting server crashes, e.g. due to a power failure, the engine resumes the previously running workflow instances at their last checkpoint. COPPER Checkpoints are written whenever a workflow executes Workflow.savepoint or Workflow.wait. Workflow.savepoint simply persists the current state of the workflow instance to the underlying database and continues later on. Workflow.wait asynchronously waits for a response, e.g. when calling an asynchronous service of partner system X that returns a correlationId 'cid' for the final response, it's good practice in COPPER to wait for this response asynchronously using Workflow.wait(WaitMode.FIRST,0,cid). Workflow.wait(...) writes a checkpoint and registers the workflow instance for waiting for a response with a particular correlationId. As soon as the response arrives (using "engine.notify(...)) the workflow instance is resumed and the response is made available in it.

So when we are talking about performance in COPPER there are two separate concerns:

Processing performance

As stated before, workflows are written in Java which is processed by the underlying JVM, which is proven to be fast. The runtime environment is mostly using standard Java technologies from the java.util.concurrent package or simply synchronized and Object.wait/notify, so from our point of view there is no need to prove that this is fast.

Database performance

Most COPPER users are using a persistent engine, because they want their workflow instances to survive crashes, downtimes and restarts. So, the two major questions about COPPER database performance are To answer these questions, we have introduced an official COPPER performance test suite. This suite offers two different performance tests:


This test measures the average latency for executing a checkpoint in an otherwise idle system. To do so, the test executes workflow SavepointPerfTestWorkflow that invokes Workflow.savepoint() ten times, measuring the latency each time. The workflow is started several times (50 times by default) and the averagy latency time if all executions is measured.


This test measures the average number of checkpoins (using Workflow.wait/Engine.notify) a system can handle as follows: It starts a large number of WaitNotifyPerfTestWorkflow workflows and measures the time until the engine has completed their execution. Each of the WaitNotifyPerfTestWorkflow workflows simulates the communication with an external partner system by calling an adapter mock ten times. Each time its waiting for the response using Workflow.wait, so the workflow instances' state is persisted for ten times (plus one time when the initial workflow instance is enqueued at the beginning). At the end of the test, the average number of wait/notify cycles (checkpoints) is processed an printed on System.out.

Running the Performance Test

Executing the performance test is quite simple - its just an executable jarfile containing everything you need. It can handle all currently supported database systems, which are Apache Cassandra, Oracle, MySQL, Postgres, H2 and Derby. There are various configuration parameters available for the test - see its usage. The test and a description how to start it can be found here PERFORMANCE_TEST_HOWTO

Performance Test Results

COPPER 4.1.2-SNAPSHOT running on a small Apache Cassandra 2.1 cluster

Application Server


Latency Test

Finished performance test with 50 workflow instances in 5117 msec, avg latency is 4.175 msec
See corresponding Logfile, containing all used parameters.

Throughput Test

Finished performance test with 50000 workflow instances in 44130 msec ==> 11330 wait/notify cycles per second
See corresponding Logfile, containing all used parameters.