# Increase `CHURN_LIMIT_QUOTIENT`
## Rationale
Current `CHURN_LIMIT_QUOTIENT` in Gnosis is low such that the network's validator set can change significantly in short periods of time posing unnecessary risks to the network. The original value was chosen without a great deal of care to facilitate staker onboarding UX. Even that argument will no longer apply with [`eip6110`](https://github.com/ethereum/consensus-specs/blob/dev/specs/_features/eip6110/beacon-chain.md) (in-protocol deposits).
`CHURN_LIMIT_QUOTIENT` dictates the `validator_churn_limit` which is constant through an epoch variable only to active validator count.
```python
def get_validator_churn_limit(state: BeaconState) -> uint64:
"""
Return the validator churn limit for the current epoch.
"""
active_validator_indices = get_active_validator_indices(state, get_current_epoch(state))
return max(MIN_PER_EPOCH_CHURN_LIMIT, uint64(len(active_validator_indices)) // CHURN_LIMIT_QUOTIENT)
```
([specs/phase0/beacon-chain.md](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_validator_churn_limit))
## Inflow
Higher `CHURN_LIMIT_QUOTIENT` results in less validators dequeued from that epoch's `activation_epoch`.
```python
def process_registry_updates(state: BeaconState) -> None:
...
# Dequeued validators for activation up to churn limit
for index in activation_queue[:get_validator_churn_limit(state)]:
validator = state.validators[index]
validator.activation_epoch = compute_activation_exit_epoch(get_current_epoch(state))
```
## Outflow
The result of computing the validator churn limit is persisted in the state for outflows. Below `initiate_validator_exit`
- Compute the highest registered `exit_epoch`, and count how many validators will exit at the epoch
- If that count exceeds churn limit, schedule to exit validator at max epoch + 1. By definition that will not have any validators scheduled to exit on it
```python
def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
...
# Compute exit queue epoch
exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH]
exit_queue_epoch = max(exit_epochs + [compute_activation_exit_epoch(get_current_epoch(state))])
exit_queue_churn = len([v for v in state.validators if v.exit_epoch == exit_queue_epoch])
if exit_queue_churn >= get_validator_churn_limit(state):
exit_queue_epoch += Epoch(1)
# Set validator exit epoch and withdrawable epoch
validator.exit_epoch = exit_queue_epoch
validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
```
Irrespective of the current status of the exit churn, the chrun decrease is well handled with the spec as is.

Implementations must make sure to invalidate any exit churn cache and recompute that fork boundary.
## New `CHURN_LIMIT_QUOTIENT`
TBD pending research. Current tentative value Ethereum's `65536`
## Max churn simulation
Consensus layer config differences to Ethereum
| Config value | Ethereum | Gnosis |
| -------- | -------- | -------- |
| `CHURN_LIMIT_QUOTIENT` | 65536 | 4096 |
- `CHURN_LIMIT_QUOTIENT`: The churn to enter and exit the validator set is greater. For 100_000 validators, _100000 / 4096 = 24_ validators can activate and exit per epoch.
Churn out | Churn in
:-------------------------:|:-------------------------:
 | 
 | 