Service Discovery: Finding Instances Without Hardcoded Hosts
Service discovery maps logical service names to live instance addresses so clients and load balancers follow scaling, deploys, and failures automatically.
Definition
Service discovery is the mechanism that registers running instances with a catalog and lets consumers resolve a stable logical name to current endpoints. It replaces static host lists and configuration edits with continuous registration, health-aware resolution, and deregistration when instances stop.
Context and scope
Dynamic environments such as Kubernetes, autoscaling groups, and multi-region deployments change instance addresses constantly, so hardcoded endpoints go stale within minutes.
Common misconceptions
- Discovery is only DNS — DNS resolves a name, but health-aware deregistration and metadata need more
- A registry removes the need for load balancing — discovery returns candidates, something must still choose one
- Client-side discovery is obsolete — it remains useful when you control the client and want to skip an extra hop
Anti-patterns
- Registering instances that never deregister after a crash, leaving dead endpoints in rotation
- Using discovery for configuration data that changes independently of instance lifecycle
- Resolving on every request without caching, turning the registry into a latency bottleneck
Related concepts
Authoritative source
https://developer.hashicorp.com/consul/docs/concepts/service-discovery
The problem it solves
Addresses are not stable. Pods restart with new IPs, autoscaling groups replace nodes, and failover promotes replicas in another region. Service discovery lets a caller ask for payments instead of 10.0.4.17:8080, and receive the instances that are healthy right now.
Client-side and server-side
In client-side discovery, the caller queries the registry, picks an instance, and connects directly. In server-side discovery, the caller talks to a load balancer or virtual IP that owns the lookup. For example, Kubernetes Services give Pods a stable virtual address while EndpointSlices track the backing instances.
Client-side discovery removes a hop and enables smarter balancing, but it pushes discovery logic into every language and requires a shared client library. Server-side discovery centralizes that logic and costs an extra network hop.
Health and deregistration
Registration is the easy half. Deregistration is where catalogs rot: a crashed process cannot announce its own death, so the platform must detect failure through heartbeats, TTLs, or orchestrator state. Health-aware resolution then removes unhealthy endpoints before traffic reaches them.
Operating it
Treat the registry as critical infrastructure. It needs redundancy across zones, a cache in every client, and a documented fallback when lookups fail. Stale entries are worse than missing ones because they send traffic into a void.
Compared to hardcoded configuration, discovery removes the coordination cost of every deploy but adds a runtime dependency: when the registry is unavailable, running instances may become unreachable even though nothing is wrong with them. Cache aggressively, and let clients keep the last known good endpoint set.
When to use it
Use discovery whenever instance addresses change without a human editing configuration: containers, autoscaling groups, and multi-region failover. Static configuration remains reasonable for a handful of stable, manually managed endpoints. The trade is clear: discovery buys elasticity and pays for it with a new critical dependency that must be monitored, cached, and rehearsed.