> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Priority fees and compute budget

> Right-sizing compute-unit limits and priority fees for Raydium transactions — benchmarks per instruction, estimation strategies, and congestion-handling patterns.

<Info>
  Every Solana transaction sets (implicitly or explicitly) two parameters: a **compute unit limit** (max CUs the tx may consume; default 200,000 × number of instructions up to a per-tx cap) and a **priority fee** in micro-lamports per CU. Under-sizing either kills transactions — too-low CU limits cause `ProgramFailedToComplete`; too-low priority fees cause the tx to sit unconfirmed until expiry.
</Info>

## The two settings

```ts theme={null}
import { ComputeBudgetProgram } from "@solana/web3.js";

const tx = new Transaction()
  .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 250_000 }))
  .add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 50_000 }))
  .add(yourRaydiumSwapIx);
```

* `setComputeUnitLimit(units)` — caps compute; the transaction pays for at most `units` CUs.
* `setComputeUnitPrice(microLamports)` — priority fee bid, in micro-lamports per CU. Total priority fee = `units × microLamports × 1e-6` lamports.

Cost math: a 250k CU limit at 50k micro-lamports/CU bids `250_000 × 50_000 / 1e6 = 12,500` lamports ≈ 0.0000125 SOL ≈ \$0.003 at \$200 SOL. Priority fees at this scale are noise for most user swaps but material for bots doing 1000 txs/day.

## CU benchmarks per instruction

Benchmarks from mainnet execution logs, averaged across recent runs. Numbers are approximate (±15%); re-measure for your specific flows.

| Instruction                      | SPL Token       | Token-2022 (simple) | Token-2022 (transfer fee) |
| -------------------------------- | --------------- | ------------------- | ------------------------- |
| CPMM initialize\_pool            | 180,000         | 200,000             | —                         |
| CPMM swap\_base\_input           | 140,000         | 180,000             | 200,000                   |
| CPMM swap\_base\_output          | 150,000         | 185,000             | 205,000                   |
| CPMM deposit                     | 130,000         | 160,000             | 180,000                   |
| CPMM withdraw                    | 120,000         | 150,000             | 170,000                   |
| CLMM create\_pool                | 70,000          | 85,000              | —                         |
| CLMM open\_position\_v2          | 120,000         | 140,000             | 160,000                   |
| CLMM increase\_liquidity\_v2     | 150,000         | 175,000             | 195,000                   |
| CLMM decrease\_liquidity\_v2     | 140,000         | 165,000             | 185,000                   |
| CLMM swap\_v2 (0 tick crossings) | 170,000         | 205,000             | 225,000                   |
| CLMM swap\_v2 (1 tick crossing)  | 220,000         | 255,000             | 275,000                   |
| CLMM swap\_v2 (3 tick crossings) | 320,000         | 355,000             | 375,000                   |
| CLMM collect\_fee                | 80,000          | 95,000              | 105,000                   |
| AMM v4 swap\_base\_in            | 140,000         | —                   | —                         |
| AMM v4 deposit                   | 120,000         | —                   | —                         |
| AMM v4 withdraw                  | 110,000         | —                   | —                         |
| Farm v6 create\_farm             | 70,000          | 85,000              | —                         |
| Farm v6 deposit (1 reward slot)  | 130,000         | 155,000             | 175,000                   |
| Farm v6 deposit (3 reward slots) | 220,000         | 255,000             | 275,000                   |
| Farm v6 withdraw                 | matches deposit |                     |                           |
| Farm v6 harvest                  | matches deposit |                     |                           |
| Farm v3/v5 deposit               | 100,000         | —                   | —                         |
| LaunchLab initialize             | 100,000         | —                   | —                         |
| LaunchLab buy\_exact\_in         | 140,000         | —                   | —                         |
| LaunchLab graduate               | 250,000         | —                   | —                         |

The "tick crossings" row for CLMM is the biggest CU variable. If you don't know how many ticks the swap will cross, budget for the worst case — 8 crossings is the hard cap (the program loads at most 8 tick arrays).

### Composed transactions

Sum the individual budgets and add:

* **+1,500 CU per CPI frame** — the runtime's fixed overhead for each cross-program call.
* **+20,000 CU per ATA creation** — `create_associated_token_account` is not free.
* **+5,000 CU for `setComputeUnitLimit` / `setComputeUnitPrice`** each.

Example: a user swap that creates the output ATA and wraps native SOL:

```
wrap_sol (create_ata + system transfer + sync_native)   ≈ 30,000
CPMM swap_base_input (SPL)                              ≈ 140,000
close_account (unwrap)                                  ≈ 5,000
ComputeBudget instructions                              ≈ 10,000
────────────────────────────────────────────────────────
Total                                                   ≈ 185,000 → budget 250,000
```

Padding: set the CU limit \~25% above the expected usage. Under-estimating costs the whole tx; over-estimating just raises priority-fee cost proportionally (priority fee is `units × microLamports`, so \~25% over-budget costs 25% extra in priority fee).

## Priority-fee estimation

Solana's local fee market means priority fees are **per-writable-account**. A tx that writes to a hot account (popular pool state) pays more than a tx that writes to a cold account. The global fee level is not the right metric for Raydium swaps; you want fees on the specific pools you're touching.

### Strategy 1: RPC provider estimator

Each major RPC provider publishes a priority-fee estimator that queries recent fees on specific accounts:

```ts theme={null}
// Helius
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${apiKey}`, {
  method: "POST",
  body: JSON.stringify({
    jsonrpc: "2.0",
    id:      "fee-estimate",
    method:  "getPriorityFeeEstimate",
    params: [{
      accountKeys: [poolStatePubkey.toBase58()],
      options:     { priorityLevel: "High" },
    }],
  }),
});
const { result } = await response.json();
const microLamports = result.priorityFeeEstimate;
```

Priority levels across most providers: `Min` / `Low` / `Medium` / `High` / `VeryHigh` / `UnsafeMax`. Map them to percentiles:

| Level    | Percentile | Use case                           |
| -------- | ---------- | ---------------------------------- |
| Min      | 25th       | Background, non-urgent bot traffic |
| Low      | 50th       | Normal user swaps                  |
| Medium   | 60th       | Default for wallet UIs             |
| High     | 75th       | Time-sensitive arbitrage           |
| VeryHigh | 95th       | Liquidations, last-chance exits    |

Providers: Helius (`getPriorityFeeEstimate`), Triton (`getRecentPrioritizationFees` with account list), QuickNode (similar).

### Strategy 2: Direct RPC query

Use the standard `getRecentPrioritizationFees` RPC:

```ts theme={null}
const fees = await connection.getRecentPrioritizationFees({
  lockedWritableAccounts: [poolStatePubkey],
});

// fees: Array<{ slot, prioritizationFee }>
// Recent N slots; default ~150 slots.

const median = percentile(fees.map(f => f.prioritizationFee), 0.5);
```

This is the vanilla Solana RPC method; works with any provider. Downside: the sample is small (150 slots ≈ 60 seconds) and noisy. For smoother estimates, use a provider's aggregation.

### Strategy 3: Historical self-tuning

For bots running constant flow, track your own landed vs. expired rates:

```
per-pool target: 80% land rate at <30s
if current_land_rate < 80%: priorityFee += 10%
if current_land_rate > 95%: priorityFee -= 5%
```

This self-corrects faster than public estimators and captures per-pool structure the public estimators don't always see.

## Handling CU-exhaustion failures

Symptom: tx fails with `exceeded maximum number of instructions allowed (200000)` or `ProgramFailedToComplete`.

Diagnosis:

```bash theme={null}
solana confirm <tx-sig> -v
# Look for "consumed N of M compute units" and which instruction exhausted.
```

Fixes:

1. **Raise the CU limit.** If your tx was using 195k of a 200k budget, bump to 300k.
2. **Split the transaction.** If you're hitting the 1.4M per-tx cap, break into two txs. Farm `harvest then stake` is a classic one to split when rewards are many.
3. **Trim accounts.** Each additional writable account adds \~2,000 CU. Pruning unused accounts helps on marginal cases.
4. **Use lookup tables.** LUT lookups are \~50 CU per resolved address, saving the 5,000 CU of a full account reference per entry.

## Handling stuck transactions

Symptom: tx submitted, never confirms, eventually expires with `BlockhashNotFound`.

Diagnosis:

* `getSignatureStatuses([sig])` returns `null` → leader never saw it.
* Returns `{ confirmationStatus: null }` → leader saw it but didn't include.

Fixes:

1. **Raise priority fee.** Re-submit with 2× the current fee.
2. **Rebuild with fresh blockhash.** Blockhash lifetime is \~60 seconds; beyond that the tx is invalid regardless of fees.
3. **Multi-RPC broadcast.** Some RPCs have better leader connectivity than others. Submit to 3–5 in parallel.
4. **Switch to Jito bundles.** See [`integration-guides/routing-and-mev`](/integration-guides/routing-and-mev). Bundles bypass public packet queues.

Retry logic skeleton:

```ts theme={null}
async function submitWithRetry(buildTx, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const tx = await buildTx({
      priorityFee: basePriorityFee * Math.pow(1.5, attempt),
      blockhash:   (await connection.getLatestBlockhash()).blockhash,
    });

    try {
      const sig = await connection.sendRawTransaction(tx.serialize(), {
        skipPreflight: attempt > 0,  // skip after first try to save latency
      });

      const result = await connection.confirmTransaction(sig, "confirmed");
      if (result.value.err) {
        // Logic error; don't retry.
        throw result.value.err;
      }
      return sig;

    } catch (e) {
      if (isExpiredError(e)) continue;  // retry
      if (isRevertError(e)) throw e;    // don't retry; deterministic failure
      throw e;
    }
  }
  throw new Error("submit: exhausted retries");
}
```

## Under congestion

When the network is congested (Jupiter / Jito bundle dashboards show backlog, RPC latency spikes, tx expiry rates climb), adjust:

| Parameter                  | Normal conditions   | Congested conditions            |
| -------------------------- | ------------------- | ------------------------------- |
| CU limit                   | +25% above estimate | +25% above estimate (unchanged) |
| Priority fee percentile    | 50th                | 75th–95th                       |
| Retry count                | 3                   | 5–7                             |
| Retry backoff              | 500ms               | 1000ms                          |
| Use Jito bundles           | Optional            | Strongly recommended            |
| Blockhash refresh on retry | Yes                 | Yes, mandatory                  |

Watching congestion signals:

* Priority-fee 75th percentile > 500k micro-lamports: congestion.
* Jito 50th percentile tip > 0.001 SOL: congestion.
* RPC response p99 > 2s: RPC-specific issue or congestion.

## Fee budgeting for bots

A trading bot running \~1000 txs/day needs a priority-fee budget. Back-of-envelope:

```
Average CU per tx:          ~250,000
50th percentile fee:        ~20,000 micro-lamports/CU
Cost per tx:                250_000 × 20_000 × 1e-6 = 5_000 lamports = 5e-6 SOL
Daily cost (1000 tx):       5e-3 SOL ≈ $1 @ $200 SOL
Monthly cost:               ~$30
```

That's the minimum. During congestion, multiply by 5–10×. Plan for \~\$150–300/month in priority fees for a steady-flow bot.

Bots that must land in specific slots (liquidations, arb) pay 95th percentile continuously and spend \~10× more. Jito bundle tips dominate at that scale — often \$1000+/month — but the alternative (being front-run or expiring) is worse.

## Pitfalls

### 1. Forgetting the CU limit

Default is 200k CUs × (instructions in tx). A single-instruction swap defaults to 200k; that's enough for CPMM on SPL Token but not CLMM with tick crossings or anything Token-2022. Always set it explicitly.

### 2. Priority fee on the wrong account

If you estimate priority fee against the token mint but the hot account is the pool state, your estimate is too low. The pool state is the right writable-account to target for Raydium.

### 3. Fees scale with CU limit

`total_priority_fee = units × microLamports`. Raising `units` from 200k to 1M at 50k micro-lamports/CU multiplies priority fee 5×. Don't over-budget CU just in case; measure.

### 4. Default tx version

Legacy transactions have lower account limits; V0 transactions with address lookup tables unlock larger routes. The SDK uses V0 by default in `txVersion: TxVersion.V0`. Don't drop to legacy unless you need wallet compatibility.

### 5. `skipPreflight` hides CU errors

`skipPreflight: true` sends the tx without local simulation. You save \~100ms but lose the early feedback on CU exhaustion. Use it only on retries, not on the first attempt.

## Pointers

* [`integration-guides/routing-and-mev`](/integration-guides/routing-and-mev) — Jito bundle strategies.
* [`integration-guides/aggregator`](/integration-guides/aggregator) — transaction assembly.
* [`integration-guides/cpi-integration`](/integration-guides/cpi-integration) — CU stacking across composed CPIs.
* [Solana compute budget program docs](https://docs.solana.com/developing/programming-model/runtime#compute-budget)

Sources:

* [Solana `getRecentPrioritizationFees` RPC](https://docs.solana.com/api/http#getrecentprioritizationfees)
* [Helius priority fee API](https://docs.helius.dev/solana-apis/priority-fee-api)
* Benchmarks: mainnet execution logs (Raydium SDK integration tests, April 2026).
