# FlexibleProportions — Per-Entity Fraction Tracking
**"What % of total does entity X contribute?"** with lazy per-entity decay.
From Linux kernel `lib/flex_proportions.c`.
| Update cost | O(1) per event |
| Memory | ~16 bytes per entity + ~16 bytes global |
| Types | `FlexProportionGlobal`, `FlexProportionEntity` |
## What It Does
Tracks a global event stream and per-entity contributions. Each entity's
fraction decays over time — recent activity matters more than old.
```
Global events: 1000 total
Entity A: 400 recent events → 40%
Entity B: 350 recent events → 35%
Entity C: 250 recent events → 25%
After Entity A goes quiet:
Entity A: fraction decays toward 0%
Entity B and C: fractions increase proportionally
```
**Lazy decay:** Per-entity counters only decay when queried. If you have
1000 entities but only check 3, you pay for 3 decays — not 1000.
## Configuration
```rust
let mut global = FlexProportionGlobal::new(1000); // half-life: 1000 events
let mut entity_a = FlexProportionEntity::new();
let mut entity_b = FlexProportionEntity::new();
// On each event, record to both global and the responsible entity:
global.record();
entity_a.record(&mut global);
// Query:
let pct_a = entity_a.fraction(&global); // 0.0 to 1.0
```
## Examples
### Trading — Shard Load Balancing
```rust
// Track which symbols generate most traffic for capacity planning
let mut global = FlexProportionGlobal::new(100_000);
let mut per_symbol: HashMap<Symbol, FlexProportionEntity> = ...;
// On each market data message:
global.record();
per_symbol.get_mut(&symbol).record(&mut global);
// Periodically check distribution:
for (sym, entity) in &per_symbol {
let pct = entity.fraction(&global);
if pct > 0.20 { /* this symbol is >20% of traffic */ }
}
```
### SRE — Service Traffic Distribution
```rust
// Which endpoints consume the most resources?
let mut global = FlexProportionGlobal::new(50_000);
let mut per_endpoint: HashMap<String, FlexProportionEntity> = HashMap::new();
// On each request:
global.record();
per_endpoint.entry(endpoint.clone())
.or_insert_with(FlexProportionEntity::new)
.record(&mut global);
// Review: which endpoint is heaviest?
for (ep, entity) in &per_endpoint {
let pct = entity.fraction(&global);
if pct > 0.25 { log::warn!("{ep} handles {:.0}% of traffic", pct * 100.0); }
}
```
## Performance
O(1) per event and per query. The lazy decay catch-up is O(1) — it
applies the decay exponent for the elapsed periods in one computation.
## Background
Linux kernel implementation: `lib/flex_proportions.c`. Used for dirty page
throttling — tracking what fraction of dirty pages each cgroup is responsible for.
Note: decay is coarse-grained (halving every N events). For smooth exponential
decay, use [DecayingAccumulator](decay-accum.md) instead.