Skip to content

pekko: bound how long a penalty can last - #1965

Merged
brharrington merged 1 commit into
Netflix:mainfrom
brharrington:fair-share-penalty-duration
Aug 11, 2026
Merged

pekko: bound how long a penalty can last#1965
brharrington merged 1 commit into
Netflix:mainfrom
brharrington:fair-share-penalty-duration

Conversation

@brharrington

Copy link
Copy Markdown
Contributor

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.

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.
@brharrington brharrington added this to the 1.9.0 milestone Aug 11, 2026
@brharrington
brharrington merged commit df5cba9 into Netflix:main Aug 11, 2026
5 checks passed
@brharrington
brharrington deleted the fair-share-penalty-duration branch August 11, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant