← Back
DEVELOPMENT

Jito Bundles for Solana Swap Backends

Decide when a Solana swap backend should use a normal send, priority fees, or a Jito-style bundle handoff through Carbium's documented swap execution path.

Bundles are not magic. They are an execution tool for flows where the landing path matters as much as the transaction payload.

Use this page when you are building a swap backend, trading system, or execution service and need to decide whether a normal Solana send is enough, whether priority fees are the right lever, or whether the flow deserves a Jito-style bundle handoff.

Part of the Carbium Solana infrastructure stack.


The short version

Most Solana app transactions should still start with the normal path: build the transaction, sign it, send it through RPC, and confirm it. A bundle becomes useful when you care about execution ordering, all-or-nothing behavior, or reducing failed-landed outcomes in a competitive slot.

Execution path Use it when Avoid it when
Normal RPC send Standard user swaps, balance moves, dashboard actions, low-urgency app flows The transaction is part of a tightly coupled trading sequence
Priority-fee tuned send You need better landing probability for one normal transaction You expect multiple dependent transactions to succeed or fail together
Bundle handoff You already have a signed transaction and need MEV-aware or atomic-style execution handling Your quote is stale, unsigned, unvalidated, or missing a confirmation plan

A bundle does not repair a bad quote, expired blockhash, broken signer flow, or unsafe slippage setting. Fix those before changing the submission path.


What a Jito-style bundle changes

Jito's public documentation describes bundles as groups of up to five signed transactions that execute sequentially and atomically. That means the bundle is ordered, and if one transaction in the bundle fails, the whole bundle is rejected instead of partially committing.

That model matters for execution-sensitive systems because Solana blockspace is competitive. Bundles are sent to a block engine, compete through tip bidding, and may return a bundle identifier before the transactions have actually landed on-chain.

The important distinction is this:

Normal send Bundle-oriented send
Submits a signed transaction to an RPC node Submits signed transaction payloads into a block-engine path
A returned signature only means the RPC accepted the request A returned bundle id only means the bundle was received for processing
Confirmation still needs status polling Bundle or transaction status still needs follow-up tracking
Good default for ordinary app actions Useful for competitive, ordering-sensitive execution

Solana's own sendTransaction documentation makes the same operational point for normal RPC sends: a successful response does not guarantee the transaction was processed or confirmed. Bundle submission has the same practical requirement. You still need a status loop.


Where Carbium fits in the flow

Carbium's Swap API docs expose a narrow signed-transaction bundle handoff:

GET https://api.carbium.io/api/v1/swap/bundle

That endpoint is covered in Txn Bundle. It expects a base64-encoded signedTransaction and returns identifiers such as bundleId and txId when the request succeeds.

Use this page for the decision. Use Txn Bundle for the exact endpoint request.

flowchart TD
  A[Quote or build transaction] --> B[Validate amount, route, slippage]
  B --> C[Deserialize and sign]
  C --> D{Execution path}
  D --> E[Normal RPC send]
  D --> F[Bundle handoff]
  E --> G[Poll signature status]
  F --> H[Track bundleId and txId]
  H --> G

📘 The Carbium bundle handoff is not a signer and not a quote builder. It belongs after quote validation and signing, not before them.


When bundles are worth considering

Bundles are worth evaluating when the cost of a bad landing outcome is higher than the extra execution complexity.

Good candidates:

  • arbitrage or routing systems where ordering changes the trade outcome
  • backend swap systems that already build and sign transactions server-side or through a controlled signer boundary
  • flows where a transaction should not partially succeed without the surrounding execution context
  • advanced routes where the team can reason about tips, priority fees, blockhash freshness, and confirmation behavior

Weak candidates:

  • first-time integration tests
  • ordinary frontend swaps where the user mainly needs a clear quote and confirmation state
  • transactions that have not been simulated or validated before signing
  • stale transactions being resubmitted because the app does not yet handle blockhash expiry correctly

If the problem is a stale blockhash, use the Blockhash Expiry Recovery Playbook. If the problem is transaction signing, use Executing Swaps. If the problem is request shape or route failure before signing, use Swap API Errors Reference.


A practical decision order

Do not start by asking, "Should this be bundled?" Start by proving the transaction is good enough to deserve a more specialized landing path.

  1. Get a fresh quote or transaction payload.
  2. Check route, output amount, minimum output, slippage, and user intent.
  3. Confirm the blockhash is still fresh enough for the send path.
  4. Sign with the wallet, backend signer, or custody flow that owns the transaction.
  5. Choose normal RPC send or bundle handoff.
  6. Track the returned signature, bundleId, or txId until the outcome is known.

This order keeps bundle usage as an execution choice instead of a debugging shortcut.


Minimal Carbium bundle handoff

Once your app has a fully signed base64 transaction, the documented Carbium bundle request looks like this:

curl --request GET 'https://api.carbium.io/api/v1/swap/bundle' \
  --get \
  --data-urlencode "signedTransaction=$SIGNED_TRANSACTION_BASE64" \
  --header "X-API-KEY: $CARBIUM_API_KEY" \
  --header "accept: application/json"

The important detail is not the curl command. It is the state of the payload before this request runs.

Before calling the bundle endpoint Why it matters
Transaction is already signed The bundle endpoint submits; it does not sign
Quote and route still match user intent Bundling a bad route only lands a bad decision more deliberately
Blockhash freshness is understood Expired transactions can still fail on the landing path
App can store bundleId and txId Operators need identifiers to debug and reconcile outcomes
Confirmation tracking exists Accepted-for-processing is not the same as finalized

Common mistakes

Mistake Why it hurts Better pattern
Using bundles before the normal send flow works You add execution complexity before the baseline is proven Make one normal signed send work first
Treating bundleId as final confirmation Receipt is not the same as landed execution Track signature or bundle status until the outcome is known
Bundling stale transactions Atomic handling does not refresh a blockhash Rebuild or refresh the transaction before submission
Using bundle submission to hide bad slippage policy Execution tooling does not fix product-level trade risk Validate output amount and slippage before signing
Reusing the same path for every user action Not every transaction needs a specialized execution route Reserve bundles for flows with ordering or landing sensitivity

🔶 For most teams, the right path is: get Q1 working, make normal execution reliable, then add the bundle handoff only for flows where landing behavior changes the business outcome. Start platform access at carbium.io, then use Txn Bundle for the exact Carbium request shape.