Connecting IoT Devices Without the Cloud
May 8, 2026 · 5 min read · IoT, Local-First, Architecture
The promise of the Internet of Things was simple: connected devices that work together intelligently. The reality, a decade later, is a graveyard of devices that stopped working when their vendor shut down the backend service.
Your Nest thermostat. Your Philips Hue bridge (v1). Your Wink hub. All of them required a cloud relay — and when that relay went dark, so did the devices.
But the deeper problem isn’t vendor shutdown. It’s architecture.
The Cloud Relay Trap
Most IoT devices communicate through this path:
Device A → [Internet] → Cloud Relay → [Internet] → Device B Even if Device A and Device B are in the same building — 10 meters apart — their messages travel thousands of kilometers through a cloud data center and back. This path fails in three common scenarios:
- Internet outage — ISP problems, infrastructure failures, blackouts
- Vendor shutdown — the relay service stops existing
- Latency-sensitive applications — cloud round-trips introduce 50-200ms latency
The cloud relay is a single point of failure with a business model attached.
A Better Architecture
With Relayly, the path becomes:
Device A → [Local Network] → Relayly (your server) → [Local Network] → Device B The relay runs on infrastructure you control — a Raspberry Pi on your local network, a VPS in the same region, or even on one of the devices itself. Devices communicate through the relay using end-to-end encryption, so the relay cannot read the messages even if it is compromised.
Why Not Peer-to-Peer?
Pure peer-to-peer (mDNS, WebRTC, Bluetooth) sounds better than a relay on paper, but it breaks down in practice:
- NAT traversal is fragile and device-dependent
- No connection persistence — devices drop off and reconnect constantly
- Mobile devices can’t reliably run P2P servers
- Cross-network communication (phone on LTE, sensor on WiFi) doesn’t work
A relay solves all of these while preserving the encryption properties. The relay is dumb — it just forwards bytes.
Relayly for IoT
Here’s what a simple IoT deployment looks like with Relayly:
# On your local server / Raspberry Pi
docker compose up --build -d
# Register your sensor
./relayly pair "Temperature Sensor A1"
# Output: Code: 483 921
# Register your controller
./relayly pair "HVAC Controller"
# Output: Code: 293 047
# Link them together
./relayly link sensor-id controller-id And in your sensor firmware (using the Go SDK):
client, _ := relayly.Connect(ctx, "ws://192.168.1.100:8080/ws", relayly.Options{
DeviceID: "sensor-a1",
PrivateKey: loadKey(),
})
// Send temperature readings every 30s — works even if internet is down
for range time.Tick(30 * time.Second) {
reading := readTemperature()
client.Send(ctx, "hvac-controller", marshalReading(reading))
} The HVAC controller receives readings and adjusts accordingly — entirely on the local network, with no cloud dependency.
When the Internet Goes Dark
The scenario we built for: complete internet loss. The sensors keep reading. The relay keeps forwarding. The controllers keep responding. Your building automation works exactly as designed, regardless of what’s happening outside.
This is the resilience model we believe critical infrastructure should be built on. Not “works most of the time” — works always.
Interested in using Relayly for IoT? Start with our Quick Start guide or open an issue to discuss your use case.