Appearance
Fees and Compute Budget
Every transaction on Zink consumes compute resources and pays fees. Understanding the fee model helps you estimate costs, optimize programs, and ensure transactions land reliably during periods of network congestion.
Upstream-compatible
The fee model and compute budget system on Zink are structurally identical to Solana mainnet — same ComputeBudget instructions, same metering, same fee-payer mechanics.
Zink-specific
Fee parameters on Zink — including base fee amounts, compute unit pricing, and priority fee mechanics — are configured independently from Solana mainnet. Always query the current Zink cluster configuration for accurate values rather than assuming Solana mainnet defaults.
Fee components
A transaction's total fee is the sum of two parts:
| Component | Description |
|---|---|
| Base fee | A fixed fee per signature. On Solana mainnet this is 5,000 lamports per signature. Zink may configure a different value. |
| Prioritization fee | An optional fee based on compute units requested, used to bid for priority during congestion. |
The fee payer — the first signer on the transaction — pays the total fee. Fees are deducted before execution begins; if the fee payer lacks sufficient lamports, the transaction is rejected without executing.
Prioritization fees
Prioritization fees let you bid for higher scheduling priority when the network is congested. The fee is calculated as:
prioritization_fee = compute_unit_limit × compute_unit_price / 1_000_000Where:
compute_unit_limitis the maximum compute units your transaction declares (see below).compute_unit_priceis a per-compute-unit bid in micro-lamports (1 micro-lamport = 0.000001 lamports).
You set both values using instructions to the Compute Budget program (ComputeBudget111111111111111111111111111111):
rust
// In a client (using solana-sdk or @solana/web3.js)
ComputeBudgetInstruction::set_compute_unit_limit(300_000)
ComputeBudgetInstruction::set_compute_unit_price(1_000) // 1,000 micro-lamports per CUZink recommendation
During periods of heavy network activity, appropriate prioritization fees help ensure your transactions are processed promptly. Monitor the getRecentPrioritizationFees RPC method to calibrate your bids.
Compute units
The SVM meters program execution using compute units (CUs). Every operation — arithmetic, memory access, syscall, logging, CPI — costs a defined number of compute units. When a transaction exceeds its compute budget, the runtime aborts execution and the transaction fails (fees are still charged).
Default and maximum budgets
| Parameter | Value |
|---|---|
| Default CU limit per transaction (if not explicitly set) | 200,000 CU |
| Maximum CU limit per transaction | 1,400,000 CU |
| Maximum CU limit per instruction | 200,000 CU (default) |
| CPI depth limit | 4 levels |
| Stack frame size | 4 KiB |
| Call depth | 64 |
| Log message size limit | 10 KiB total per transaction |
Setting the compute budget
If your transaction needs more (or less) than the default 200,000 CU, set an explicit limit:
typescript
// TypeScript example
import { ComputeBudgetProgram } from "@solana/web3.js";
transaction.add(
ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 500 }),
);Best practice: Simulate your transaction first to measure actual CU consumption, then set the limit to ~20–30% above the observed value. Setting an unnecessarily high limit increases your prioritization fee (since the fee is based on the requested limit, not actual usage), while setting it too low causes transaction failure.
Compute unit costs of common operations
| Operation | Approximate CU cost |
|---|---|
| Simple arithmetic (add, mul) | 1 |
| SHA-256 hash (per 32 bytes) | ~100 |
| Ed25519 signature verify | ~25,000 |
| CPI invocation overhead | ~1,000 + target program CU |
| Account data read | ~100 per 10 KB |
sol_log (log a message) | ~100 |
| System Program: transfer | ~300 |
| Token Program: transfer | ~4,000 |
These are approximate and may change between runtime versions. Always simulate to get precise numbers.
Fee payer
The fee payer is the first signer in the transaction's account_keys array. Conventions:
- In most client-initiated transactions, the user's wallet is the fee payer.
- Relayer or gasless patterns can designate a different account as fee payer by placing it first in the signer list.
- The fee payer must hold enough lamports to cover the base fee + prioritization fee. If not, the transaction is rejected before execution.
Practical tips
Always set an explicit compute budget for non-trivial transactions. The 200,000 CU default is enough for simple transfers but not for complex program logic.
Simulate before submitting to estimate CU usage and catch errors without paying fees. See Transactions — Simulation.
Right-size your CU limit. An oversized limit wastes money on prioritization fees. An undersized limit causes failures.
Monitor priority fees dynamically. Use the
getRecentPrioritizationFeesRPC method to see what other transactions are bidding, and adjust yourcompute_unit_priceaccordingly.Budget for CPI. Cross-program invocations (CPI) consume compute units from the calling transaction's budget. A transaction with deep CPI chains needs a higher CU limit.