How do I set priority fees on Solana (compute unit limit + compute unit price) for reliability during congestion?
Layer-1 Blockchain Networks

How do I set priority fees on Solana (compute unit limit + compute unit price) for reliability during congestion?

7 min read

Quick Answer: On Solana, you set “priority fees” by attaching a ComputeBudgetInstruction that specifies (1) a compute unit limit for your transaction and (2) a compute-unit price (in microlamports per CU). During congestion, validators prioritize transactions offering higher total fees (limit × price) per unit of compute, so sizing both parameters correctly is what gets your transactions through.

Why This Matters

If you’re running payouts, trading, or any workflow that can’t stall when the network is busy, relying on default fees is a risk. Solana doesn’t use a simple “gas price” model; it uses compute budgets and local fee markets to price contention. You get reliability during congestion by explicitly telling the network:

  • how much compute you’re willing to consume, and
  • how much you’re willing to pay per unit of compute.

Done right, your critical flows keep confirming in ~400ms even when everything else feels slow. Done badly, you either overpay, hit compute-limit failures, or get deprioritized behind better-priced flows.

Key Benefits:

  • Predictable confirmation under load: Proper priority fees keep core payment and trading flows moving when the network is congested.
  • Cost control at the byte/compute level: Tuning compute limits and prices lets you pay for exactly the resources you need, instead of blindly overpaying.
  • Separation of “fast path” vs. “best effort”: You can treat critical transactions (payouts, treasury moves) differently from background flows by using different fee profiles.

Core Concepts & Key Points

ConceptDefinitionWhy it's important
Compute units (CUs)A metering unit for how much work a transaction does. Every instruction consumes a certain number of CUs up to a per-tx limit.Your transaction can fail or be throttled if it runs out of compute, even with a high fee. You must set a realistic CU limit.
Compute-unit limitThe maximum number of compute units you allow this transaction to use, set via set_compute_unit_limit.This caps your cost and tells the runtime how much capacity to budget, but setting it too low leads to ComputationalBudgetExceeded.
Compute-unit price (priority fee)An extra fee set via set_compute_unit_price, in units of 0.000001 lamports (microlamports) per CU. Total extra fee = limit × price.Validators prioritize higher effective fees per CU. This is your main lever to gain priority during congestion.

How It Works (Step-by-Step)

On Solana, “priority fees” are implemented via the Compute Budget program. You add special instructions to your transaction before your core business logic:

  • ComputeBudgetInstruction::set_compute_unit_limit(u32 limit)
  • ComputeBudgetInstruction::set_compute_unit_price(u64 price)

The prioritization fee is calculated as:

prioritization fee (lamports) = requested max CUs × CU price (microlamports) ÷ 1,000,000

Example: limit = 200,000 CUs, price = 10 microlamports/CU
→ Fee = 200,000 × 10 / 1,000,000 = 2,000,000 / 1,000,000 = 2 lamports.

  1. Estimate your transaction’s compute usage

    Before you can set a sensible limit and price, you need a rough CU profile:

    • Run the transaction on devnet with --compute-unit-limit bumped high (e.g., 1,000,000) and inspect logs.
    • Use local tooling or program logs to observe consumed compute; many frameworks (e.g., Anchor) can surface CU usage.
    • Add a safety margin (e.g., 20–50%) on top of peak usage to account for variance in downstream CPIs.

    Rule of thumb:

    • Simple transfers & memos: tens of thousands of CUs.
    • Complex DeFi swaps / multi-leg CPIs: hundreds of thousands of CUs+.
  2. Set a compute-unit limit with a safety buffer

    Once you have a baseline, set the limit via the compute budget instruction:

    import {
      ComputeBudgetProgram,
      Transaction,
    } from '@solana/web3.js';
    
    const transaction = new Transaction().add(
      // 1) Set CU limit
      ComputeBudgetProgram.setComputeUnitLimit({
        // Example: baseline ~120k CUs + 40% buffer
        units: 170_000,
      }),
      // 2) Your actual business instructions go here...
    );
    

    Design principles:

    • Avoid under-provisioning: If you’re hitting ComputationalBudgetExceeded, raise the limit. A higher cap doesn’t mean you always pay more; you pay for the CUs actually used, but priority is based on the cap.
    • Avoid huge arbitrary limits: 1M+ CUs “just in case” for simple flows can push priority fees higher than needed if you price per CU aggressively. Size per route type (e.g., simple transfer vs multi-hop swap).
  3. Attach a priority fee via compute-unit price

    Next, set the price you’re willing to pay per CU. This is your congestion lever:

    transaction.add(
      ComputeBudgetProgram.setComputeUnitPrice({
        // 10 microlamports = 0.000010 lamports per CU
        // Total fee = limit * 10 / 1_000_000
        microLamports: 10n,
      }),
    );
    

    A practical pattern is to define fee profiles in your backend:

    • Low priority (best-effort): price = 0–2 microlamports/CU
    • Normal: price = 3–10 microlamports/CU
    • High priority (during congestion): price = 11–50+ microlamports/CU

    You can then:

    • Dynamically adjust the profile by route type (e.g., merchant payouts vs. “check balance”).
    • Increase microLamports in response to elevated retry counts or rising confirmation latencies.

    Validators multiply your requested max CUs by the CU price and use this to compare the economic value of competing transactions in the local fee market. During congestion, transactions with more priority fee per unit of compute tend to land first.

Common Mistakes to Avoid

  • Underestimating compute and overpaying on price:
    Setting a very high microLamports but too low a CU limit means your transaction can still fail with ComputationalBudgetExceeded. Fix compute sizing first; then tune pricing.

  • Relying on a single static priority configuration for all traffic:
    Using one limit and one price for everything forces you to either overpay for low-value flows or underpay for critical ones. Segment your flows (e.g., KYC updates vs. treasury sweeps) and give each a different compute/price profile.

Real-World Example

Imagine you’re running a USDC payout service on Solana. You batch payouts and send them as multi-recipient transactions with memos for reconciliation. Under normal conditions, your devnet profiling shows each payout batch uses ~150,000 CUs. You set:

  • CU limit: 200,000 (150k baseline + ~33% buffer)
  • CU price: 5 microlamports/CU for standard payouts

Normal days, everything confirms in a couple of slots and your fee per batch is:

  • 200,000 × 5 / 1,000,000 = 1 lamport of priority fee (plus base fee)

During a market event, you see:

  • Confirmation times creeping up.
  • A growing backlog of pending payouts.

Your backend detects the rising average confirmation over the last N slots and automatically moves payouts into a “high priority” profile:

  • CU limit: unchanged at 200,000
  • CU price: raised to 25 microlamports/CU

Now each batch carries a much stronger economic signal:

  • 200,000 × 25 / 1,000,000 = 5 lamports

This higher fee per CU moves your payouts ahead of background traffic in the local fee market, keeping your SLA for merchants intact, while your low-urgency tasks (like refreshing on-chain analytics) stay on the cheaper profile and can lag without business impact.

Pro Tip: Treat priority fees like SLOs, not guesses. Monitor transaction failure reasons, compute usage, and confirmation latency per route. When you see ComputationalBudgetExceeded, raise CU limits; when you see slow confirmations but no compute errors, raise CU price just for the affected flow, not globally.

Summary

Priority fees on Solana are about buying reliable compute during congestion, not blindly bidding on “gas.” You set them by:

  • Sizing your compute-unit limit to match real program usage with a safety margin.
  • Setting a compute-unit price in microlamports per CU, which becomes your prioritization fee when multiplied by the limit.

By profiling compute, segmenting flows into different fee profiles, and dynamically adjusting CU price under load, you can keep mission-critical payments, trading, and treasury transactions confirming fast even when the network is busy—without overspending on every transaction.

Next Step

Get Started