← Back to Articles         
Dynamic Microservice Discovery

Dynamic Microservice Discovery

Published on 29 Sep 2026     12 min read Microservices
Service Discovery

1. How Does One Microservice Locate Another Microservice Dynamically?

What is dynamic service location?

In a microservices architecture, services often run on multiple instances, and their network locations can change dynamically.

For example:

Order Service
      |
      | Needs product information
      v
Product Service

In a simple environment, OrderService could call a fixed address:

https://localhost:7002/api/products/10

But in production, ProductService may have several instances:

Product Service
 ├── Instance 1 → 10.0.1.11:8080
 ├── Instance 2 → 10.0.1.12:8080
 └── Instance 3 → 10.0.1.13:8080

Autoscaling may then add another:

10.0.1.14:8080

or remove an existing instance.

Therefore, OrderService should normally not maintain a hard-coded list of instance IP addresses.

Instead, it uses service discovery.


What is Service Discovery?

Service Discovery is the mechanism that allows one service to find the current network location of another service.

Conceptually:

Service Name
     ↓
Service Discovery
     ↓
Available Service Instance(s)
     ↓
IP Address + Port

For example:

"ProductService"

        ↓ Resolve

10.0.1.11:8080
10.0.1.12:8080
10.0.1.13:8080

The important idea is:

Call a logical service identity rather than hard-coding individual service-instance addresses.


Why do we need Service Discovery?

Modern microservices are dynamic.

Instances can:

  • start
  • stop
  • restart
  • fail
  • move to another machine/node
  • receive different IP addresses
  • scale out
  • scale in

Suppose OrderService contains:

var url = "http://10.0.1.11:8080/api/products/10";

If that Product Service instance disappears, the call fails.

Changing configuration manually every time an instance changes is impractical.

Service discovery solves this problem.


Purpose

Its primary purpose is to answer:

"Where is ProductService currently running?"

The typical flow is:

Order Service
      |
      | Find ProductService
      v
Service Discovery Mechanism
      |
      | Available endpoint(s)
      v
Product Service Instance

Service Registry

A common service-discovery design uses a Service Registry.

The registry maintains information about currently available services.

Example:

Service Address Port Status
ProductService 10.0.1.11 8080 Healthy
ProductService 10.0.1.12 8080 Healthy
ProductService 10.0.1.13 8080 Healthy
OrderService 10.0.2.10 8080 Healthy

Conceptually:

               Service Registry
              /       |        \
             /        |         \
            v         v          v
        Product     Order      Payment
        Service     Service     Service

How does registration happen?

There are different architectures, but a common conceptual flow is:

ProductService starts
       |
       | Register / become discoverable
       v
Service Registry
       |
       | ProductService
       | 10.0.1.11:8080
       v

OrderService
       |
       | Find ProductService
       v
Service Registry
       |
       | 10.0.1.11:8080
       v
OrderService calls ProductService

Registries/platforms also need a way to determine whether an instance remains usable, such as:

Health checks
Heartbeats
Leases
Platform/container health state

The exact mechanism depends on the discovery technology.


What happens during autoscaling?

Suppose Product Service initially has:

ProductService
    |
    ├── Instance A
    └── Instance B

Traffic increases.

The platform creates:

ProductService
    |
    ├── Instance A
    ├── Instance B
    ├── Instance C
    └── Instance D

The discovery/routing infrastructure becomes aware of the new healthy instances.

When demand decreases:

Instance C removed
Instance D removed

those instances should no longer be returned/routed to.

This is why dynamic discovery works much better than maintaining instance URLs manually.


Two Main Types of Service Discovery

There are two important patterns:

1. Client-Side Service Discovery
2. Server-Side Service Discovery

That leads directly to your second question.


2. Client-Side vs Server-Side Service Discovery

The major difference is:

Who performs service discovery and chooses the destination instance?


A. Client-Side Service Discovery

What is it?

With client-side discovery, the calling service itself participates in discovery.

For example:

OrderService needs ProductService.

OrderService:

  1. Queries the registry/discovery mechanism.
  2. Gets available ProductService instances.
  3. Selects an instance, often through client-side load balancing.
  4. Calls that instance directly.

Architecture

                Service Registry
                       ^
                       |
              "Find ProductService"
                       |
                       |
                Order Service
                       |
              Choose an instance
                       |
          +------------+------------+
          |            |            |
          v            v            v
       Product      Product      Product
       Instance A   Instance B   Instance C

Example

Registry contains:

ProductService

10.0.1.11:8080
10.0.1.12:8080
10.0.1.13:8080

Order Service queries the registry:

OrderService
     |
     | Find "ProductService"
     v
Registry
     |
     v

10.0.1.11:8080
10.0.1.12:8080
10.0.1.13:8080

The client-side component might select:

10.0.1.12:8080

Then:

OrderService
     |
     | HTTP
     v
10.0.1.12:8080

Client-Side Load Balancing

Client-side discovery is frequently combined with client-side load balancing.

For example:

Request 1 → Instance A
Request 2 → Instance B
Request 3 → Instance C
Request 4 → Instance A

Depending on the technology, algorithms could include:

Round Robin
Random
Weighted selection
Least requests/connections

Client-Side Example – Conceptual C#

To understand the pattern, imagine a registry interface:

public interface IServiceRegistry
{
    Task<List<ServiceInstance>> GetInstancesAsync(string serviceName);
}

Model:

public class ServiceInstance
{
    public string Host { get; set; } = "";
    public int Port { get; set; }
}

Order Service:

public class ProductClient
{
    private readonly IServiceRegistry _registry;
    private readonly HttpClient _httpClient;

    public ProductClient(
        IServiceRegistry registry,
        HttpClient httpClient)
    {
        _registry = registry;
        _httpClient = httpClient;
    }

    public async Task<string> GetProductAsync(int id)
    {
        var instances =
            await _registry.GetInstancesAsync("ProductService");

        var instance = instances[0];

        var url =
            $"http://{instance.Host}:{instance.Port}/api/products/{id}";

        return await _httpClient.GetStringAsync(url);
    }
}

This is intentionally simplified.

In a real system, you wouldn't normally write:

instances[0]

You would have proper selection/load-balancing, health handling, retries, timeouts, etc.


Advantages of Client-Side Discovery

1. Direct communication

Once the client finds an instance:

Client Service → Target Service

There is no mandatory discovery proxy in the data path.

2. Flexible load balancing

The client can potentially control instance selection.

3. Fewer intermediary hops

The caller can communicate directly with the selected instance.

4. Custom routing logic

Specialized clients can implement sophisticated selection policies.


Disadvantages of Client-Side Discovery

1. More complexity in every client

Every calling application may need discovery/load-balancing functionality.

2. Language/library dependency

If you have:

.NET
Java
Go
Node.js
Python

each ecosystem needs compatible discovery support.

3. More responsibility for application developers

The application must account for:

Discovery
Load balancing
Failures
Retries
Timeouts
Registry interaction

4. Tight coupling to discovery mechanism

Application code/infrastructure libraries may become coupled to a particular discovery system.


B. Server-Side Service Discovery

What is it?

With server-side discovery, the calling service sends its request to a stable intermediary such as a load balancer, proxy, ingress, gateway, or platform routing layer.

That infrastructure determines the appropriate backend instance.


Architecture

Order Service
      |
      | ProductService request
      v
Load Balancer / Proxy / Platform
      |
      | Discover/select healthy instance
      v
+-------------+-------------+
|             |             |
v             v             v
Product A   Product B   Product C

The caller does not need to know:

10.0.1.11
10.0.1.12
10.0.1.13

It only needs a stable destination.


Example

Instead of:

http://10.0.1.11:8080/api/products/10

the application may call something logically stable, such as:

http://product-service/api/products/10

How that name resolves and how traffic reaches an instance depends on the platform.

For example, container orchestration commonly provides stable service names plus internal load balancing.


Server-Side Discovery Flow

Suppose:

Order Service
Product Service × 3

The flow is:

OrderService
     |
     | Request ProductService
     v
Stable Service Endpoint
     |
     v
Routing / Load-Balancing Infrastructure
     |
     | Which instances are healthy?
     |
     +--------+--------+
     |        |        |
     v        v        v
    P1       P2       P3

The routing layer chooses, for example:

P2

So:

OrderService
     ↓
Stable endpoint
     ↓
Load Balancer
     ↓
ProductService Instance 2

ASP.NET Core Example

From the application's perspective, this can be very simple.

appsettings.json

{
  "Services": {
    "ProductService": "http://product-service"
  }
}

Program.cs

builder.Services.AddHttpClient<ProductClient>((sp, client) =>
{
    var configuration =
        sp.GetRequiredService<IConfiguration>();

    var url =
        configuration["Services:ProductService"];

    client.BaseAddress = new Uri(url!);
});

ProductClient.cs

public class ProductClient
{
    private readonly HttpClient _httpClient;

    public ProductClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetProductAsync(int id)
    {
        return await _httpClient
            .GetStringAsync($"/api/products/{id}");
    }
}

Notice that the code does not contain:

10.0.1.11
10.0.1.12
10.0.1.13

The underlying infrastructure handles instance selection.


Advantages of Server-Side Discovery

1. Simpler application code

The client doesn't need detailed knowledge of all service instances.

2. Centralized infrastructure

Discovery and routing responsibilities are moved away from individual applications.

3. Technology independent

Your services could be:

ASP.NET Core
Java
Node.js
Python
Go

They can all communicate through standard networking protocols without each implementing the same registry client.

4. Easier operational management

Infrastructure handles instance membership and routing.

5. Works naturally with cloud/container platforms

This model aligns well with managed load balancers, container platforms, proxies, and orchestration systems.


Disadvantages of Server-Side Discovery

1. Additional infrastructure

You need some routing/discovery layer.

2. Additional network hop in some architectures

Conceptually:

Client
  ↓
Proxy / Load Balancer
  ↓
Service

rather than direct instance-to-instance communication.

3. Infrastructure becomes critical

The routing layer must itself be highly available.

4. Troubleshooting can become more distributed

Problems might exist in:

DNS
Proxy
Load Balancer
Health checks
Service
Network

rather than solely inside application code.


Client-Side vs Server-Side Discovery

Feature Client-Side Server-Side
Who performs discovery? Calling service/client library Infrastructure
Who chooses instance? Client Proxy/load balancer/platform
Client complexity Higher Lower
Direct instance call Usually yes Usually through infrastructure
Load balancing Client-side Infrastructure-side
Registry awareness Client Infrastructure/platform
Language dependency Can be higher Usually lower
Centralized routing No Yes
Application responsibility Higher Lower
Operational infrastructure Less centralized More centralized

Important: API Gateway vs Service Discovery

These are related but not the same thing.

An API Gateway may perform:

Routing
Authentication
Authorization
Rate limiting
Request transformation
Aggregation
Logging

Service discovery answers:

"Where are the available instances of this service?"

For example:

Internet Client
      |
      v
API Gateway
      |
      | Route → Product Service
      v
Discovery / Routing Infrastructure
      |
      v
Load Balancer
      |
      +--------+--------+
      |        |        |
      v        v        v
 Product 1 Product 2 Product 3

Depending on the platform and gateway, some of these responsibilities can be integrated into the same infrastructure.


Important: Service Registry vs Service Discovery

These terms are also related but different.

Service Registry

The database/directory of service instances.

ProductService
 ├── 10.0.1.11:8080
 ├── 10.0.1.12:8080
 └── 10.0.1.13:8080

Service Discovery

The process of finding an appropriate service endpoint using registry, DNS, platform metadata, or other mechanisms.

Think:

Service Registry = Information

Service Discovery = Finding/using that information

Common Technologies

Different environments implement these ideas differently.

Examples you may encounter include:

Consul
Netflix Eureka
Kubernetes Services + DNS
Azure Container Apps service discovery
AWS Cloud Map
HashiCorp Nomad/Consul environments
Service meshes

With modern managed platforms, developers often don't build a custom service registry themselves; the platform provides discovery/routing primitives.


Complete Conceptual Flow

Consider three services:

OrderService
ProductService
PaymentService

ProductService has three instances:

                 Microservices

                  OrderService
                       |
                       | Need Product
                       v
              Service Discovery
                       |
              "ProductService"
                       |
                Load Balancing
                       |
          +------------+------------+
          |            |            |
          v            v            v
      Product-1    Product-2    Product-3

If Product-2 fails:

Product-1 → Healthy
Product-2 → Unhealthy
Product-3 → Healthy

the discovery/routing system should stop directing new requests to Product-2.

If autoscaling creates:

Product-4 → Healthy

it can become eligible to receive traffic.

That's the fundamental value of dynamic service discovery.


Key Points

For interviews, remember these:

  1. Microservice instance locations can change because of scaling, deployment, restart, and failure.
  2. Therefore, services should generally avoid hard-coded instance IP addresses.
  3. Service Discovery enables services to locate other services dynamically.
  4. A Service Registry maintains information about available service instances in registry-based designs.
  5. In client-side discovery, the calling client participates in discovering and selecting an instance.
  6. In server-side discovery, infrastructure performs discovery/routing and instance selection.
  7. Service discovery and load balancing are closely related but represent different responsibilities.
  8. Health information is important so unavailable instances stop receiving traffic.
  9. Modern orchestration/cloud platforms frequently provide discovery capabilities automatically.
  10. API Gateway and Service Discovery solve different problems, although gateways can integrate with discovery infrastructure.

Interview Questions and Answers

Q1. What is Service Discovery?

Answer:
Service discovery is the mechanism through which one service dynamically locates another service's available network endpoint instead of relying on hard-coded instance addresses.


Q2. Why do Microservices need Service Discovery?

Answer:
Because service instances can be dynamically created, removed, restarted, or relocated due to deployment, failures, and autoscaling. Their individual IP addresses therefore should not normally be hard-coded.


Q3. What is a Service Registry?

Answer:
A service registry is a directory containing information about available service instances, such as their service identity, network location, and potentially health-related metadata.


Q4. What is Client-Side Service Discovery?

Answer:
The calling service queries a discovery mechanism, obtains available target instances, selects one—often using client-side load balancing—and calls it directly.

Client
   ↓
Registry
   ↓
Choose instance
   ↓
Service

Q5. What is Server-Side Service Discovery?

Answer:
The client sends a request to a stable endpoint, proxy, load balancer, or platform routing layer, and that infrastructure locates/selects an appropriate backend service instance.

Client
   ↓
Load Balancer / Proxy
   ↓
Discovery
   ↓
Service Instance

Q6. What is the main difference?

Answer:

Client-side discovery: the client participates in choosing the service instance.
Server-side discovery: infrastructure chooses/routes to the service instance.


Q7. What happens when a service instance fails?

The discovery/routing system should eventually identify the instance as unavailable through its health, heartbeat, lease, or platform-state mechanism and stop sending new traffic to it.


Q8. How does autoscaling work with Service Discovery?

When new instances are created, they become discoverable and eligible for traffic. When instances are terminated, they are removed from the available routing/discovery set.


Q9. Is API Gateway the same as Service Discovery?

No.

An API Gateway provides an entry point and cross-cutting capabilities such as routing, authentication, rate limiting, and transformation.

Service discovery solves the problem of locating available service instances.


Q10. Do we need to build our own Service Registry in ASP.NET Core?

Usually no in a production cloud/container environment.

If you deploy using a platform that already provides service naming, discovery, health management, and load balancing, you should generally use those platform capabilities rather than creating a custom SQL/in-memory registry.


Interview Summary

A strong short answer is:

In Microservices, service instances are dynamic, so we should not hard-code their individual IP addresses. Service Discovery allows one service to locate another dynamically. In client-side discovery, the calling service discovers and selects an instance. In server-side discovery, infrastructure such as a proxy, load balancer, or orchestration platform discovers/selects the instance. Modern platforms such as Kubernetes and Azure Container Apps provide service-discovery capabilities, reducing the need to build a custom registry.

← Back to Articles