Bug Description
EmaHealthTracker::record in crates/backend/src/health.rs computes latency using a simple moving average rather than a true exponential moving average:
rust
// Current implementation
self.latency_ema = (self.latency_ema + duration) / 2;
This always assigns 50% weight to the most recent sample regardless of history. A true EMA uses a configurable smoothing factor alpha:
rust
// Correct EMA
new = alpha * sample + (1 - alpha) * old
Impact
With the current formula, a single high-latency spike immediately pulls the EMA up by 50%, potentially triggering a Degraded health status for a backend that is otherwise healthy. A proper EMA with a small alpha (e.g. 0.1) smooths over transient spikes and gives more stable health tracking which is critical for correct load balancing decisions in a production RPC proxy.
Proposed Fix
Add an alpha: f64 field to HealthConfig (default 0.1)
Replace the formula with alpha * sample + (1 - alpha) * old
Update existing tests to reflect corrected behavior
Bug Description
EmaHealthTracker::record in crates/backend/src/health.rs computes latency using a simple moving average rather than a true exponential moving average:
rust
// Current implementation
self.latency_ema = (self.latency_ema + duration) / 2;
This always assigns 50% weight to the most recent sample regardless of history. A true EMA uses a configurable smoothing factor alpha:
rust
// Correct EMA
new = alpha * sample + (1 - alpha) * old
Impact
With the current formula, a single high-latency spike immediately pulls the EMA up by 50%, potentially triggering a Degraded health status for a backend that is otherwise healthy. A proper EMA with a small alpha (e.g. 0.1) smooths over transient spikes and gives more stable health tracking which is critical for correct load balancing decisions in a production RPC proxy.
Proposed Fix
Add an alpha: f64 field to HealthConfig (default 0.1)
Replace the formula with alpha * sample + (1 - alpha) * old
Update existing tests to reflect corrected behavior