Operate a fleet
This guide lists the clients a gateway serves, removes one client, spreads NATS connections again after a NATS restart, and cuts off a fleet. A fleet is a NATS account. The admin subjects reference has each request and reply.
Before you start, you need:
- Gateways with an admin account. See Set up the admin account.
- The
natsCLI, with the operator user in the admin account.
1. Find the gateways
Each gateway has an id. Set it with --id. Without --id, the gateway
picks one and logs it at start.
To find every gateway that serves your fleet, here FLEET_A, send info
on the account's subject:
nats req '$MQG.admin.account.FLEET_A.info' '' --replies 0 --timeout 1s
Each gateway replies with its id, version, start time and client counts.
To find every gateway, send $MQG.admin.ping.info instead.
2. List the clients
nats req '$MQG.admin.account.FLEET_A.list' '' --replies 0 --timeout 1s
Each gateway replies with the fleet's clients on it. Each client has its
connection id (cid), account, protocol, client ID, address, connect time
and NATS server:
{"id":"gw-1","clients":[{"cid":3,"account":"FLEET_A","protocol":"mqtt","client_id":"sensor-41","remote":"10.0.4.17:51122","since":"2026-10-08T09:12:44Z","nats_server":"n1"}],"count":1,"truncated":false}
To list one gateway, send list to $MQG.admin.server.<id>.list.
3. Remove one client
nats req '$MQG.admin.account.FLEET_A.kick' '{"client_id": "sensor-41"}' --replies 0 --timeout 1s
Each gateway replies. The reply {"id":"gw-1","kicked":true,"cid":3}
means that the disconnect started on gw-1.
- An MQTT 5 client gets "Administrative action".
- An AMQP client gets
amqp:connection:forced. - The gateway publishes the client's will.
The client can reconnect. To keep it out, revoke its credential.
If a client ID matches more than one connection, the gateway refuses the
kick. This can happen with AMQP container IDs. Kick by cid on the
gateway that serves the client instead:
nats req '$MQG.admin.server.gw-1.kick' '{"cid": 7}'
Rebalance after a NATS restart
When you restart NATS servers one at a time, client NATS connections move to the other servers. The last server you restart gets none of them back. To count the connections on each server:
nats req '$MQG.admin.server.gw-1.list' '{"account": "FLEET_A"}' | jq -r '.clients[].nats_server' | sort | uniq -c
To move connections to the empty server, here n3:
nats req '$MQG.admin.server.gw-1.rebalance' '{"account": "FLEET_A", "server": "n3", "over": "2m"}'
The gateway moves enough connections to give n3 an equal share. To set a
different number, add max. over spreads the moves over time. Clients
stay connected while their NATS connections move. The gateway logs
rebalance finished at the end.
If n3 is down or in lame duck mode, the gateway refuses the request and
gives the reason.
Send rebalance to each gateway, for each account. Each request moves only
the clients of one account on one gateway.
Revoke a user or a fleet
Remove the user from the NATS server config, or revoke its JWT. Then reload the server:
nats-server --signal reload
In operator mode, use nsc revocations add-user and push the account.
NATS closes every connection of the user. The gateway then disconnects those clients within a few seconds:
- An MQTT 5 client gets "Not authorized".
- The gateway publishes each will.
- A revoked client that reconnects gets "Not authorized".
Other fleets are not affected, because their clients act as other users.
Stop serving a fleet
Remove the account's credential from accounts in the config file. Then
restart the gateways, as in Change the config.
Check it works
- After a kick,
listno longer shows thecid. - After a rebalance, the
jqcount shows connections onn3. - After a revoke, the revoked clients are no longer in
list.