The Cost of Bitcoin-Anchored Identity: A Ten-Year Fee Model

Sep 25, 2026

Introduction

"What does it cost to anchor identity to Bitcoin?" A person who controls a budget usually asks this question first. Many of the current answers show no calculation. Some answers say that Bitcoin is too expensive for all uses except high-value settlement. Other answers say that the cost is trivial, but they give no numbers.

The calculation is not difficult. This post does it in four steps:

  1. Calculate the size of a Beacon Signal in vbytes.
  2. Calculate the cost of that signal at different fee rates.
  3. Show how aggregation changes the cost for each DID.
  4. Calculate the ten-year totals for two example deployments.

The result is probably not what a skeptic expects. But the result also does not show that an anchor in Bitcoin is free.

All on-chain figures are in satoshis (sats). A conversion to fiat money needs an assumption about the price of bitcoin, and this post does not make that assumption.

The Size of a Beacon Signal

A Singleton Beacon Signal is a normal Bitcoin transaction. It spends a UTXO at the Beacon Address. Its last output is an OP_RETURN output that holds the Signal Bytes. The specification fixes the size of this payload, so the calculation is stable. A Beacon Signal "commits to, and anchors in a Bitcoin block, 32 bytes of information" (Beacons). These 32 bytes are an update announcement, the hash of a Beacon Announcement Map, or the root of a Sparse Merkle Tree (SMT).

The usual transaction has one Taproot (P2TR) key-path input, one P2TR change output, and one OP_RETURN output with the 32-byte payload. We measure its size in virtual bytes (vB), as BIP 141 defines them. The transaction weight is the base size times three, plus the total size. The virtual size is the weight divided by four, rounded up.

ComponentWeightSize
Overhead: version, input count, output count, and locktime (10 bytes), plus the segwit marker and flag (2 bytes of witness data)42 WU10.5 vB
P2TR key-path input: 41 bytes of base data and a 66-byte witness230 WU57.5 vB
P2TR change output (43 bytes)172 WU43 vB
OP_RETURN output with a 32-byte payload (43 bytes)172 WU43 vB
Total616 WU154 vB

The witness is small. A key-path spend needs one 64-byte Schnorr signature (BIP 341). The witness adds one byte for the item count and one byte for the length, so it is 66 bytes. Witness bytes count as one weight unit each, and base bytes count as four (BIP 141). Thus the witness adds 16.5 vB, not 66 vB.

Taproot does not make a Singleton Beacon Signal smaller than the older SegWit form. A P2WPKH input is larger than a P2TR input (68 vB, not 57.5 vB). But a P2WPKH change output is smaller (31 vB, not 43 vB). Thus a P2WPKH signal with P2WPKH change is about 153 vB. The code comments of the reference implementation give the same figures: 154 vB for P2TR and 153 vB for P2WPKH (beacon.ts).

The advantage of Taproot for beacons is aggregation. With MuSig2, many keys make one 64-byte signature, as the next section shows. The post From Taproot to DIDs describes these protocol upgrades.

The cost at different fee rates is:

Fee rateCost of one signal
0.1 sat/vBabout 15 sats
1 sat/vB154 sats
5 sat/vB770 sats
10 sat/vB1,540 sats
50 sat/vB7,700 sats
100 sat/vB15,400 sats
250 sat/vB38,500 sats

The first row is possible because Bitcoin Core 29.1 changed the default minimum relay fee rate to 0.1 sat/vB (29.1 release notes). But if the network does not widely adopt the new defaults, transactions at these rates "are not guaranteed to propagate or confirm" (29.1 release notes).

For context, we calculated these values from the block fee-rate data of mempool.space:

  • From September 2016 to September 2026, the daily median fee rate in blocks had an average of about 41 sat/vB.
  • In the same period, the daily median was 100 sat/vB or more on about 11% of days. It was 200 sat/vB or more on about 4% of days.
  • The highest average of the daily median over any 365 days was about 189 sat/vB, in the year to February 2018.
  • The highest daily medians were about 930 sat/vB on 22 December 2017 and about 870 sat/vB on 20 April 2024. On 20 April 2024, block 840,000 cut the block subsidy in half for the fourth time (Bitcoin Core chainparams).
  • In 2026 to 25 September, the daily median was 2 sat/vB or less on 98% of days.

The sizes above are a minimum, not a typical total. Some Beacon Signals are larger:

  • A transaction with more than one input is larger. This occurs if no single UTXO at the beacon can pay the fee.
  • A legacy P2PKH beacon gets no witness discount. A P2PKH signal with P2PKH change is about 235 vB, and the reference implementation budgets 240 vB for it.

The P2PKH case is real. For a key-based did:btcr2 identifier, the initial DID document has three Singleton Beacons. They use the P2PKH, P2WPKH, and P2TR addresses of the genesis key. A controller can use the P2TR or P2WPKH beacon for its normal updates. For fee headroom, the reference implementation budgets 160 vB for a P2TR signal, not 154 vB (beacon.ts).

What Aggregation Saves

This number changes the economics.

A MuSig2 aggregate beacon spends one key-path input, for any number of participants. With MuSig2, n public keys aggregate to one key, and n partial signatures aggregate to one 64-byte Schnorr signature. Bitcoin nodes see a normal single-signature Taproot spend. Thus the transaction stays at about 154 vB for a cohort of 2 or a cohort of 2,000.

Cohort sizevB for each participantAt 10 sat/vBAt 100 sat/vB
1 (Singleton)1541,540 sats15,400 sats
1015.4154 sats1,540 sats
1001.54about 15 sats154 sats
1,0000.154about 1.5 satsabout 15 sats

In a cohort of 1,000, one update costs a participant about 1.5 sats in on-chain fees at 10 sat/vB. At 100 sat/vB, a rate of severe congestion, it costs about 15 sats.

These figures assume that all participants sign. The reference implementation also adds a k-of-n fallback leaf to the beacon output (ADR 042). The section about unconfirmed signals below describes it. A spend through that leaf holds k signatures and a script that lists all n keys, so its size increases with the cohort. With the default k = n-1, our calculation gives these sizes:

  • about 387 vB for a cohort of 10
  • about 2,615 vB for a cohort of 100
  • about 12,500 vB for a cohort of 500

Even for a cohort of 500, that is about 25 vB for each participant. The script uses 34 bytes for each key, and the control block is 65 bytes. BIP 342 limits the stack to 1,000 elements, and this limit also applies to the initial stack. The witness of this leaf holds one element for each key, and the script then pushes one more. Thus a leaf of this form cannot be spent with 1,000 or more keys.

The on-chain result is good, but it has a condition: the on-chain fee is not the only cost of aggregation.

  • Someone must operate the Aggregation Service.
  • Each update waits for a cohort round. It does not go out when you are ready.
  • Each participant must respond in each round, so one absent participant affects the full cohort.
  • A resolver must process each Beacon Signal of each beacon in the DID document. Thus each participant keeps data for each cohort signal, also for signals with no update for its DID.

The last item is a storage cost. For a CAS Beacon, the resolver needs the Beacon Announcement Map of each signal, from sidecar data or from CAS (Process CAS Beacon). For an SMT Beacon, the resolver needs an SMT Proof for each signal (Process SMT Beacon). The Aggregation Service builds these proofs, and the participant must keep them (Aggregate Beacons). An SMT leaf can include a nonce, but the nonce is OPTIONAL in the specification (Optimized SMT).

Someone also pays the on-chain fee. In the reference implementation, the operator of the Aggregation Service funds the beacon output (ADR 042). The specification lists "Cost of enrollment" and "Cost per announcement per DID or Aggregation Participant" as cohort conditions that a service can set (Aggregate Beacons).

Next week's post covers these operational costs, and they are real. Aggregation changes a fee for each update into a shared operational load. At scale, that is a good trade. For one organization that anchors twice a year, it is a poor trade.

Two Ten-Year Models

A fee has an effect only when you multiply it by the number of updates, and many estimates are wrong about that number. A btcr2 DID with no updates has no on-chain cost. Creation needs no transaction, and an identifier that does not change puts nothing on-chain. The cost is proportional to change, not to existence.

Thus the important question is: how often does a DID change? For most identifiers, it changes rarely. We use annual key rotation as a baseline for good practice. Some DIDs need more updates, and most DIDs need fewer.

Model A: One Corporate DID, Annual Rotation

An organization anchors one corporate identity. It rotates its document control key once a year. It uses a Singleton Beacon and does not join a cohort.

In ten years, it publishes ten Beacon Signals, a total of 1,540 vB. A rotation needs only one update, because the old key can sign the update that replaces it (rotation post). If you use the add-then-remove pattern from that post, double the figures below.

This total counts only the signals. The transaction that funds the beacon also pays a fee, and so do later top-ups and consolidations. Add a small number of transactions of about the same size.

Sustained fee rateTen-year on-chain total
10 sat/vB15,400 sats
50 sat/vB77,000 sats
200 sat/vB308,000 sats

At a sustained 200 sat/vB for ten years, the total is 308,000 sats (0.00308 BTC). That rate is higher than any 365-day average in the mempool.space data. Whether 0.00308 BTC is a small or a large expense depends on the price of bitcoin when you spend it. This post does not make that assumption.

Model B: 10,000 Employee DIDs, Annual Rotation, Aggregated

An enterprise issues a DID to each employee and rotates each DID once a year. It uses aggregation with cohorts of 500.

That is 10,000 updates each year in 20 cohort transactions. In ten years, that is 200 transactions and 30,800 vB.

Sustained fee rateTen-year on-chain total
10 sat/vB308,000 sats
50 sat/vB1,540,000 sats
200 sat/vB6,160,000 sats

There are 100,000 updates in ten years. At a sustained 50 sat/vB, one annual key rotation costs about 15 sats in on-chain fees. At 10 sat/vB, it costs about 3 sats. At 200 sat/vB, it costs about 62 sats.

This model has three assumptions:

  • All participants sign in each round. If a round uses the k-of-n fallback leaf, its transaction is about 12,500 vB, not 154 vB.
  • Cohort membership does not change. A change of membership needs a new Beacon Address, and each member must add that address to its DID document with an update.
  • Each cohort has one funded UTXO at its Beacon Address. The operator funds it, and by default the change goes back to that address for the next round (beacon.ts).

The Costs That Dominate

Both models give the same result, and the result is the opposite of the usual objection.

At realistic update rates, on-chain fees are not the largest cost of a btcr2 deployment. In our experience, the costs below are usually larger, often by ten times or more.

Infrastructure. You need a node with an index, as the node post describes, and a second node for redundancy. The storage requirement increases each year. In our estimate, a redundant pair has a hardware cost in the low thousands of US dollars, plus a small cost each year.

Storage and retention. You must keep sidecar data, back it up, and test the restore process. You must do this for as long as your longest-lived credential needs it. The data is small, but the process has a cost, and the retention period is years.

Staff time. Someone integrates the resolver, selects the confirmation policy, sets up alerts, installs upgrades, and responds to failures. In our experience, this cost is larger than each other item in both models. This is true in the first year, and probably in each later year.

Aggregation operations. An Aggregation Service has liveness obligations to its cohort. If you operate one, it needs an on-call rotation.

Thus, for a budget discussion, "Bitcoin fees are cheap" is not the useful statement. The useful statement is this: an anchor in Bitcoin costs approximately what a small internal service costs. The on-chain fees are a small part of that cost. The real reason to hesitate about btcr2 is operational complexity, not transaction fees. That objection is more accurate, and it gives a more useful discussion.

The Beacon Wallet

The fee model assumes that the beacon can send a transaction when necessary. That is a problem of UTXO management.

Keep several spendable UTXOs. The reference implementation spends only a confirmed UTXO above 546 sats (beacon.ts). Thus a beacon with one UTXO must wait until its last transaction confirms, and during congestion that wait can be hours or days. Keep several independent UTXOs, so that an urgent signal does not wait behind an unconfirmed one.

Do not make dust. A change output near the dust limit can cost more to spend than it holds when fees increase. A P2TR input adds 57.5 vB to a transaction, so at 50 sat/vB that input costs about 2,900 sats. Make change large enough to stay economical at fee rates well above the current rates.

Consolidate when fees are low. Beacon wallets collect small change outputs. Combine them when fees are low, for example at 1-2 sat/vB, the usual daily median in 2026. Then a future signal does not need three inputs at 50 sat/vB.

Keep a reserve. A beacon with no funds cannot publish the emergency key removal that an incident needs. Keep a reserve for one signal at a very high fee rate. Monitor the balance as you monitor disk space.

When a Signal Does Not Confirm

If the fee is too low, your Beacon Signal stays in the mempool. There are two solutions, and the beacon type sets the cost of each.

RBF (replace-by-fee). Send the transaction again at a higher fee rate. Bitcoin Core 28.0 changed the default value of -mempoolfullrbf from 0 to 1. Bitcoin Core 29.0 removed the option, and its release notes call full replace-by-fee "the standard behavior" (29.0 release notes). Thus nodes at these versions usually accept a replacement, also if the original did not signal BIP 125 replaceability.

Bitcoin Core 31.0 changed the replacement rule. A replacement must make the fee-rate diagram of the mempool strictly better. For a transaction with no unconfirmed parents or children, a higher fee and a higher fee rate are sufficient. Check the behavior of your node and of your broadcast path. Do not assume it.

RBF has a special safety property for beacons. The update payload contains no transaction ID. The anchor is external, and the resolver derives the block height at resolution time. Thus a replacement with the same OP_RETURN payload changes the txid, but it changes nothing that an update commits to. The announcement stays the same, so you need no new sidecar data and no new signature on the update.

CPFP (child pays for parent). Spend the change output of the unconfirmed transaction at a high fee rate, so that a miner includes both transactions. The total cost is higher than the cost of an RBF, but sometimes CPFP is the only solution.

The important operational difference is this: for an aggregate beacon, one signer alone usually cannot do RBF or CPFP. An RBF through the MuSig2 key path needs a new MuSig2 session. All cohort participants must be online again to give new partial signatures. If the cohort is no longer available, a new session is possibly impossible.

CPFP also needs the cohort, and this fact surprises many people. A Beacon Signal spends from the Beacon Address. For an Aggregate Beacon, the RECOMMENDED example of the specification uses an n-of-n P2TR address with one key for each participant. In the reference implementation, the change goes back to that same address by default (beacon.ts). Participants sign with SIGHASH_DEFAULT, which commits to all outputs, so nobody can change the change address after the signatures exist. Under this default, the change output belongs to the cohort, so a child transaction needs cohort signatures.

The default is a policy, not a rule of the protocol. The reference implementation lets the funder of the cohort name a different change address. For an operator-funded cohort, that address is usually in the wallet that the operator uses to fund the cohort (ADR 044).

The reference implementation also has other paths, but the specification does not describe them. It builds the beacon output from the MuSig2 aggregate key and a script tree with two leaves (recovery-policy.ts):

  • A k-of-n fallback leaf. Any k members can spend it with separate signatures and no nonce exchange. This leaf changes which members must be online, but a round with k members is still necessary. The output commits to the leaf, so k members can use it to sign a replacement or a child. The cost is the larger witness from the section above.
  • A CSV recovery leaf. The operator can spend it alone after a relative timelock, 144 blocks by default. BIP 68 counts this delay from the confirmation of the output that the transaction spends. Thus the operator can sign a replacement of the unconfirmed signal alone if the beacon UTXO confirmed at least 144 blocks earlier. The operator cannot use this leaf for a child of the unconfirmed change output.

These two leaves also change who can sign a Beacon Signal without the full cohort. Next week's post explains that tradeoff.

The practical result: an Aggregation Service must set the correct fee before the MuSig2 session starts, because a later correction is difficult. Plan for the cohort to stay available until the transaction confirms, not only until the broadcast. A Singleton operator controls its beacon alone, so it can use RBF alone.

Fee Estimation

There are two workable strategies.

Estimate high and send once. Use the conservative mode of the Bitcoin Core RPC estimatesmartfee. This mode uses a longer time horizon and can return a higher fee rate. You can pay more than necessary, but you usually do not need to act after the broadcast. For a few signals each year, the extra cost is small in absolute terms.

Estimate low and plan to bump. Send near the bottom of the mempool, and increase the fee if the transaction does not confirm. Since Bitcoin Core 28.0, economical is the default mode of estimatesmartfee. The release notes say that this change is "expected to reduce over-estimation for many users, particularly if Replace-by-Fee is an option" (28.0 release notes).

This strategy costs less on average, but it needs a monitor and an automatic bump path. At volume, the work is worth it. For ten transactions in ten years, it is not.

Urgent signals are different. An example is the removal of a compromised key, as in the rotation post. For these signals, pay the fee that the signal needs. The goal is to make the period in which an attacker holds a valid key as short as possible. That goal is worth more than any realistic fee.

The reserve is for this case, so approve its use in advance. Then nobody must approve an unusual expense during an incident.

Conclusion

A P2TR Beacon Signal is 154 vB. Aggregation divides that size across the cohort. Each additional participant adds almost no on-chain cost, because MuSig2 makes one signature. One corporate DID with annual rotation costs 15,400 to 308,000 sats in ten years, at sustained rates of 10 to 200 sat/vB. Ten thousand aggregated employee DIDs cost about 3 sats for each rotation at 10 sat/vB, and about 62 sats at 200 sat/vB.

The fees are not the main problem. The node, the storage, the retention process, and the staff time are the costs that appear in a budget, so plan for them. If someone objects to a Bitcoin anchor because of cost, ask which cost they mean. At these update rates, the on-chain fees do not support the objection.

Next week: the operations of the aggregation that makes these numbers possible. The post covers what the Aggregation Service learns about you. It also covers what happens if a cohort member stops in the middle of a MuSig2 session.

Jintek LLC