---
title: "Proposal throttles and governance rate limits"
url: "https://caper.network/wiki/dao-governance/concepts/voting/proposal-throttles-and-rate-limits"
updated: 2026-08-12
license: CC-BY-4.0
license_url: "https://creativecommons.org/licenses/by/4.0/"
---

# Proposal throttles and governance rate limits

| Concept | Proposal throttles — the rules that bound _how many_ proposals can reach a vote, _who_ may open one, and _what it costs_ |
| --- | --- |
| Problem addressed | Governance spam, voter fatigue, and griefing a treasury through the cost of processing proposals |
| Common mechanisms | Sponsor thresholds · proposal deposits and offerings · concurrency caps · action and payload caps · expirations · retroactive cancellation |
| Reference implementations | [Compound Governor Bravo](https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/GovernorBravoDelegate.sol) · [Moloch v2](https://github.com/MolochVentures/moloch/blob/master/contracts/Moloch.sol) · [Baal](https://github.com/HausDAO/Baal/blob/main/contracts/Baal.sol) (DAOhaus v3) |
| Key trade-off | Every throttle that stops spam also raises the floor on who can govern |

## What a throttle is, and why it is not a quorum

Most DAO design attention goes to how votes are _counted_ — [quorum and threshold design](/wiki/dao-governance/concepts/voting/quorum-and-threshold-design), [token weighting](/wiki/dao-governance/concepts/voting/token-weighted-voting), [quadratic schemes](/wiki/dao-governance/concepts/voting/quadratic-voting-and-funding). A throttle acts one stage earlier: it decides which proposals get to exist. Quorum rules answer "did enough weight participate?"; throttles answer "may this proposal be put in front of anyone at all?"

The distinction matters because the two failure modes are different. A badly-set quorum produces the wrong _outcome_. A missing throttle produces no outcome at all: an open proposal queue is a channel any address can write to, and a governance system whose voters are exhausted has effectively lost quorum without ever changing the number. The [proposal lifecycle](/wiki/dao-governance/concepts/voting/proposal-lifecycle) describes the stages a proposal passes through; this page covers the gates on the entrance.

Four costs are being rationed, and a given mechanism usually targets one of them:

- **Attention** — voters and delegates can only read so much. This is the cost [holographic consensus](/wiki/dao-governance/concepts/voting/holographic-consensus) attacks by making prediction markets triage the queue.
- **Gas and settlement work** — someone has to pay to conclude every proposal, whether or not it passes.
- **Storage** — proposal metadata is written to a substate or contract that later operations must traverse.
- **Legitimacy** — a queue full of unserious proposals makes the serious ones harder to see, and makes low turnout look normal.

## Sponsor thresholds: who may open a proposal

The oldest throttle is a floor on the proposer. Compound's [Governor Bravo](https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/GovernorBravoDelegate.sol) — the template most token-weighted DAOs inherited — gates `propose()` on `comp.getPriorVotes(msg.sender, block.number - 1) > proposalThreshold`, measured one block back so the threshold cannot be met with a flash loan taken in the same block. The threshold is itself bounded: governance may set it anywhere between `MIN_PROPOSAL_THRESHOLD` of 1,000 COMP and `MAX_PROPOSAL_THRESHOLD` of 100,000 COMP, so no vote can raise the drawbridge past a hard ceiling or lower it to zero.

Bravo also ships the exemption that every threshold eventually needs. `isWhitelisted(account)` returns true while `whitelistAccountExpirations[account] > block.timestamp`, letting governance grant a named address time-limited permission to propose below the threshold — the standard remedy for the case where the people best placed to write proposals are not the people holding the most tokens. See [voting power activation and delegation thresholds](/wiki/dao-governance/concepts/voting/voting-power-activation) for how that floor interacts with delegation.

The Moloch lineage draws the line at membership rather than magnitude. In [Moloch v2](https://github.com/MolochVentures/moloch/blob/master/contracts/Moloch.sol) any address can submit a proposal, but it sits inert until a member _sponsors_ it into the voting queue — `submitProposal` and `sponsorProposal` are separate functions, the second carrying an `onlyDelegate` modifier, and the proposal struct records the sponsor's address alongside a `sponsored` flag. The queue is member-curated by construction. [Baal](https://github.com/HausDAO/Baal/blob/main/contracts/Baal.sol), the v3 rewrite, makes the same idea numeric: `sponsorThreshold` is documented as a "minimum number of shares to sponsor a proposal (_not %_)", and a submitter above it self-sponsors, skipping the queue and starting its own voting clock in the same transaction.

Off-chain governance reaches the same design by social means. Long COVID Labs' own governance framework, [LCL DP-1](https://snapshot.box/#/s:longcovidlabs.eth/proposal/0x7cefbd56122cb21bc08a8aba952d35c31bc800a9e2f0e31c55d0ffc42e0d483e), requires a proposal to spend four days in the DAO's public Telegram and collect at least ten 👍 reactions _including at least one from a named core-team member_ before it may go to a binding Snapshot vote. That is a sponsor threshold with a human quorum and a core-team veto, implemented entirely in emoji.

## Deposits, offerings, and who is really being charged

A price on proposing is the throttle most often reached for and most often mis-specified, because two different things get called the same thing.

A **refundable deposit** prices bad faith, not proposing. Moloch v2 holds a `proposalDeposit` — the deployed default was 10 ETH, roughly $1,000 at the time — and returns it when the proposal is processed. What it does not return is the `processingReward` (default 0.1 ETH), which `_returnDeposit` pays out of escrow to whoever calls the processing function, with the remainder going back to the sponsor. The contract enforces the relationship at construction: `require(_proposalDeposit >= _processingReward)`. The deposit exists to fund the conclusion of the proposal, and only the leftover is a returnable bond.

A **non-refundable offering** prices access. Baal's `proposalOffering` is charged only to submitters _below_ the sponsor threshold — the code comments call it an "Optional anti-spam gas token tribute" — so members propose free and outsiders pay. That is a deliberate two-tier entrance, and worth naming as such: a fee framed as anti-spam is frequently a membership boundary wearing a price tag.

The distinction has a practical test. Ask what the money is _for_. If it funds the work of concluding the proposal, it is a settlement pre-payment and it should be sized to that work. If it is returned on good behaviour, it is a bond and should be sized to the harm. If it is neither returned nor spent on the proposal, it is a toll, and the honest question is who it is meant to keep out.

## Concurrency, size, and expiry caps

Thresholds bound _who_; the rest of the throttle family bounds _how much_.

**One proposal at a time.** Governor Bravo enforces a per-proposer concurrency cap of exactly one, and does it twice — `propose()` reverts with "one live proposal per proposer" if the caller's latest proposal is in either the `Active` or the `Pending` state. Checking both matters: a cap that only looked at `Active` could be defeated by queueing proposals during the voting delay.

**A cap on the whole queue.** A per-proposer limit does nothing against many proposers, so systems that automate proposal creation tend to add a global one. DAOhaus's agent runbook, [AGENT_TASKS.md](https://github.com/HausDAO/moloch-skills/blob/main/AGENT_TASKS.md), instructs an autonomous member to open no new proposal while three are already in voting — a queue-depth cap chosen because the constraint being protected is human review capacity, not chain capacity. The same document tells the agent to read process-readiness from the contract's own `state(id)` rather than an indexer's flag, which is the operational half of the same discipline.

**Payload caps.** Bravo sets `proposalMaxOperations = 10`, bounding how many actions one vote can authorize — a limit on blast radius as much as on cost, and a close relative of [typed versus arbitrary execution](/wiki/dao-governance/concepts/voting/typed-vs-arbitrary-execution). Baal takes the storage-side route and persists only `hashOperation(proposalData)`, keeping the payload off-chain entirely and the hash as the commitment.

**Expiry.** Baal proposals carry an `expiration` field, required to be either zero or later than `block.timestamp + votingPeriod + gracePeriod`, so a proposal can be written to die rather than linger. An expiring queue is self-cleaning; a permanent one accumulates.

## Throttles that reach backwards

The subtle members of the family apply after a proposal is already live, and they exist because eligibility can change mid-flight.

Governor Bravo lets _anyone_ cancel a live proposal once its proposer's voting power has fallen below `proposalThreshold` — for a whitelisted proposer, only the `whitelistGuardian` may do it. The effect is that the threshold is a continuing requirement, not an entry test: a proposer who borrows or is delegated enough weight to propose and then gives it up loses the proposal too.

Moloch's `jailed` field is the membership analogue. A member with a passing guild-kick proposal against them is barred from both voting and sponsoring, and several code paths refuse to act on a jailed applicant at all — the throttle prevents a member on the way out from filling the queue on the way.

Baal's `minRetentionPercent` is the most interesting of the three because it throttles on the _voters'_ behaviour rather than the proposer's: a proposal auto-fails if more than `(1 − minRetentionPercent)` of total shares exit before it is processed. It is a rate limit on governing a membership that is leaving, and a structural answer to the ragequit-then-execute problem that [governance timelocks](/wiki/dao-governance/concepts/voting/governance-timelocks) address from the other end.

## The trade-off nobody escapes

Every throttle listed here works, and every one of them raises the floor on who can participate. A 100,000 COMP proposal threshold makes spam impossible and makes independent proposing the preserve of large holders and whitelist grantees. A member-sponsorship gate keeps the queue serious and makes the member set the gatekeeper of what the DAO is allowed to consider. A non-refundable offering deters drive-by proposals and charges exactly the people who are not yet inside.

Two rules of thumb survive contact with the implementations above. First, **price the work, not the person**: a charge sized to the cost of concluding a proposal is defensible at any wealth level, while a charge sized to deter is a wealth test by construction. Second, **cap the queue, not the proposer**, where you can — a depth cap on proposals in voting protects reviewer attention without asking who wrote them, whereas a per-proposer cap is trivially defeated by using two addresses.

The honest reading of the record is that most DAOs adopt throttles reactively, after a queue fills or a treasury is griefed, and inherit whichever numbers their framework shipped with. The parameters are rarely revisited even as the token distribution that made them reasonable changes underneath them.

## How Caper approaches this

A [caper](/wiki/foundations/what-is-a-caper) carries four throttles, and the interesting one is a fee that is explicitly not an anti-spam price.

Opening a [proposal](/wiki/governance/proposals) requires an exact XRD payment equal to the caper's `proposal_fee`, 500 XRD by default — _exact_, so an over-payment aborts rather than tipping the treasury — and there is no refund path: the payment is banked by the caper it was proposed to. The fee has a floor written into the fee-setting function itself, `proposal_fee >= SETTLEMENT_GAS_BUDGET`, with the reason stated in the source: so that "the permissionless settle path can never draw more treasury than the proposal itself banked." That is Moloch's `require(_proposalDeposit >= _processingReward)` invariant reached independently — a proposal must pre-fund the work of concluding it — and it means the fee's size is derived from settlement cost rather than chosen to deter.

The proposer must also hold at least one of the caper's own tokens, checked as a proof at creation, which is a sponsor threshold set to the minimum non-zero value: membership, not magnitude. Metadata is capped at 512 bytes of title and 16,384 of description, and the source names the reason plainly — unbounded, the meta blob "is a free griefing lever on every write that touches its substate."

The fourth is a throttle deliberately left off. A caper sets **no cap on the number of voters** in a proposal, because settlement is chunked across transactions rather than iterating every ballot in one, so a large turnout cannot brick the settle path. It is worth stating as its own point: several throttles in this family exist only because concluding a proposal is a single unbounded loop, and making that loop resumable removes the need for the limit rather than tuning it.
