Glossary

Sigop Budget

Learn what the sigop budget is in Bitcoin and how it limits signature operations per block to prevent DoS attacks.

Key Takeaways

  • The sigop budget caps the number of computationally expensive signature operations that can appear in a Bitcoin block, preventing denial-of-service attacks that exploit slow cryptographic verification.
  • Bitcoin uses two accounting systems: a block-wide weighted limit of 80,000 sigop cost units (introduced by SegWit), and a per-input budget for Tapscript that ties allowed signature checks to the witness size of each input.
  • The per-input Tapscript budget replaced the rigid block-wide cap for Taproot spends, enabling more complex scripts like large multisig arrangements without hitting a global ceiling.

What Is the Sigop Budget?

The sigop budget is a consensus-enforced limit on signature operations (sigops) in Bitcoin. Signature verification is the most CPU-intensive step in validating a transaction: each OP_CHECKSIG or OP_CHECKMULTISIG call requires an elliptic curve multiplication against the transaction hash. Without a cap, an attacker could craft a single block packed with thousands of signature checks, stalling every node on the network for minutes.

The budget has evolved across three eras of Bitcoin Script: the original pre-SegWit static count, the SegWit weighted model, and the Tapscript per-input budget. Each revision refined how Bitcoin accounts for verification cost while preserving the core goal of bounding validation time.

How It Works

Bitcoin enforces sigop limits at two levels depending on the script type. Legacy and SegWit v0 scripts are subject to a block-wide cap, while Tapscript inputs use a per-input budget that scales with witness size.

The Original Limit (Pre-SegWit)

Satoshi introduced sigop counting as a soft fork early in Bitcoin's history. The original rule was straightforward: a block could contain at most 20,000 signature operations. Every OP_CHECKSIG counted as 1 sigop, and every OP_CHECKMULTISIG was assumed to cost 20 sigops regardless of how many keys it actually checked.

Counting was entirely static: the validator scanned both scriptSig and scriptPubKey for signature opcodes without executing the script. This meant sigops in unexecuted branches (inside OP_IF blocks that would never run) still counted toward the limit, and multisig operations were overcounted since a 2-of-3 multisig used the same 20-sigop budget as a 15-of-15.

SegWit Weighted Accounting (BIP 141)

When SegWit activated in August 2017, it introduced weight units for measuring block capacity. Sigop accounting followed the same pattern: the block limit became 80,000 weighted sigop cost units (MAX_BLOCK_SIGOPS_COST), with legacy sigops multiplied by a scale factor of 4.

// SegWit sigop cost calculation
WITNESS_SCALE_FACTOR = 4

// Legacy/P2SH sigops cost 4 units each
legacy_sigop_cost = legacy_sigop_count × WITNESS_SCALE_FACTOR

// Witness (SegWit v0) sigops cost 1 unit each
witness_sigop_cost = witness_sigop_count × 1

// Total block sigop cost must not exceed 80,000
total_sigop_cost = legacy_sigop_cost + witness_sigop_cost
assert(total_sigop_cost <= 80000)  // MAX_BLOCK_SIGOPS_COST

This weighted model aligned sigop accounting with the block weight limit of 4,000,000 weight units. A fully legacy block still had an effective cap of 20,000 sigops (20,000 x 4 = 80,000 cost), while a block composed entirely of SegWit transactions could include up to 80,000 witness sigops. Additionally, for relay purposes, Bitcoin Core enforces a per-transaction policy limit of 16,000 sigop cost (one-fifth of the block limit), though this is not a consensus rule.

Tapscript Per-Input Budget (BIP 342)

Tapscript, activated with Taproot at block 709,632 in November 2021, took a fundamentally different approach. Instead of contributing to the block-wide 80,000 limit, Tapscript inputs have their own per-input sigop budget calculated from the witness size:

// BIP 342 per-input sigop budget
sigop_budget = 50 + witness_size_bytes

// Each successful signature check costs 50 from the budget
// Empty signatures (for OP_CHECKSIGADD aggregation) cost 0
// Script fails if sigop_budget < 0 after all checks

The logic behind this formula is elegant: a valid Schnorr signature is 64 bytes and a public key is 32 bytes, so each signature check naturally consumes at least 96 bytes of witness space. Since the budget grants one signature check per 50 bytes of witness, any script with real signatures and keys will never exhaust the budget. Only pathologically constructed scripts with many sigops but almost no data would hit the limit.

The base allowance of 50 ensures that even a minimal witness can include at least one signature verification, preventing edge cases where a valid single-sig spend would fail the budget check.

Why It Matters

The sigop budget is a critical piece of Bitcoin's security model. It bounds the worst-case CPU time a block can impose on every full node in the network. Without it, a miner could produce a valid block that takes minutes to verify, disrupting block propagation and potentially enabling selfish mining strategies.

The evolution from a static block-wide cap to a per-input budget reflects Bitcoin's broader move toward more granular resource accounting. The Tapscript approach is particularly important for enabling advanced spending conditions: a 50-of-100 multisig using OP_CHECKSIGADD would consume 50 x 50 = 2,500 budget units from its sigop budget, which means the input's witness would need to be at least 2,450 bytes (2,500 - 50 base). Since 100 public keys (32 bytes each) and 50 signatures (64 bytes each) already total 6,400 bytes of witness data, the budget is easily satisfied.

For a deeper look at how these constraints shape what is possible in Bitcoin Script, see the research article on Bitcoin Script programmability.

Use Cases

Multisig and Threshold Signatures

The per-input budget is especially relevant for large multisig setups. Under the legacy block-wide limit, a transaction with many signature checks could consume a disproportionate share of the block's sigop budget, crowding out other transactions. With Tapscript, each input only needs enough witness data to justify its signature operations, and the cost is self-contained.

Protocols like MuSig2 and FROST aggregate multiple signers into a single key-path spend that uses just one signature, avoiding the sigop budget question entirely. When key-path spending is not possible and a script-path fallback is needed, the per-input budget ensures the additional signature checks remain bounded.

Complex Spending Conditions

Tapscript removed the 201 non-push opcode limit and the 10,000-byte script size cap that constrained legacy scripts. The per-input sigop budget is now the primary constraint on how many signature checks a single input can perform. This enables more expressive spending policies built with Miniscript and complex Taptree structures.

Protocol Design

Layer 2 protocols and covenant proposals must account for sigop budgets when designing their on-chain footprint. A commitment transaction with many outputs, each requiring signature verification, needs to ensure its total sigop cost stays within bounds. The per-input model simplifies this analysis: each input's budget is independent, so adding more inputs does not reduce the budget available to existing ones.

Risks and Considerations

Legacy Overcounting

The legacy and SegWit v0 sigop counting still applies to non-Taproot transactions. Overcounting from OP_CHECKMULTISIG (always charged at 20 sigops regardless of the actual key count) wastes block capacity. This is one reason OP_CHECKSIGADD was introduced in Tapscript: it replaces the overcounted multisig pattern with individual signature checks that each cost exactly 1 unit from the budget.

Block Validation Asymmetry

Even with the sigop budget, block validation time is not perfectly predictable. Signature verification speed depends on hardware, and the budget does not account for other costs like hashing or stack operations. The proposed BIP 440 (Varops Budget) aims to generalize the Tapscript budget model to cover non-signature opcodes as well, creating a more comprehensive resource accounting system.

Interaction with Block Weight

The sigop budget and the block weight limit are independent constraints. A block must satisfy both: total weight under 4,000,000 units and total sigop cost under 80,000 (for legacy and SegWit v0 scripts). In practice, the weight limit is almost always the binding constraint, since typical transactions carry far fewer sigops per byte than the budget allows. However, adversarially constructed transactions can hit the sigop limit before the weight limit, which is precisely why the budget exists.

Transition Complexity

Having two parallel systems (block-wide for legacy/SegWit v0 and per-input for Tapscript) adds complexity to block validation logic. Miners building block templates must track both budgets simultaneously when selecting transactions. The Great Consensus Cleanup proposal has discussed adding a per-transaction cap of 2,500 legacy sigops to further tighten the legacy rules without a full migration to the Tapscript model.

This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.