Reference · Reference
Fees and limits
Budget for the transaction's executed work as well as its signed envelope. The default executor charges a signature component, consumed compute and an optional priority fee. RPC's getFeeForMessage reports only signature plus priority fees, so it is not a complete execution-cost quotation.
All values below describe inspected source defaults. Consensus-affecting configuration must agree across validators; endpoint and proxy limits can impose additional restrictions. Use availability to identify the build being queried.
For exact simulation and receipt fields, use RPC contracts. To investigate a saved transaction's actual fee and outcome, follow Inspect a transaction. CLI input units are specified separately for the public and Rust utilities in the CLI reference.
Units and fee calculation
One SING is 1,000,000,000 lamports. A compute-unit price instruction uses micro-lamports per CU, with one million micro-lamports per lamport. Bridged-token amounts use that token's smallest unit, not necessarily nine decimals.
For an ordinary transaction under default TurboConfig:
signature fee = signature count × 5,000 lamports
execution fee = consumed CU × 1 lamport/CU
priority fee = ceil(billed CU limit × micro-lamports/CU ÷ 1,000,000)
total debit = signature fee + execution fee + priority feeThe priority component charges the requested/billed limit, not actual consumption. Signature and consumed-compute rates are executor configuration values; the defaults are not a fiat price guarantee. Source: default fee rates, fee calculation and failure reconstruction.
A canonical one-signature System transfer accounts for 450 CU. With no priority price, its default charge is 5,450 lamports, or 0.00000545 SING. The public CLI uses this fixed number in its balance precheck.
For another example, an instruction consuming 120,000 CU with an explicit 300,000 CU limit and a price of 1,000 micro-lamports/CU has:
5,000 + 120,000 + ceil(300,000 × 1,000 / 1,000,000)
= 125,300 lamportsThis is a source-derived calculation, not a measured transaction or fee reservation.
Registry-only housekeeping transactions are an exception in the current protocol-5 source: if every instruction targets the validator registry and at least one instruction exists, the transaction is fee-exempt. Adding a non-registry instruction, including compute-budget metadata, does not satisfy that exact predicate. Registration's associated account funding and mixed transactions still need funds.
What the fee RPC returns
getFeeForMessage takes a base64-encoded canonical message:
{"jsonrpc":"2.0","id":1,"method":"getFeeForMessage","params":["<base64 message>"]}It validates message decoding and compute-budget instructions. If the recent blockhash is expired and there is no valid durable nonce, the result contains value: null. Otherwise it returns context.slot and a lamport value calculated as required signatures × 5,000 plus priority fee.
It does not execute the message to determine consumed CU. For the transfer above it can quote 5,000 while the default executor debits 5,450. It also does not apply the registry-only executor exemption. This makes the RPC useful for its specific signature/priority components, but unsuitable as a universally exact debit estimate. See the handler.
Use simulation and the actual receipt to understand execution cost, while remembering that simulation neither reserves state nor guarantees later inclusion.
Execution failures can still cost money
The ordinary failure path discards application writes, then reconstructs the fee debit from pre-transaction state. For a canonical executed EVM revert, its nonce change may also survive. A failure before any compute is consumed returns no reconstructed fee. If the payer cannot fund the fee, the executor does not mint an unbacked debit; execution/replay bookkeeping can still record that work occurred.
Consequently, “atomic transaction” means application-state changes do not partly publish. It does not mean every failed attempt is free, or that computation and nonce effects rewind. The transaction lifecycle explains the stages at which rejection and executed failure differ.
Compute budgets
| Setting | Default or hard bound | Behavior |
|---|---|---|
| Per-instruction execution default | 1,400,000 CU | Multiplied by non-budget instruction count, then capped at transaction ceiling |
| Transaction execution ceiling | 1,400,000 CU | SVM_MAX_COMPUTE_UNIT_LIMIT can change it, up to 48,000,000 |
| Priority-fee default without explicit CU limit | 200,000 CU per non-budget instruction | Capped; intentionally distinct from the wider execution allowance |
| Explicit CU limit | Unsigned 32-bit request | Clamped to configured ceiling; used for both execution allowance and priority billing |
| Default priority price | 0 micro-lamports/CU | Optional unsigned 64-bit price |
| Block requested-compute budget | 250,000,000 CU | Mempool selection budgets requested limits, not observed execution |
| SBF heap | 32 KiB default, 256 KiB maximum | Request must be within range and a multiple of 1,024 bytes |
| Loaded account data | 64 MiB maximum | Zero request invalid; larger request capped |
Thus one instruction with a price but no explicit limit can execute up to the default 1.4 million CU while its priority fee is based on 200,000 CU. With a price of 1 micro-lamport/CU, that priority component rounds up to one lamport.
A large CU request affects block packing even if the transaction later uses little compute. A transaction deferred for the remaining block budget can become eligible in a later block; requesting the maximum for every instruction is not costless to scheduling.
Compute-budget instructions must have no account operands, valid exact wire data, and no duplicate instruction of the same budget kind. The deprecated discriminator zero is rejected. See budget constants, billing and sanitization, and block selection.
The two compute-limit environment overrides are resolved once. Invalid, empty or zero values fall back with warnings; values above the hard bound are clamped. Changing them can change whether execution succeeds, so it requires a coherent validator configuration, not an independent per-node tuning experiment.
Wire, account and service bounds
| Boundary | Source default/bound | Practical consequence |
|---|---|---|
| Submitted decoded transaction | 1 MiB | SVM_MAX_TX_BYTES overrides, capped at 4 MiB; shared by public admission paths |
| Canonical instruction account indices | One-byte indices | At most 256 addressable account keys |
| Account data allocation | 10 MiB maximum | A loader upload can require several transactions |
| HTTP request body | 2 MiB | Base64 and JSON overhead also count; raising the decoded cap alone does not enlarge HTTP |
| HTTP headers | 32 KiB | Oversized or incomplete headers rejected/timed out |
| JSON-RPC batch | 256 items by default | SVM_RPC_MAX_BATCH; zero falls back rather than making it unbounded |
getMultipleAccounts | 100 accounts | Split larger reads |
| WebSocket subscriptions | 256 per connection | Rejected beyond the per-connection bound |
| WebSocket connections | 8,192 default | Operator-configurable; block subscriptions disabled by default |
| HUWM message payload | 4,096 bytes | Application payload, distinct from header and transaction envelope |
| Withdrawal minimum | 1,000 token base units | Not 1,000 SING and not a universal minimum fiat value |
A cap is the maximum that a layer may accept, not a promise that every lower-size object succeeds. The upstream JavaScript instruction serializer has its own buffer constraints; the SDK's larger transaction serializer cannot bypass every upstream instruction-size limit. Likewise, a 2 MiB HTTP body may be narrowed by a front proxy. Source: transaction limits, HTTP transport, RPC batching, WebSocket policy.
The WASM source's declared memory constant is not itself an installed Wasmtime memory limiter. Do not import it into an operational limit table as an enforced cap; the WASM chapter describes the active construction.
Account funding and bridge fees
The rent sysvar computes an exemption minimum from the account's data size plus a 128-byte overhead, using defaults of 3,480 lamports per byte-year and a two-year threshold. That formula gives 890,880 lamports for zero data and 1,586,880 for 100 bytes. It defines the helper's funding calculation, not evidence that every program charges recurring rent. Use the target loader/program's checks and getMinimumBalanceForRentExemption when preparing account creation. See rent calculation.
The bridge withdrawal helper charges five basis points:
total fee = floor(gross base units × 5 / 10,000)
net = gross − total feeFor 1,000,000 token base units, net is 999,500 and the fee is 500. The helper divides that into relay and protocol portions; the withdrawal path currently consumes the net result while discarding those two split variables. Do not describe that accounting formula as proof that relayers and treasury accounts were actually paid. It also does not cover destination gas, exchange fees or another chain's protocol charges. See fee helper and withdrawal preparation.
The fee helper's “deposits are free” describes its bridge fee policy, not free foreign transactions or free local submission. For custody and settlement semantics, continue with asset bridging.
Validation scope and near-limit checks
Tests in the compute-budget module cover clamping, duplicate requests, priority rounding and the separate default billing limit. Mempool tests exercise requested-compute packing; RPC tests exercise expired-blockhash quotes and resource rejection. These source tests were inspected, not rebuilt for this documentation.
A good application acceptance check records requested CU, consumed CU, quoted components, actual receipt fee and error outcome for its representative transaction. It should test the relevant near-limit case, not assume that a successful small transfer validates an oversized upload or cross-VM workflow.
Compatibility and availability
Distinguish Singularity's implemented execution and interoperability contracts from installable packages, enabled node paths and dated public-service observations.
Glossary
Shared vocabulary for Singularity's execution environments, account state, consensus, HILSA evidence, settlement and client tooling.