# Services

> Give an internal app one name and address, run it on several machines, and let devices move to a backup on their own.

A **service** is an internal app with its own name and address, separate from any one machine. You run it on one or more machines (its **hosts**), and every device reaches it by the service's name. If the host in use goes offline, devices move to the next one.

Use it for anything people rely on every day: a wiki, Grafana, an admin tool, a Git server. Services work over **TCP**.

## Set one up

1. **Create the service.** In the dashboard, open **Services** and add one with a name (like `grafana`) and its ports (like `tcp:443`). It gets an address from `100.100.0.0/16` and a name.
2. **Run it on each host.** On every machine that runs the app, tell the client which local port to send the service's traffic to:

   ```bash
   underpass serve --service=svc:grafana --tcp=443 127.0.0.1:3000
   ```

   The target can be a port (`3000`), `127.0.0.1:3000` or `localhost:3000`.
3. **Approve the hosts.** In **Services**, approve each machine. A machine only serves once an admin approves it.

People then open `https://grafana` (or the service's full name) from any device in the network.

## Which host is used

Every device picks the same host, so everyone sees the same app state:

1. Hosts that are **approved** and currently **serving** are candidates.
2. **Online** hosts come first, then the one that has served the **longest**.
3. Each device uses the first candidate it can reach.

This is failover, not load balancing: one host serves at a time, and the others wait as backups.

## Failover timing

| What happens | When devices move |
|---|---|
| You stop serving on a host (`serve … off`) | Right away |
| A host loses power or its network | After about **90 seconds**, when it counts as offline |

For planned maintenance, stop serving first:

```bash
underpass serve --service=svc:grafana --tcp=443 off
```

Then update or restart the machine, and run the `serve` command again.

## See what a machine serves

```bash
underpass serve status
```

## Limits

- 1 to 16 ports per service, TCP only
- Up to 64 services per host
- Service and machine names share one namespace: a service can't have the same name as a machine

## Access

Only devices in your network can reach a service. To narrow it further, name it in an [access rule](/features/access-controls) as `svc:grafana`.
