> ## Documentation Index
> Fetch the complete documentation index at: https://simplecloud.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Route players with autoscaling

> Send a player to an available server without managing group capacity yourself

When a player needs a server, query the group for available capacity and connect them to the least-loaded instance.

<Note>
  Let SimpleCloud manage the number of servers in a group. This workflow only chooses from instances that are ready now.
</Note>

## Route a player to a group

The following router finds playable servers in a group, ignores full instances, and attempts one connection. It returns `NoCapacity` when no suitable server is available and `ConnectionAttempted` with the result from `CloudPlayer.connect` otherwise.

```java GroupRouter.java theme={null}
package com.example;

import app.simplecloud.api.CloudApi;
import app.simplecloud.api.player.CloudPlayer;
import app.simplecloud.api.server.Server;
import app.simplecloud.api.server.ServerQuery;
import app.simplecloud.api.server.ServerState;

import java.util.Comparator;
import java.util.concurrent.CompletableFuture;

public final class GroupRouter {
    private final CloudApi api;

    public GroupRouter(CloudApi api) {
        this.api = api;
    }

    public CompletableFuture<RouteResult> routeToGroup(
        CloudPlayer player,
        String groupName
    ) {
        ServerQuery query = ServerQuery.create()
            .filterByServerGroupName(groupName)
            .filterByState(ServerState.AVAILABLE, ServerState.INGAME);

        return api.server().getAllServers(query).thenCompose(servers -> servers.stream()
            .filter(server -> server.getPlayerCount() != null)
            .filter(server -> server.getPlayerCount() < server.getMaxPlayers())
            .min(Comparator
                .comparingInt((Server server) -> server.getPlayerCount())
                .thenComparingInt(Server::getNumericalId))
            .<CompletableFuture<RouteResult>>map(server -> {
                String serverName = groupName + "-" + server.getNumericalId();
                return player.connect(serverName)
                    .thenApply(RouteResult.ConnectionAttempted::new);
            })
            .orElseGet(() -> CompletableFuture.completedFuture(
                new RouteResult.NoCapacity()
            )));
    }

    public sealed interface RouteResult {
        record NoCapacity() implements RouteResult {}

        record ConnectionAttempted(
            CloudPlayer.ConnectResult result
        ) implements RouteResult {}
    }
}
```

`AVAILABLE` and `INGAME` servers can accept players. Sorting by player count spreads new connections across the group, while the numerical ID gives the selection a stable tie-breaker.

The server name uses SimpleCloud's default `<groupName>-<numericalId>` registration pattern, such as `lobby-3`. If you changed the registration pattern, build the name with that same pattern here.

Handle `NoCapacity` by keeping the player in your queue or fallback lobby. For `ConnectionAttempted`, use the returned `ConnectResult` to confirm the connection or show an appropriate fallback.

## Next steps

* Use the [Groups API](/docs/en/developer/api/groups) to create and configure groups.
* Use the [event handling guide](/docs/en/developer/guides/event-handling) when your plugin should react as servers become available.
* See the [Servers API](/docs/en/developer/api/servers) for server queries, models, and lifecycle actions.
