scalecube-services turns a plain Java interface into a clustered service
Microservices library - scalecube-services is a high throughput, low latency reactive microservices library built to scale. It features: API-Gateways, service-discovery, service-load-balancing, the architecture supports plug-and-play service communication modules and features. built to provide performance and low-latency real-time stream-processing
At a glance
- What is it?
- The scalecube/scalecube-services library provisions Java interfaces as services across a SWIM based peer to peer cluster, with pluggable transports, encoders and API gateways. It is aimed at real time stream processing on a .NET style reactor stack, and it expects you to accept a mesh architecture with no broker.
- Who is it for?
- Adopt scalecube-services when you want to expose Java interfaces across a cluster of JVM peers with streaming semantics and no broker, and when a reactor based stack is already your baseline. Do not adopt it if you need the operational familiarity of a broker, a mainstream service mesh, or a managed platform, since the README is explicit that the design is a fully mesh, brokerless architecture.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A service is an annotated interface, nothing more
The design decision that defines this library is that a service carries no framework type. You declare an interface, annotate it, and the library provisions it. The example in the README shows the whole contract.
@Service("io.scalecube.Greetings")
public interface GreetingsService {
@ServiceMethod("sayHello")
Mono<Greeting> sayHello(String name);
}The implementation is an ordinary class with an ordinary method, and the return type is a Project Reactor Mono.
public class GreetingServiceImpl implements GreetingsService {
@Override
public Mono<Greeting> sayHello(String name) {
return Mono.just(new Greeting("Nice to meet you " + name + " and welcome to ScaleCube"));
}
}Return types are what decide the communication pattern. The README lists four of them: fire and forget, request response, request stream and request bidirectional. A Mono return gives request response, a Flux return gives a stream of responses, and a Flux parameter gives bidirectional streaming.
@Service
public interface ExampleService {
@ServiceMethod
Mono<String> sayHello(String request);
@ServiceMethod
Flux<MyResponse> helloStream();
@ServiceMethod
Flux<MyResponse> helloBidirectional(Flux<MyRequest> requests);
}So the reactive types are not decoration. They are the API surface, and the same interface can host all four patterns side by side.
Two nodes, a seed member and a service member
The quickstart provisions two cluster nodes and makes one remote interaction across them. The mechanics matter more than the sample itself. The first node is a seed, which is a member node that provisions no services of its own. The second node joins that seed and provisions a service instance. A proxy is then created from the seed node by the service API and a greeting request is sent.
//1. ScaleCube Node node with no members (container 1)
Microservices seed = Microservices.builder()
.discovery("seed", ScalecubeServiceDiscovery::new)
.transport(RSocketServiceTransport::new)
.startAwait();
// get the address of the seed member - will be used to join any other members to the cluster.
final Address seedAddress = seed.discovery("seed").address();The second node points its discovery at the seed address and registers the service implementation.
//2. Construct a ScaleCube node which joins the cluster hosting the Greeting Service (container 2)
Microservices serviceNode = Microservices.builder()
.discovery("seed", ep -> new ScalecubeServiceDiscovery(ep)
.membership(cfg -> cfg.seedMembers(seedAddress)))
.transport(RSocketServiceTransport::new)
.services(new GreetingServiceImpl())
.startAwait();Every peer needs the seed address to join, which is the one piece of bootstrap configuration the library cannot remove.
Calling a service is a fluent proxy built from the interface
The client side is a proxy derived from the same interface, obtained from any node in the cluster rather than from the node that hosts the implementation. The proxy call returns a reactive type, and consuming it is what actually sends the request.
//3. Create service proxy (can be created from any node or container in the cluster)
// and Execute the service and subscribe to incoming service events
seed.
call().
api(GreetingsService .class)
.
sayHello("joe").
subscribe(consumer ->{
System.out.
println(consumer.message());
});The README then closes the example by shutting both nodes down and awaiting them, which shows that the lifecycle is owned by the Microservices instance rather than by the JVM.
// await all instances to shutdown.
Mono.
whenDelayError(seed.shutdown(),serviceNode.
shutdown()).
block();Two details are worth copying into your own code. The proxy can be created from any node, so a caller does not need to know where the implementation lives, and the shutdown is awaited with whenDelayError so one failing node does not abort the shutdown of the other.
SWIM membership removes the need for a discovery service
The cluster membership protocol is the load bearing part of the design, and the README states it plainly: zero configuration, automatic peer to peer service discovery using the SWIM cluster membership protocol. That is what makes the seed and member arrangement in the example work. A node that learns the seed address joins, and the SWIM failure detector then tracks liveness across the mesh. The consequences are structural. The README claims no single point of failure and no single point of bottleneck, and it explains why that holds: the architecture is fully mesh and brokerless, so there is no central registry or message broker that can become the failure domain. The cost is equally structural, and the README is direct about it, describing the design as ideal for real time data processing, large scale distributed systems and environments where minimizing latency matters, but noting it delivers that without complex middleware setups. You are trading central infrastructure for peer to peer gossip, and the operational tooling for the latter is yours to build.
Transport, encoder and gateway are all pluggable points
The library is built from a small number of seams, and each one is replaceable. The feature list names pluggable API gateway providers over http, websocket and rsocket, pluggable service transports over tcp, aeron and rsocket, and pluggable encoders including json, SBE and Google protocol buffers. Security is pluggable too, with authentication and authorization providers named as an extension point. The repository layout mirrors these seams as separate Maven modules: services-api, services-discovery, services-gateway, services-security, services-transport-parent, services, plus services-examples and a docs directory. Because the transports include rsocket and aeron, and the encoder set includes SBE, this is aimed at systems that care about the cost per message rather than only about developer convenience. The API gateway side is where external traffic enters, and the README names the available gateways as rsocket, http and websocket.
Resilience is a property of discovery, not a separate library
Several of the advertised features are consequences of the membership design rather than independent mechanisms. The README lists built in failure detection, fault tolerance and elasticity, then adds a line that is worth reading carefully: natural circuit breaker via scalecube-cluster discovery and failure detector. In other words, there is no separate resilience layer to configure. A peer that fails is detected by the membership protocol, and the routing and balancing strategies then avoid it. Those strategies are said to work for both stateless and stateful services, which is a harder claim than it sounds, because a stateful service cannot simply have a request redirected to another instance. The feature list also covers service instance tagging, and service discovery partitioning using a hierarchy of namespaces for multi cluster deployments. That last one is the escape hatch for large organisations, since a single flat membership across regions is exactly the case where a gossip protocol starts to cost more than it saves.
The API surface is Reactor, and the documentation lives elsewhere
Reactor is not an optional choice here. The README explains that reactive microservices communicate via streams using asynchronous data flows, so services process and react to data as it arrives without blocking operations, and that this in practice involves technologies and protocols that support reactive streams, such as Reactor. Every example returns a Mono or a Flux, and the shutdown call returns a Mono that you block on. If your team is not already comfortable with Reactor semantics, the learning curve is the dominant cost of this library. The documentation itself is not in the repository README. The README links a user guide hosted at scalecube.github.io, with separate pages for the services overview, defining services, implementing services, provisioning clustered services and consuming services, and the project's homepage is scalecube.github.io. The repository also carries a docs/ directory and a requirements.txt pinning requests at version 2.33.0, which is a hint that the documentation tooling is Python driven.
Editorial conclusion
Adopt scalecube-services when you want to expose Java interfaces across a cluster of JVM peers with streaming semantics and no broker, and when a reactor based stack is already your baseline. Do not adopt it if you need the operational familiarity of a broker, a mainstream service mesh, or a managed platform, since the README is explicit that the design is a fully mesh, brokerless architecture. Verify first by pulling the io.scalecube artifacts from Maven Central, running the two node seed and member example, and confirming that release 2.13.33, published on 2026-10-20, matches the API your code expects.
Frequently asked questions
How do I define a service in scalecube-services?
A service is an interface annotated with @Service and its methods with @ServiceMethod, returning Reactor types. A Mono return gives request response, a Flux return gives a stream of responses, and a Flux parameter gives bidirectional streaming, so one interface can carry all four communication patterns.
How does scalecube-services handle service discovery without a discovery server?
The README describes zero configuration, automatic peer to peer service discovery using the SWIM cluster membership protocol. A node joins by pointing its discovery at a seed member's address, and the membership protocol then tracks peers and failures across a fully mesh, brokerless architecture.
Which transports and encoders does scalecube-services support?
The README lists pluggable service transports over tcp, aeron and rsocket, pluggable API gateway providers over http, websocket and rsocket, and pluggable encoders including json, SBE and Google protocol buffers. Authentication and authorization providers are also pluggable.
How does the two node seed example work in scalecube-services?
The seed node starts with discovery and transport configured and provisions no services. A second node joins the cluster by configuring membership with the seed address and registers a service instance through the services method. A proxy created from any node in the cluster then calls the service interface and the reactive result is subscribed to.
Does scalecube-services need a message broker?
The README describes the architecture as fully mesh and brokerless, with no single point of failure and no single point of bottleneck, so there is no central broker or registry. Failure detection and the circuit breaker behaviour come from the cluster discovery and failure detector rather than from separate infrastructure.
What licence is scalecube-services released under?
The project is licensed under Apache-2.0, with the licence stored in a file named LICENSE.txt at the top level of the repository alongside the Maven pom.xml and the services modules.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/scalecube-scalecube-services)Was this useful?