# https://tunnels.io/use-cases/iot

[Home](https://tunnels.io/) / [Use cases](https://tunnels.io/use-cases) / IoT and embedded devices

IoT and embedded devices

# Reach a device that lives behind someone else’s router.

A sensor in a customer's plant room. A Raspberry Pi in a rented flat. A gateway on a network whose administrator will never take your call. The client runs on the device itself, dials outward, and the device answers on a public HTTPS hostname. No port is forwarded and no router is touched.

[Get started free →](https://tunnels.io/get-started) [See pricing](https://tunnels.io/pricing)

## The device is somewhere you cannot go.

You shipped the hardware; the network belongs to the customer. You have no router access, no VLAN and no firewall console, and in most cases you never will.

The usual asks all fail in the same place. A port forward is a change request to somebody else's IT department, and a growing share of connections sit behind carrier-grade NAT, where there is no inbound path to open at any price.

A reverse tunnel inverts the direction. The device opens the connection outward, the way it already reaches an update server, and the public hostname is served from our edge. See [why the connection is opened outward](https://tunnels.io/learn/what-is-a-reverse-tunnel) for the mechanism, or [the four ways to publish a private server](https://tunnels.io/learn/how-to-expose-localhost) for the alternatives.

## Where does the tunnel client run?

On the device. Not on a jump box, and not on a gateway that proxies to the boards behind it. Each device owns its client and its hostname, so one unit can be swapped or moved to another site without editing a shared config, and no single gateway can take the whole site offline.

The client is a single Rust binary with no runtime to install. The shipped linux armv7 build is 5.1 MB and the arm64 build is 5.4 MB, so what goes onto the board is one small file rather than a stack, which matters when you are counting flash rather than disk.

```
# on the device, once
$ curl -fsSL https://tunnels.io/install.sh | bash
$ tunnels config add-authtoken <token>
# the device now answers on a public name
$ tunnels start pump-14
Active Tunnels:
▸ https://pump-14.tunnels.host → http://localhost:80  [https]
```

## Which published build matches your board?

We publish eleven targets at release 0.0.62: Linux amd64, arm64, 386 and armv7; macOS amd64 and arm64; Windows amd64, 386 and arm64; FreeBSD amd64; and NetBSD amd64. The two that matter on embedded hardware are `linux armv7` and `linux arm64`.

| Device class | Published target | Typical use | Note |
| --- | --- | --- | --- |
| Raspberry Pi | `linux armv7, linux arm64` | Field sensors, kiosk displays, a web UI on a Pi 3, 4 or 5. | A 64-bit Raspberry Pi OS takes arm64. The 32-bit image takes armv7. |
| x86 industrial gateway | `linux amd64` | DIN-rail gateways and panel PCs on Debian or Ubuntu. | The ordinary Linux build. |
| 32-bit legacy box | `linux 386` | Older industrial PCs and thin clients still in service. | Published at the current release, so an old box gets the same client. |
| BSD-based appliance | `freebsd amd64` | Firewall and storage appliances built on FreeBSD. | NetBSD amd64 is published too, with the same HTTPS and TCP support. |

## How does one hostname per device scale?

One device, one reserved subdomain, and the name is the asset. A runbook entry reading `pump-14.tunnels.host` beats an address a technician has to look up.

This is where the free plan runs out. Basic issues a random 16-character subdomain, reassigned whenever the client restarts, which is fine on the bench and useless in the field because every power cut renames the device. Reserved subdomains start on Professional, which carries three. Gold raises that to ten static names, adds three custom domains of your own and supports a wildcard, with certificates issued through Cloudflare for SaaS once you point a CNAME at us. Premium removes the cap and the lease expiry.

## What happens when a device loses power?

Field devices do not shut down. They stop. There is no graceful teardown and nobody next to the box to start anything again, so the client has to be a service the operating system brings back.

Under systemd that is a short unit file. `Restart=always` covers the crash and the cold boot, and `network-online.target` stops it starting before the interface has an address.

```
# /etc/systemd/system/tunnels.service
[Unit]
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/bin/tunnels --log stdout start pump-14
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```

### Backoff

The client reconnects on exponential backoff, so a site that lost its uplink an hour ago is not still retrying every second.

### Jitter

Devices that lost power together wake together, and backoff alone keeps them in lockstep. Randomised jitter spreads the attempts out.

### A server-directed delay

The client honours a reconnect delay sent by the server, so a restart on our edge is not a stampede.

## How much bandwidth does a device actually use?

A device posting a 200-byte reading every ten seconds moves roughly 50 MB a month. That is a little over one percent of the 4 GB on the free Basic plan, and a rounding error against the 128 GB on Professional. Telemetry does not need a plan decision.

A camera is a different product. One continuous stream at 1 Mbit/s is about 10 GB a day, which clears Professional's 128 GB in under a fortnight and Premium's 512 GB in roughly six weeks. Budget for that honestly. Snapshots and short clips pulled when an alarm fires sit back near the telemetry end.

## Which plan you need

One tunnel per exposed service, so a board publishing both a web UI and an SSH port counts as two. The plan tunnel limit is the number of services online at once, not the number of devices. Basic is $0: one tunnel, a random subdomain, 4 GB a month, and no raw TCP at all. It is a bench test, not a deployment.

Professional

$4 /mo, or $40/year

Five tunnels, three reserved subdomains, 128 GB, 8,192 requests per second. Raw TCP starts here, which is what MQTT on port 1883 and SSH to the board need.

Gold

$10 /mo, or $96/year

Ten tunnels, ten static subdomains, three custom domains with wildcard support, 256 GB. Where device names move onto your own domain.

Premium

$20 /mo, or $192/year

Unlimited tunnels, uncapped domains with no lease expiry, 512 GB and no request-rate cap. The one to look at past ten units.

A 24-month prepay is available on all three: $72 Professional, $144 Gold, $288 Premium. [Pricing](https://tunnels.io/pricing) is always authoritative.

## What this does not do

We carry HTTPS and raw TCP. Nothing else. Device work is full of protocols that are not HTTP, so read this first.

### No UDP

CoAP is UDP, so it is out, and so are MQTT-SN and the other UDP variants. Plain MQTT over TCP on port 1883 works as a raw TCP tunnel, which starts on Professional at $4 a month. There is no SMTP tunnel type, though SMTP is itself TCP, so a device that emails its own alerts can relay over a raw TCP tunnel like any other TCP service.

### No device management

No over-the-air updates, no fleet dashboard, no provisioning workflow. This is a network path to a device you already own and manage. Even upgrading the client is a deliberate `tunnels update` on the box.

### One tunnel per exposed service

A board exposing a web UI and an SSH port is two tunnels, and both count. The ceiling is one on Basic, five on Professional, ten on Gold, unlimited on Premium.

### Exposure is your decision

A public hostname makes the device reachable by anyone who learns the name. `--httpauth user:pass` puts HTTP basic auth in front at the edge, and that is the whole of what we offer. No OAuth, no IP allowlisting. Authentication on the device stays your job.

## Questions

### Can I reach a Raspberry Pi behind a router I do not control?

Yes. The client runs on the Pi and opens an outbound connection to our edge, so the router sees an ordinary outgoing session and nothing has to be forwarded. You get a public HTTPS hostname that reaches the Pi wherever it is plugged in, including behind carrier-grade NAT.

### Is there an ARM build for embedded Linux?

Yes. We publish linux armv7 and linux arm64 next to linux amd64 and linux 386, eleven targets in total at release 0.0.62. A 64-bit Raspberry Pi OS takes the arm64 build and the 32-bit image takes armv7.

### Does MQTT work over a tunnel?

MQTT over TCP on port 1883 works as a raw TCP tunnel, and raw TCP starts on Professional at $4 a month, so the free plan cannot open one. MQTT-SN and the other UDP variants do not, because we carry HTTPS and raw TCP only. CoAP is UDP and is out for the same reason.

### What happens when a whole site loses power and comes back at once?

Each client reconnects on exponential backoff with jitter, and honours a reconnect delay sent by the server, so devices that booted in the same second spread their attempts instead of arriving together. Under systemd with Restart=always, the tunnel is back before anyone notices.

## Related reading

[Homelab services The same shape of problem on a network you do own.](https://tunnels.io/use-cases/homelab) [SSH to an unroutable machine A shell on the board, over a raw TCP tunnel.](https://tunnels.io/use-cases/ssh) [Remote desktop access When the device in the field has a screen somebody must drive.](https://tunnels.io/use-cases/remote-desktop) [Why the connection is opened outward The mechanism underneath all of this.](https://tunnels.io/learn/what-is-a-reverse-tunnel) [Four ways to publish a private server Tunnels, SSH forwarding, port forwarding and deploying.](https://tunnels.io/learn/how-to-expose-localhost) [Compared with Tailscale A private mesh between enrolled machines, not a public hostname.](https://tunnels.io/compare/tailscale)

Put one device online and see.

The free plan proves the path from the bench. Reserved names, raw TCP and fleet-sized bandwidth start at $4 a month.

[Get started →](https://tunnels.io/get-started) [See plans and limits](https://tunnels.io/pricing)
