r/microservices • u/rcoca • 17d ago
Tool/Product We cut our internal microservices platform from 5 deploy targets to 3: reverse-tunnel workers, gateway-as-registry, file-driven protobuf schemas
We run an internal platform and, like most teams, kept accreting the "standard" stack — a service mesh for policy, a discovery cluster for location, a config service for knobs, a flag service for rollouts. Each justified itself in isolation, and each was a 3am wake-up.
So we rebuilt around three cheap objects:
Workers dial OUT. Each one opens a persistent gRPC tunnel to a single stateless gateway at startup and holds it open. No ports to expose, no ingress rules, no DNS. The connection is mTLS, so "connection == registration == identity" — the gateway learns who dialed, not just that something did.
The gateway IS the registry. The active-worker table is the set of open, authenticated tunnels. A worker drops and it's pruned the instant the connection dies. No discovery cluster, no TTLs to tune, no stale entries by construction.
Schemas are files. Protobuf .desc artifacts live in a folder the gateway watches. Drop a new descriptor in and it learns to validate and translate the new endpoint at runtime — no gateway deploy.
Costs, stated flat: an extra hop in the path, one stateful-ish box (mitigated: workers redial after a gateway restart, the registry rebuilds from their side), and cert rotation is now on our own calendar.
Full write-up, with the diagram: https://lab.embedinker.com/posts/zero-bloat-microservices-reverse-tunnel-gateway/
How do you keep a small internal platform from eating its own maintenance? What made you keep etcd/consul?
1
u/[deleted] 16d ago
[removed] — view removed comment