vitessio/vitess · info

ignoring lower bad rate of %v because such a high degradatio

Error message

ignoring lower bad rate of %v because such a high degradation (%.1f%%) is unlikely (current highest good: %v)

What it means

memory.markBad() ignores a 'bad' rate that is more than 10% below the current highest good rate, because such a drastic drop is statistically unlikely to indicate a real capacity change (more likely noise). The bad observation is discarded and this error is returned.

Source

Thrown at go/vt/throttler/memory.go:119

func (m *memory) markBad(rate int64, now time.Time) error {
	// Bad rates are rounded up instead of down to not be too extreme on the
	// reduction and account for some margin of error.
	rate = m.roundUp(rate)

	// Ignore higher bad rates than the current one.
	if m.bad != 0 && rate >= m.bad {
		return nil
	}

	// Ignore bad rates which are too drastic. This prevents that temporary
	// hiccups e.g. during a reparent, are stored in the memory.
	// TODO(mberlin): Remove this once we let bad values expire over time.
	highestGood := m.highestGood()
	if rate < highestGood {
		decrease := float64(highestGood) - float64(rate)
		degradation := decrease / float64(highestGood)
		if degradation > 0.1 {
			return fmt.Errorf("ignoring lower bad rate of %v because such a high degradation (%.1f%%) is unlikely (current highest good: %v)", rate, degradation*100, highestGood)
		}
	}

	// Delete all good values which turned bad.
	goodLength := len(m.good)
	for i := goodLength - 1; i >= 0; i-- {
		goodRate := m.good[i]
		if goodRate >= rate {
			goodLength = i
		} else {
			break
		}
	}
	m.good = m.good[:goodLength]

	m.bad = rate
	m.touchBadRateAge(now)
	return nil

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. No action needed — the module deliberately ignores implausible drops.
  2. If degradation is real, it will be observed repeatedly; sustained bad rates below the 10% threshold will eventually be recorded.
  3. Check for measurement artifacts (low thread count, short sampling window) if valid degradations are being ignored.
Defensive patterns

Strategy: try-catch

Try / catch

if err := mem.markBad(rate); err != nil {
    log.Debug("bad rate ignored as implausible", slog.Any("error", err))
}

Prevention

When it happens

Trigger: markCurrentRateAsBadOrGood calls markBad(rate) when rate < highestGood and (highestGood-rate)/highestGood > 0.1, e.g. a transient measurement dip after the throttler is told the current rate was bad.

Common situations: A single slow query or temporary stall causes a spiky low observed rate; throttler threads report rates unevenly under low concurrency.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/237d6f4b2995d4d6. Report an issue: GitHub.