A JVM service instance boots and registers itself with a Netflix Eureka server. Walk through what happens from that registration until another service is able to send it a request.
answer
- four steps, one timer each
- register, renew, fetch, choose
- the instance describes itself
- callers cache the entire registry
- nothing routes through the server
basics
~20 sThe instance posts its own metadata to the Eureka server and then heartbeats every 30 seconds to keep its lease alive. Callers download the whole registry, cache it in memory, and pick an instance themselves — Eureka never carries request traffic.
solid answer
~50 sFour steps. First, **registration**: the instance's Eureka client sends its own record — application name, instance id, host or IP, port, status `UP`, plus free-form metadata — to the server, which stores it as a lease. Second, **renewal**: that client heartbeats every 30 seconds by default; each heartbeat resets the lease clock, and if they stop the server eventually evicts the entry. Nothing polls the instance — liveness here means "the heartbeat thread is still running". Third, **fetch**: a calling service does not query per request; its Eureka client pulls the entire registry, refreshes it roughly every 30 seconds using delta fetches, and holds it in memory. Fourth, **selection**: the caller's own load balancer picks an address from that cached list and connects directly. Eureka is a lookup table, not a proxy, so calls keep working while the registry is down — and every caller is a refresh interval behind reality.
code
bash · 10 linesEUREKA=http://eureka.internal:8761/eureka
# 1. read the whole registry the way a client does
curl -s -H 'Accept: application/json' "$EUREKA/apps"
# 2. read one application's instances
curl -s -H 'Accept: application/json' "$EUREKA/apps/ORDER-SERVICE"
# 3. drain one instance without stopping the process
curl -s -X PUT "$EUREKA/apps/ORDER-SERVICE/i-0abc123/status?value=OUT_OF_SERVICE"go deeper
Be able to name the four steps in order — register, heartbeat, fetch, choose — and say plainly that the caller holds a cached copy of the registry and picks the instance itself.
Explain the timers behind each step and their defaults, and why a heartbeat is a weak liveness signal: it proves a background thread runs, not that the application can serve a request.
Show that you have operated this. Talk about draining an instance by pushing a status change rather than killing it, about instances advertising an unroutable address, and about what actually degrades when the registry is unavailable.
Own the consequence of putting the registry outside the request path: availability is cheap and routing policy is per-caller, but freshness is bounded by client caches and every participant needs an embedded client, which quietly makes the platform JVM-only.
## What Eureka actually is Netflix Eureka is a **service registry**: a small HTTP server whose entire job is to hold the answer to "which instances of which application are currently up, and at what address?". It is deliberately *not* a proxy or a load balancer. No request between two of your services ever passes through a Eureka server, which is why a Eureka outage is survivable in a way that a reverse-proxy outage is not. ## Step 1 — registration On startup, the instance's embedded Eureka client builds a record of itself: application name (the logical service, e.g. `ORDER-SERVICE`), a unique instance id, hostname and/or IP, port, an initial status such as `STARTING` or `UP`, a health-check URL, and arbitrary key/value metadata. It sends that record to the server, which stores it as a **lease**. The important property is that the instance describes itself. The server does not discover anything; it believes what it is told. A misconfigured instance that advertises a container-internal IP that nobody outside can route to will register perfectly happily, and callers will fail to reach it. ## Step 2 — renewal (the heartbeat) The client then renews its lease on a timer — `leaseRenewalIntervalInSeconds`, default **30 seconds**. Each renewal resets the lease clock, which is configured by `leaseExpirationDurationInSeconds`, default **90 seconds**. Miss enough heartbeats and the server's eviction task removes the entry. This is heartbeat-based (passive) liveness, and its limitation is worth saying out loud in an interview: a heartbeat proves the client's background thread is scheduled, not that the application can serve a request. A JVM with an exhausted request thread pool, a broken database connection, or a wedged downstream will keep heartbeating cheerfully while failing every real call. If you want a stronger signal, an instance can *report* a status change itself, and an operator can force one through the registry's REST API: ```bash curl -X PUT "$EUREKA/apps/ORDER-SERVICE/i-0abc123/status?value=OUT_OF_SERVICE" ``` That takes an instance out of rotation without killing the process — the standard way to drain one node. ## Step 3 — the caller fetches the registry A calling service does **not** ask the registry "where is order-service?" on each request. Its Eureka client downloads the *whole* registry once at startup and then refreshes on a timer — `registryFetchIntervalSeconds`, default **30 seconds**. Refreshes are normally *delta* fetches: the server returns only recent changes, and the client compares an application hash to detect drift, falling back to a full re-fetch when the two disagree. The result is kept entirely in the caller's memory. ## Step 4 — the caller chooses an instance Because the list lives in the caller, the caller also does the load balancing: it applies its own policy — round-robin, zone affinity, availability filtering — to the cached list and opens a connection straight to the chosen instance. This is what "client-side" means concretely in Eureka. ```bash # The registry is just a REST resource you can read yourself curl -s -H 'Accept: application/json' "$EUREKA/apps" | head -40 ``` ## What this design buys, and what it costs It buys **availability and cheapness**. There is no component in the data path to size, and if every Eureka server dies, running callers keep using their last cached list and keep serving traffic. Each caller can also make its own routing decisions — prefer its own zone, weight instances differently — which a shared load balancer cannot express per-caller. It costs **freshness and reach**. Every caller is up to a fetch interval behind the registry, which is itself up to a lease duration behind reality, so a dead instance stays in someone's list for a while. And the model only works for callers that embed a Eureka client, which in practice means JVM services: a non-JVM service or an external client cannot join without a translation layer. ## The one-line summary for an interview Register, heartbeat, fetch, choose. The instance keeps itself alive by heartbeat; the caller keeps a cached copy of the whole registry and load-balances locally; the registry is only ever consulted out-of-band, never in the request path.
- If every Eureka server is down, can your services still call each other?Yes, for as long as the callers stay up. Each client holds the registry in memory and keeps using its last copy, so existing routes work; it simply stops learning about changes. What breaks is anything new — a fresh instance cannot register, and a client starting cold has an empty registry and can resolve nothing until a server answers.
- Does a Eureka heartbeat prove the instance can serve requests?No. The heartbeat comes from a background thread in the client and proves only that the process and that thread are alive. An instance with a full request queue, a dead database pool, or a hung dependency keeps renewing its lease while failing every call. If you want application health to affect discovery, the instance has to report its own status change to the registry.
- What is the difference between an instance's status being DOWN and its lease being evicted?A `DOWN` or `OUT_OF_SERVICE` instance is still in the registry, with a lease and a status callers are expected to filter on — it is a deliberate, immediate signal. Eviction is the server deleting the entry after the lease expires, which is slow and implicit. Draining uses status; crashing gets you eviction.
saying these in an interview costs you the question
- Thinks callers ask Eureka for an address on every request
- Believes traffic is proxied through the Eureka server
- Says the Eureka server polls each instance's health endpoint
- Assumes a registered instance is immediately visible to all callers
- Cannot say who performs the load balancing