Relay Docs
Access & governance

Agents

The brokers that carry every governed connection, who runs them, how many replicas they run, and which teams use them.

An agent brokers database traffic for your workspace. When a member connects, the agent opens a local proxy, applies masking and policy, and forwards queries to the real database.

An agent runs as one or more replicas: identical processes that share the work. One or more agents serve each connection. When a member opens a tunnel, the server picks one replica of those agents to carry it.

Every workspace has an agent named default. You can't delete it.

Managed and self-hosted agents

An agent is one of two kinds:

  • Managed. Relay runs the agent's replicas in your workspace's cluster and keeps them up to date. The default agent is a managed agent.
  • Self-hosted. You run the agent's replicas, for example inside your own network. They join the agent with an enrollment token bound to it.

Use a managed agent when Relay can reach the database: over the internet with an IP allowlist, or through a private endpoint. Use a self-hosted agent when only machines inside your network can reach it.

Each managed agent has its own public endpoint on port 443, over TLS. relay connect dials it for you. <segment> is your workspace's DNS segment.

AgentPublic endpoint
defaultagent.<segment>.db.userelay.sh
Any other managed agentagent-<name>.<segment>.db.userelay.sh

Managed agents don't count toward your plan's self-hosted agent limit, and there is no cap on them today. Self-hosted agents count. See Plan limits.

Status and replicas

relay agents list shows one row per agent:

> relay agents list
NAME       TYPE         STATUS    REPLICAS  VERSION
default    managed      online    2/2       c6db801
office-vm  self-hosted  degraded  2/3       c6db801

An agent's status comes from its online replicas and its expected replica count:

StatusMeaning
onlineAt least the expected number of replicas is online. Without an expected count, at least one is.
degradedSome replicas are online, but fewer than expected.
offlineNo replica is online.

REPLICAS shows online replicas over the expected count, for example 2/3. Without an expected count, it shows only the online count.

The expected count is the minimum replicas of a managed agent. A self-hosted agent has one only if you set --expected-replicas. See Expected replicas.

-o wide adds the SCALING, CONNECTIONS, TEAMS and DESCRIPTION columns.

To see an agent's replicas, run relay agents get:

> relay agents get default
REPLICA                       STATUS  VERSION  TUNNELS  LAST HEARTBEAT
relay-agent-79db57855-6qf4z   online  c6db801  0        2026-10-23 16:59:20

-o wide adds the ADDR, MAX TUNNELS and CREATED AT columns.

In the dashboard, the Agents page lists each agent with its type, status, replicas, teams and connections. An agent's page shows its replicas, a Size card with the minimum and maximum replicas of a managed agent or the expected replicas of a self-hosted one, and its teams.

Create a managed agent

To create a managed agent, pass --managed:

relay agents create edge --managed
relay agents create burst --managed --min-replicas 2 --max-replicas 10
  • The name must be a DNS label: at most 40 lowercase letters, digits, or hyphens, starting and ending with a letter or a digit.
  • A managed agent runs from 1 to 50 replicas. Without --min-replicas and --max-replicas, it runs 1.
  • If the minimum equals the maximum, the agent runs that many replicas. If the minimum is lower, the agent scales between the two on CPU use.
  • --description sets a free-text description.

Relay creates the agent's enrollment token and starts its replicas. The token appears in relay enrollment-tokens list with a name that starts with managed:. Don't delete it: the agent's replicas use it when they restart.

An Agent Edition control plane has no managed agents. There, the command fails with managed agent pools are not available on this control plane.

Resize a managed agent

To change the number of replicas, run relay agents update:

relay agents update burst --min-replicas 2 --max-replicas 20
relay agents update edge --min-replicas 3 --max-replicas 3

The same limits apply as at creation. --min-replicas and --max-replicas apply only to managed agents.

Create a self-hosted agent

  1. Create the agent. --expected-replicas is optional:

    relay agents create onprem --expected-replicas 3
  2. Create an enrollment token bound to the agent:

    relay enrollment-tokens create --name onprem-agents --agent onprem

    --agent is required.

  3. Start each replica with the token. Every process joins the token's agent under its host name, so the same settings work for any number of replicas. See Settings for self-hosted agents.

An enrollment token is shown once when you create it. Save it somewhere safe — it can't be viewed again.

Use one token for all of an agent's replicas. A token is reusable unless you create it with --single-use, and it decides which agent a replica joins. A replica started with --pool set to any other agent gets enrollment token is bound to pool onprem.

To move a replica to another agent, stop it and start it with that agent's token. It joins there as a new replica. Remove the old one with relay agents replicas delete <agent> <replica>.

To get the agent binary and its installation guide, see Who runs the agent.

Expected replicas

--expected-replicas tells Relay how many replicas a self-hosted agent should run, from 1 to 50. It sets the agent's status and caps its replicas. To change or clear it, run relay agents update:

relay agents update onprem --expected-replicas 4
relay agents update onprem --expected-replicas 0

0 clears the expected count. Without one, the agent has no cap.

With an expected count, the agent refuses a new replica once expected + 1 replicas are online. The one extra lets a rolling restart or a replacement come up before the old replica stops. A replica that enrolls again under a name it already has doesn't count as new.

The refused process logs the error and keeps retrying, from 2 up to 30 seconds apart. Each refusal is written to the activity log, at most once every 10 minutes for each agent and replica name.

Replicas

Each process you start with an agent's token is one replica of that agent.

  • A replica's name defaults to its host name, which is the pod name in Kubernetes. Set --name only where host names aren't unique.
  • Names are unique within an agent. The same name in another agent is a separate replica.
  • Two running processes can't share a name. The second one gets agent <name> is already running in pool <pool> at <address> and keeps retrying, from 2 up to 30 seconds apart. It enrolls once the first process stops, or once the first misses heartbeats for 90 seconds after a crash.
  • A replica that restarts under its name takes its old place.

Delete an agent or a replica

To delete an agent:

relay agents delete onprem
  • You can't delete the default agent.
  • You can't delete an agent while connections use it. Remove it from each connection first.
  • A self-hosted agent must also have no replicas left. Stop its replicas, then remove them with relay agents replicas delete.
  • When you delete a managed agent, Relay stops and removes its replicas.

To remove one replica:

relay agents replicas delete onprem office-vm-2

Removing a replica does not stop proxies already running on it. A self-hosted replica that is still running enrolls again on its next start, since its token is reusable. To take a replica out of service, stop it first, then remove it. Delete or rotate the enrollment token if it must not come back.

Serve a connection from several agents

To serve a connection from several agents, give each agent a priority:

relay connections agents set pg-prod edge:10 burst:5

Each argument is <agent>:<priority>. The command replaces the connection's whole agent list.

  • The agent with the highest priority becomes the connection's main agent. On a tie, the agent listed first wins.
  • Each agent must exist in the connection's workspace and appear once. The list can't be empty.
  • relay connections update <name> --agent <agent> replaces only the main agent. The new main agent keeps the old main agent's priority.

Default connections of a managed database can have extra agents too, for example a team's agent.

Restrict an agent to teams

To reserve an agent for some teams, bind it to them:

relay agents teams set edge data-eng analytics

The command replaces the agent's team list. You can bind only teams from the agent's organization. An agent with no teams is unrestricted: anyone who may connect can use it. To make an agent unrestricted again, run the command with no teams:

relay agents teams set edge

How the server picks a replica

Each time you open a tunnel, the server picks the replica:

  1. It keeps the connection's agents that you may use: agents bound to one of your teams, and unrestricted agents.
  2. It prefers agents bound to your teams over unrestricted agents.
  3. Then it prefers the agent with the higher priority.
  4. In that agent, it picks the online replica with the fewest tunnels that isn't full. If no replica of the agent is online and has room, it tries the next agent.

If you aren't in any team that an agent is bound to, you use only the connection's unrestricted agents. If the connection has none, the server refuses the tunnel. Owners and admins follow the same rules.

For example, pg-prod uses two agents:

AgentTeamsPriority
edgedata-eng10
burstnone5

A member of data-eng gets a replica of edge. If every replica of edge is offline or full, they get one of burst. Everyone else gets a replica of burst. Members of data-eng would go to edge even if burst had the higher priority.

From CLI 0.8.0, relay connect dials the replica the server picks. Older CLIs ignore these rules and dial the least-loaded online replica of the connection's main agent.

Fix tunnel errors

relay connect prints these errors when the server can't give you a replica:

MessageCauseWhat to do
no agent pool on this connection is available to your teamsEvery agent on the connection is bound to teams you aren't in.Ask an admin to add you to one of those teams, or to add an unrestricted agent to the connection.
tunnel for "<name>" not opened: no online replica in the connection's agentsNo replica is online in the agents you may use. Older CLIs print no online agent in the connection's pools instead.Run relay agents list to check the agents' status. Start the replicas of a self-hosted agent and check that they can reach Relay. If a managed agent stays offline, contact support.
all agents in the connection's pools are at capacityEvery online replica of those agents has reached its tunnel cap.Try again later. To add room, raise a managed agent's --max-replicas, run more replicas of a self-hosted agent, or raise their --max-tunnels. If the self-hosted agent has an expected count, raise --expected-replicas first.
no online agent available for connection "<name>"The connection has a single agent and none of its replicas is online. CLIs older than 0.9.0 also print this for a connection with several agents when its main agent has no online replica.Start a replica of the agent. For a connection with several agents, upgrade to CLI 0.9.0 or later.

Monitoring

Each replica reports a heartbeat with its version. relay agents get and the agent's page in the dashboard show each replica's status, address, active tunnels, and last heartbeat. The agent's status rolls up from its replicas. See Status and replicas.

Capacity

A replica can have a tunnel cap, set with --max-tunnels. The replica reports the cap in each heartbeat. The server sends no new tunnels to a replica that is full, and counts tunnels it has issued that the replica hasn't reported yet. If a tunnel reaches a full replica anyway, the replica refuses it with RESOURCE_EXHAUSTED. Without a cap, a replica takes any number of tunnels.

Shutdown

When a replica gets SIGTERM or SIGINT, it shuts down in this order:

  1. It stops taking new tunnels. /readyz returns 503, and a new tunnel gets agent is shutting down, so the client can retry.
  2. Open tunnels get up to the drain timeout to finish, 25 seconds by default. The replica then closes the tunnels that are still open.
  3. It reports the ended sessions and sends its buffered audit events, with up to 5 seconds for each.
  4. It deregisters from the control plane.

Give the process more time to stop than the drain timeout plus these final reports.

Audit backpressure

Each replica buffers up to 10,000 query audit events until it sends them to the control plane. It never overwrites an event that it hasn't sent. If the control plane is unreachable, the backlog grows.

When the backlog reaches the threshold, 90% of the buffer by default, the connection's fail mode decides what happens to each new audited statement:

  • Deny (fail closed). The replica refuses the statement before it reaches the database, with audit backlog is full: the control plane is unreachable; try again later. The session stays open.
  • Allow (fail open). The statement runs. If the buffer is full, its audit event is dropped.

The replica accepts statements again as soon as it sends enough of the backlog to fall below the threshold. A replica with no control plane has no backpressure.

Settings for self-hosted agents

Set these on each replica of a self-hosted agent, as a flag or an environment variable. A flag takes priority over its environment variable.

FlagEnvironment variableDefaultDescription
--enrollment-tokenRELAY_ENROLLMENT_TOKENnoneThe enrollment token. Pass it from a secret store.
--nameRELAY_AGENT_NAMEhost nameThe replica's name, unique within its agent. See Replicas.
--poolRELAY_AGENT_POOLthe token's agentThe agent to join. Leave it unset: any other agent than the token's is refused.
--max-tunnelsRELAY_AGENT_MAX_TUNNELS0 (no cap)The most tunnels this replica carries at once. See Capacity.
--shutdown-drain-timeoutRELAY_SHUTDOWN_DRAIN_TIMEOUT25sHow long open tunnels have to finish after SIGTERM or SIGINT. See Shutdown.
--audit-backpressure-thresholdAUDIT_BACKPRESSURE_THRESHOLD0.9The fraction, above 0 and at most 1, of the audit buffer at which audited connections refuse statements. See Audit backpressure.

For the full list, see the installation guide that comes with the agent.

Permissions

ActionPermission
Create an agentorg.agent_pools.create
Resize an agent, or set its expected replicas or teamsorg.agent_pools.update
Delete an agentorg.agent_pools.delete
Remove a replicaorg.agents.delete
Create an enrollment tokenorg.enrollment_tokens.create
Set a connection's agentsorg.connections.update

From the CLI

relay agents list
relay agents get <agent>
relay agents create <name> [--managed] [--min-replicas N --max-replicas N] [--expected-replicas N] [--description D]
relay agents update <agent> [--min-replicas N --max-replicas N] [--expected-replicas N] [--description D]
relay agents delete <agent>
relay agents teams set <agent> [<team>...]
relay agents replicas delete <agent> <replica>
relay connections agents set <connection> <agent>:<priority>...
relay enrollment-tokens create --name <name> --agent <agent> [--expires-in D] [--single-use]
relay enrollment-tokens list|delete

See the CLI reference.

On this page