skip to content

Explain instance registration, lease renewal heartbeats, and how the server evicts dead instances in Eureka.

level: middleimportance: must knowfreq 65%

answer

  1. register -> lease -> heartbeat renew
  2. renewal 30s / expiration 90s (~3 misses)
  3. EvictionTask sweeps every 60s
  4. graceful shutdown = cancel (DELETE)
  5. crash lingers ~90s + eviction sweep

basics

~20 s

On startup a client registers an instance and gets a lease. It then sends a heartbeat (renews the lease) every 30 seconds. If the server gets no heartbeat within the lease-expiration window (90s), the lease expires and an eviction task removes that instance from the registry.

solid answer

~40 s

Registration is a lease-based mechanism. On startup the client POSTs its instance descriptor to the server, which stores it and grants a lease. The client then renews that lease with a periodic heartbeat, controlled by eureka.instance.lease-renewal-interval-in-seconds (default 30s). Each instance also declares lease-expiration-duration-in-seconds (default 90s) — the max time the server waits without a heartbeat before considering the lease dead. A separate server-side EvictionTask runs on eureka.server.eviction-interval-timer-in-ms (default 60s) and removes expired leases. On graceful shutdown the client sends a cancel (DELETE) so it's removed immediately. Because eviction is timer-based and needs missed heartbeats, a crashed instance can linger in the registry for up to ~90s plus the eviction interval — clients must tolerate stale entries (retries/circuit breakers).

code

java · 18 lines
java
// application.yml on a Eureka client — the timing knobs
// eureka:
//   instance:
//     lease-renewal-interval-in-seconds: 30   # heartbeat cadence (client -> server)
//     lease-expiration-duration-in-seconds: 90 # server waits this long w/o heartbeat
//   client:
//     registry-fetch-interval-seconds: 30      # how often client refreshes its cache

// On the Eureka SERVER — how often expired leases are actually removed
// eureka:
//   server:
//     eviction-interval-timer-in-ms: 60000      # EvictionTask cadence

// Timeline for a crashed instance (kill -9):
//   t=0     last heartbeat received
//   t=90s   lease considered expired (no cancel was sent)
//   t<=+60s next EvictionTask sweep removes it
//   => up to ~150s of a stale UP entry -> consumers must retry / use a circuit breaker

go deeper

for a junior

Know heartbeat every 30s renews a lease; no heartbeat -> eventually removed.

for a middle

Recite defaults (30s renew, 90s expire, 60s eviction) and the register/heartbeat/cancel HTTP flow.

for a senior

Explain the lingering-instance window and why consumers need retries/circuit breakers; distinguish instance vs server properties.

for a principal

Reason about tuning trade-offs (detection speed vs chatter vs self-preservation false-trips) and eventual-consistency implications for call routing.

## Lease model Eureka models each registration as a **lease** that must be continuously **renewed**, so the registry self-cleans when instances vanish. ### 1. Registration On startup the Eureka client sends a **register** request (HTTP POST to `/eureka/apps/{APPNAME}`) carrying its `InstanceInfo`: app name, instance id, IP/host, port, status page + health-check URLs, and metadata. The server stores it and marks status `UP`. This grants a **lease**. ### 2. Lease renewal (heartbeats) The client then periodically sends a **heartbeat** (HTTP PUT) to renew the lease. Cadence is set per instance: - **`eureka.instance.lease-renewal-interval-in-seconds`** — how often the client sends a heartbeat. **Default 30s.** - **`eureka.instance.lease-expiration-duration-in-seconds`** — how long the server keeps the lease alive without a heartbeat before treating it as expired. **Default 90s.** (Roughly 3 missed heartbeats.) These are **client-declared** values sent to the server at registration — the instance tells the server its own timing. ### 3. Eviction Expiry alone doesn't remove an instance; a background **`EvictionTask`** on the server periodically scans for expired leases and removes them. Its cadence is **`eureka.server.eviction-interval-timer-in-ms`** (**default 60000ms = 60s**). So a dead instance can linger: heartbeat missed → wait out the 90s expiration → wait for the next eviction sweep. Worst case ~90s + up to 60s. ### 4. Graceful shutdown = cancel On clean shutdown the client sends a **cancel** (HTTP DELETE to `/eureka/apps/{APPNAME}/{INSTANCEID}`) so the server removes it **immediately** rather than waiting for lease expiry. Spring Boot triggers this via the client's shutdown hook. A hard crash (kill -9, OOM) skips this, hence the lingering entry. ## Why the numbers matter - Lowering the heartbeat interval and expiration makes the registry detect failures faster, but increases network chatter and can trip **self-preservation** more easily on flaky networks. - The renewal interval and expiration interact with **self-preservation**, which computes expected renewals per minute from the interval (30s → 2/min per instance). ## Gotchas - Instances persist for up to ~90s after a crash — **the registry is eventually consistent, never a real-time truth**. Consumers must handle calling an instance that's already gone (Spring Cloud LoadBalancer retries, Resilience4j circuit breaker). - Client-side registry caches (fetched every 30s) add *more* staleness on top of server-side lag. - Changing `lease-expiration-duration` below `3 * lease-renewal-interval` risks premature eviction from a single dropped heartbeat. - These are `eureka.instance.*` (client timing) vs `eureka.server.*` (eviction sweep) — a common config mix-up. ## When to tune Tighten intervals only when fast failure detection outweighs extra load and false-eviction risk; otherwise keep defaults and lean on client resilience.

  • Why can a crashed instance still appear UP for a while, and how do you cope?
    Eviction needs missed heartbeats (up to 90s) plus the next 60s eviction sweep, and Eureka only marks/removes then. It never sends a cancel on a hard crash. Consumers cope with client-side load-balancer retries and circuit breakers (Resilience4j) rather than trusting the registry as real-time truth.
  • What is the difference between eureka.instance.* and eureka.server.* timing properties?
    eureka.instance.* (lease-renewal-interval, lease-expiration-duration) are client-declared and control the heartbeat contract for that instance. eureka.server.eviction-interval-timer-in-ms controls how often the server actually sweeps and removes already-expired leases.

saying these in an interview costs you the question

  • Saying the server removes an instance instantly when a heartbeat is missed (ignores the 90s expiration + eviction sweep).
  • Claiming heartbeats happen every second or that intervals aren't configurable.
  • Assuming the registry is a real-time, strongly-consistent source of truth.
  • Confusing lease-renewal-interval (heartbeat) with registry-fetch-interval (client cache refresh).

context