Note: (as per 7.5.1)

As per version 7.5.1 the clustering support has been refactored and pulled into a separate module. By default ebean-cluster is included as a dependency and uses TCP sockets for cluster communication.


When Ebean servers are running in a cluster then it is the job of the clustering support to:

  • Notify L2 cache invalidation events
  • Notify BeanPersistListeners (of remote insert/update/delete events)

When a transaction commits the events that will result in cache invalidation or have registered BeanPersistListeners are collected into a RemoteTransactionEvent and this event is broadcast to all the members in the cluster. Each member then processes the event invalidating parts of the local L2 cache and invoking listeners as necessary.


Internally Ebean has a container whose job is to create EbeanServer instances and to manage cluster communication (like TCP sockets). The container has access to all the EbeanServer instances it creates and can access them by name. The EbeanServer name is included in the cluster messages and is used to identify which EbeanServer needs to process any given cluster message.

L2 cache invalidation

For details on L2 cache invalidation refer to Table IUD invalidation and Bean IUD invalidation.

If a bean type is not using L2 bean cache or L2 query cache and that bean type also does not have a BeanPersistListener registered then bean persist events for that type (Bean insert, update and delete) are not sent across the cluster (as there is no L2 cache invalidation required).

Cluster message

The message send around the cluster is a RemoteTransactionEvent which contains information for Table IUD bulk changes and Bean IUD events.

Each message contains the

EbeanServer name

The name of the EbeanServer the message relates to.

Table IUD details

For bulk table insert, update or delete events the message contains the table name and boolean flags for insert, update and delete.

Bean IUD details

For bean insert, update or delete events the message contains the bean type (class name) and a list of id values for inserted, updated and deleted beans.


By default clustering support is included via a dependency on ebean-cluster so we just need to configure it. The example properties below show the configuration for a 3 node cluster.

## the host:port for this node

## all the members of the cluster

Each member of the cluster should configure their unique localHostPort value.

The cluster configuration is per container and not per EbeanServer instance. The EbeanServer name is part of the message sent around the cluster and is used to get the correct EbeanServer instance to process each message.


At INFO level logging on org.avaje.ebean.Cluster messages are output when clustering starts, stops and members leave or join.

Startup configuration
INFO  org.avaje.ebean.Cluster - Clustering using local[] members[[,]]
INFO  org.avaje.ebean.Cluster - Register as online with member [localhost:9942]
Member joining/leaving
INFO  org.avaje.ebean.Cluster - Cluster member [localhost:9943] online[true]

At DEBUG level messages are logged for sending and receiving events.

Sent message
DEBUG org.avaje.ebean.Cluster - sending: [org.example.domain.Customer updateIds:[4]]
Received message
DEBUG org.avaje.ebean.Cluster - processing [org.example.domain.Customer updateIds:[4]]


The BeanPersistListener listens for committed bean events.

These listen events occur after a successful commit. They also occur in a background thread rather than the thread used to perform the actual insert update or delete. In this way there is a delay between the commit and when the listener is notified of the event.

For a cluster these events are broadcast to support the remoteInsert(), remoteUpdate() and remoteDelete() methods.

External modification

You use ebeanServer.externalModification() to notify Ebean that beans have been committed externally using raw JDBC, some other framework like Spring JDBC or some other process.

This translates directly into a Table IUD message that is sent around the cluster to invalidate L2 cache as appropriate.