pekko: bound how long a penalty can last - #1965
Merged
brharrington merged 1 commit intoAug 11, 2026
Merged
Conversation
Demerit grows by one step per denial and decays at a fixed rate, so how long a caller stays penalized is set by how much demerit it accrued. It is clamped only where more of it could no longer contain a hog any further, which for a budget of 100 is 103, and at the default decay of 0.3 per second that is close to six minutes of penalty bought by a burst lasting a second. A larger budget raises the clamp and with it the duration. Lowering the clamp is the wrong fix. The containment formula is `share - demerit`, so demerit has to be able to reach the size of the share for a hog to be held down to its floor; capping it lower would leave a hog on a large budget almost unconstrained. Bound the duration instead. Demerit is dropped outright once it is older than `max-penalty-duration` (default 60s), measured from the last denial, so a caller that keeps hammering stays penalized for as long as it keeps it up but recovers within the horizon of backing off. The magnitude is untouched, so containment is exactly as strong as it was. Expiring the value rather than time-boxing a separate "is penalized" test means every reader picks the bound up for free: the cap, the contention check, and the pruning of callers that have gone idle all go through `demerit`. The pruning matters here, since a caller whose demerit is still decaying is retained rather than reclaimed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Demerit grows by one step per denial and decays at a fixed rate, so how long a caller stays penalized is set by how much demerit it accrued. It is clamped only where more of it could no longer contain a hog any further, which for a budget of 100 is 103, and at the default decay of 0.3 per second that is close to six minutes of penalty bought by a burst lasting a second. A larger budget raises the clamp and with it the duration.
Lowering the clamp is the wrong fix. The containment formula is
share - demerit, so demerit has to be able to reach the size of the share for a hog to be held down to its floor; capping it lower would leave a hog on a large budget almost unconstrained.Bound the duration instead. Demerit is dropped outright once it is older than
max-penalty-duration(default 60s), measured from the last denial, so a caller that keeps hammering stays penalized for as long as it keeps it up but recovers within the horizon of backing off. The magnitude is untouched, so containment is exactly as strong as it was.Expiring the value rather than time-boxing a separate "is penalized" test means every reader picks the bound up for free: the cap, the contention check, and the pruning of callers that have gone idle all go through
demerit. The pruning matters here, since a caller whose demerit is still decaying is retained rather than reclaimed.