Introduction
Every transaction on Radix pays a fee in XRD, and every manifest you write has to say where that XRD comes from. That is what the lock_fee call at the top of most manifests is doing. Two things about the Radix model differ from what you may expect coming from an EVM chain, and both change how you design a dApp.
First, the fee is not attached to the signer. XRD is held in vaults owned by components, so a fee is paid by whichever component locks it – which may be the user's Smart Account, your dApp's component, or both. Second, the total fee is not a single gas number: it is a network cost, an optional user tip, and any royalties the code you called charges, each with different destinations.
What Makes Up a Fee
The fee model prices each transaction in three parts, and the first of those is itself three separately-metered quantities:
- Network fee – the cost of running the transaction and of the state it leaves behind. It is the sum of an execution cost, a finalization cost and a storage cost. The first two are metered in cost units against a fee table; the third is charged per byte written to state and to archive.
- Tip – an optional percentage the submitter adds when demand exceeds capacity. It is charged on the execution and finalization costs only, not on storage or royalties, and goes straight to the validator proposing the round.
- Royalties – amounts set by a package publisher or component instantiator, charged whenever a transaction calls that code. Royalties are part of the fee the user pays, but they are not burnt or shared with validators; see Events, Metadata, and Royalties for how to configure them.
Because royalties are counted inside the fee, a transaction that touches an expensive component costs more than an identical transaction that does not – and the user sees the total before signing, in the wallet's transaction summary.
The Prices, and the Fiat Peg Behind Them
The prices are protocol constants, declared in radix-common/src/constants/transaction_execution.rs and assembled into a CostingParameters struct by the engine. Every figure below is checkable against any committed transaction's receipt.fee_summary through the Gateway API.
| Parameter | Value | What it controls |
EXECUTION_COST_UNIT_PRICE_IN_XRD | 0.00000005 XRD | Price of one execution cost unit |
FINALIZATION_COST_UNIT_PRICE_IN_XRD | 0.00000005 XRD | Price of one finalization cost unit |
STATE_STORAGE_PRICE_IN_XRD | 0.00009536743 XRD | Price of one byte of state storage |
ARCHIVE_STORAGE_PRICE_IN_XRD | 0.00009536743 XRD | Price of one byte of archive storage (payload, events, logs) |
EXECUTION_COST_UNIT_LIMIT | 100,000,000 | Ceiling on execution cost units in one transaction |
FINALIZATION_COST_UNIT_LIMIT | 50,000,000 | Ceiling on finalization cost units in one transaction |
EXECUTION_COST_UNIT_LOAN | 4,000,000 | Cost units advanced before the first lock_fee |
USD_PRICE_IN_XRD | 16.666… XRD | The fiat multiplier – the rate at which USD-denominated royalties convert to XRD |
Working the mainnet transaction above back through them: 7,286,902 execution cost units at 0.00000005 XRD is 0.3643451 XRD, 820,152 finalization cost units is 0.0410076 XRD, and 0.09574889972 XRD of storage is exactly 1,004 bytes at 0.00009536743 XRD each. The three constants are not documentation – they are what the ledger charged.
The last row is the one worth reading twice. USD_PRICE_IN_XRD is the "fiat value multiplier": it fixes what the protocol believes a dollar is worth in XRD, and at 16.666… it values 1 XRD at $0.06. That figure is not read from an oracle and does not track the market – it is a compiled-in constant, and CostingParameters::latest() in transaction_executor.rs still returns babylon_genesis(), so no protocol update since Babylon has moved it. XRD traded at about $0.00093 on 23 August 2026, roughly sixty-four times below the rate the fee model assumes.
For a developer that cuts two ways. Transaction costs are set in XRD and are therefore stable in XRD and cheap in fiat – the half-XRD transaction above cost about $0.0005. But anything the protocol prices in dollars is converted at $0.06 per XRD, so a royalty declared in USD, and the 166.666… XRD per-function royalty ceiling nominally described as $10, are worth far less than their labels suggest at today's price. Preview credit is generous for the same reason: PREVIEW_CREDIT_IN_XRD advances 1,000,000 XRD, commented in the source as $60,000.
Locking a Fee
A transaction pays from a fee reserve, which is established by calling lock_fee on a component that owns an XRD vault. In practice this is the first instruction in most manifests:
CALL_METHOD
Address("account_rdx...")
"lock_fee"
Decimal("5")
;The amount is a ceiling, not a charge. Whatever the transaction does not spend is returned to the vault it was locked from. Locking too little is the failure mode to guard against: if the reserve runs dry mid-execution the transaction fails, and the fees already consumed are not refunded.
Multiple Payers
More than one vault can lock a fee in the same transaction, and later locks are used preferentially. That is what makes fee sponsorship straightforward on Radix: a dApp component can lock part or all of the fee so the user does not need XRD to interact with it, and a profit-taking application can chip in a share of each trade. Nothing about this requires a meta-transaction relayer – it is a normal manifest instruction.
The Bootstrap Loan
The instructions that run before the first lock_fee still cost something. The network covers them with a small automatic loan of cost units, which must be repaid the moment the reserve is established. A transaction that burns through the loan without locking enough is rejected outright and leaves no ledger record. One that repays the loan and then fails is committed as failed: the state changes roll back, but the fees spent up to the failure are kept.
Where Fees Go
Spent fees are split by type, and the shares are protocol constants rather than a validator setting:
- Network fee – 25% goes to the validator that proposed the round and 25% to the validator set, shared at the end of the epoch in the same shape as network emissions. The remaining 50% is burnt. The two shares are
NETWORK_FEES_PROPOSER_SHARE_PERCENTAGEandNETWORK_FEES_VALIDATOR_SET_SHARE_PERCENTAGEin transaction_execution.rs, both set to 25, and the burn is whatever is left after them:to_burn_amount()subtracts both shares from the total rather than computing a share of its own. - Tips – paid immediately and entirely to the round proposer. The corresponding constants are
TIPS_PROPOSER_SHARE_PERCENTAGE = 100andTIPS_VALIDATOR_SET_SHARE_PERCENTAGE = 0, so a tip is never burnt and never shared. - Royalties – deposited into a system-generated vault owned by the component (or, for package royalties, by the package). The instantiator or deployer claims them with a badge the system creates automatically at instantiation or deployment. A single function's royalty is capped at
MAX_PER_FUNCTION_ROYALTY_IN_XRD, 166.666… XRD.
A live example. The Gateway returns this breakdown for any committed transaction under receipt.fee_destination; for mainnet transaction txid_rdx15gl7urc8kn36mjeq0hwru4mhn9t6uknkh7c7vsnw7tkh6t85zh9q6t3jzn at state version 553,951,096 (23 August 2026), against network fees of 0.50110159972 XRD:
| Destination | XRD | Share |
| Burnt | 0.25055079986 | 50% |
| Round proposer | 0.12527539993 | 25% |
| Validator set (epoch pool) | 0.12527539993 | 25% |
The burn is why fee revenue is deflationary for XRD supply, and the epoch pool is why validator income tracks participation rather than luck of the round.
Fee Tables and Fee Auctions
On Bitcoin the fee is a bid, as it was on Ethereum before its EIP-1559 fee reform. Each transaction names a price, the block producer includes the highest, and every included sender pays what it bid: a first-price auction. In a 2018 post on first- and second-price auctions, Ethereum co-founder Vitalik Buterin set out why neither standard format fits. A first-price auction offers no simple rule for choosing a bid, so a sender has to model everyone else’s bids to avoid overpaying. A uniform-price auction, in which every included sender pays the lowest included bid, lets senders bid what inclusion is worth to them, but the block producer can then add its own transactions to raise the clearing price, or collude with senders to raise their bids and refund them through another channel. His proposal was a minimum fee, burned and adjusted every block to keep blocks about half full, with the producer keeping only what a sender pays above it. EIP-1559 has that shape: a base fee that rises when blocks are more than half full and falls when they are less, always burned, plus a priority fee paid to the producer.
In the slides for a talk on transaction fee economics the same year, Buterin framed the fee as the price of an externality: each transaction imposes a cost on other nodes, present and future, that the producer who includes it does not bear. A protocol can charge for that cost directly, as a Pigouvian tax does, or cap it, as cap-and-trade does. Citing Martin Weitzman’s 1974 comparison of prices and quantities, he noted that the two are equivalent under perfect information, and that otherwise the better choice depends on whether the social cost or the private benefit rises faster. He treated storage separately: every future node must hold what a transaction writes, and he judged storage underpriced and proposed an ongoing fee per byte stored.
Later theory set a limit on what any auction rule can achieve. Hao Chung and Elaine Shi proved in Foundations of Transaction Fee Mechanism Design (SODA 2023) that when block space is finite, no non-trivial fee mechanism can both make truthful bidding each user’s best strategy and stop the block producer from gaining through a side deal with a single user: the only mechanism that meets both confirms nothing. Under a relaxed definition that charges a cheating party for the risk that its fake or inflated bid is confirmed in a later block, they built a mechanism that qualifies, the burning second-price auction, and showed that burning part of each payment, as EIP-1559 does, makes some incentive properties reachable that are otherwise impossible.
The Radix network fee is not a bid. It follows from what the transaction does, the cost units it consumes and the bytes it adds, priced at the constants listed above and in the documentation’s fee table, so in Weitzman’s terms the protocol sets the price directly rather than letting an auction find it. The one element a sender chooses is the tip, the counterpart of EIP-1559’s priority fee. Radix burns part of each network fee, as Buterin’s proposal did, but the burned amount follows the fixed table rather than adjusting with demand. Storage is charged once, for the bytes a transaction adds, with no ongoing fee of the kind the talk proposed.
Practical Guidance
- Lock generously. The unspent portion comes back, so a reserve that is too high costs nothing and a reserve that is too low burns fees for a failed transaction.
- Estimate before you submit. Preview the transaction through the Gateway API to get a fee estimate rather than guessing, especially for manifests whose cost varies with input size.
- Sponsor deliberately. If your component locks the fee, anyone who can call it can spend your XRD – gate the sponsoring method with a badge or a business rule, not just goodwill.
- Price royalties as user cost. A royalty is invisible in your own testing but appears in every user's fee summary.
Next Steps
- Radix Engine Toolkit – build and sign transactions from your own code, with no wallet in the loop
External Links
- How do Transaction Fees Work on Radix? – Radix Knowledge Base
- Using Royalties – Radix Documentation
- Transactions – Radix Documentation
- transaction_execution.rs – the costing constants in radixdlt-scrypto
- fee_summary.rs – how a spent fee is split between proposer, validator set and burn
- Transaction Costing – Radix Documentation
- First and second-price auctions and improved transaction-fee markets – Vitalik Buterin, ethresear.ch, 2018
- Transaction fee economics – Vitalik Buterin, keynote at TechCrunch’s Ethereum Meetup, Zug, 2018 (slides, archived)
- Foundations of Transaction Fee Mechanism Design – Hao Chung and Elaine Shi, SODA 2023
