Most Solana trading bots lose not because of the algorithm, but because their transactions end up at the back of the queue. An incorrectly calculated priority fee negates the advantage of a fast network. Solana processes theoretically 65,000 TPS with ~400 ms finalization, but without fine-tuning compute units and fees, you fall behind competitors. Often clients come with a ready algorithm, but their transactions hang for minutes, or they overpay 0.2 SOL per trade using inflated limits. We solve this by dynamically selecting fees based on percentiles, saving up to 30% of the budget. Over the years, our engineers have delivered over 30 Solana DeFi projects, with average bot latency of 30 ms.
How Solana Transaction Model Works and Differs from EVM
In Ethereum, gas price determines priority. In Solana, priority depends on a combination of compute units (CU) and priority fee. Compute units are analogous to gas, the computational resource limit per transaction (max 1.4M CU). Priority fee is an additional payment in lamports per compute unit. Proper configuration of these parameters is the key to fast order execution.
According to Solana Foundation, average finalization is ~400 ms. However, without our fine-tuning, you won't achieve this metric.
Essential instructions for a competitive bot:
import { ComputeBudgetProgram } from "@solana/web3.js";
// Set CU limit (important: not more than needed)
const setComputeLimit = ComputeBudgetProgram.setComputeUnitLimit({
units: 200_000, // typically 100k-200k for a swap
});
// Set priority fee
const setPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 100_000, // 0.1 lamport per CU = 0.02 SOL on 200k CU
});
transaction.add(setComputeLimit, setPriorityFee, ...swapInstructions);
If the CU limit is calculated incorrectly too low, the transaction fails with exceeded compute budget. Too high — overpayment and reduced priority (validators optimize throughput by fee/CU ratio). We use dynamic priority fee calculation via RPC method getRecentPrioritizationFees, selecting the 75-90 percentile for maximum priority. Typical fee savings with this approach is up to 30% compared to a fixed rate.
How to configure priority fee correctly? (Steps)
- Get current fees via
getRecentPrioritizationFees. - Select target percentile (e.g., 90th).
- Set
microLamportsinComputeBudgetProgram.setComputeUnitPrice. - Add the instruction to the transaction before other operations.
Jupiter: Route Aggregation
Jupiter is the standard liquidity aggregator on Solana, combining Raydium, Orca, Meteora, and over 20 other DEX/AMMs. API v6 is the latest.
Quote API
const quote = await fetch(`https://quote-api.jup.ag/v6/quote?` + new URLSearchParams({
inputMint: "So11111111111111111111111111111111111111112", // SOL
outputMint: USDC_MINT,
amount: "1000000000", // 1 SOL in lamports
slippageBps: "50", // 0.5%
onlyDirectRoutes: "false",
maxAccounts: "64", // transaction account limit
}));
const quoteData = await quote.json();
The parameter maxAccounts: 64 is critical: a Solana transaction can contain no more than 64 unique accounts. A complex route through multiple protocols risks exceeding the limit, causing TooManyAccounts error. We automatically select a route that fits within this constraint, sacrificing optimality but guaranteeing execution.
Swap execution
const swapResponse = await fetch("https://quote-api.jup.ag/v6/swap", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
quoteResponse: quoteData,
userPublicKey: wallet.publicKey.toString(),
wrapAndUnwrapSol: true,
dynamicComputeUnitLimit: true,
prioritizationFeeLamports: "auto",
}),
});
const { swapTransaction } = await swapResponse.json();
const tx = VersionedTransaction.deserialize(Buffer.from(swapTransaction, "base64"));
tx.sign([wallet]);
const txid = await connection.sendRawTransaction(tx.serialize(), {
skipPreflight: false,
maxRetries: 3,
});
In production, we recommend enabling dynamicComputeUnitLimit — Jupiter simulates the transaction and sets the optimal CU limit itself.
Raydium: Direct Integration
For latency-sensitive operations, direct integration with Raydium CLMM (Concentrated Liquidity Market Maker) is faster than via Jupiter. We use SDK v2:
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import { PublicKey } from "@solana/web3.js";
const raydium = await Raydium.load({
owner: wallet,
connection,
disableFeatureCheck: true,
});
const poolInfo = await raydium.clmm.getPoolInfoFromRpc(POOL_ID);
const { transaction } = await raydium.clmm.swap({
poolInfo,
ownerInfo: { useSOLBalance: true },
inputMint: new PublicKey(INPUT_MINT),
amountIn: new BN(amount),
amountOutMin: new BN(minAmountOut),
observationId: poolInfo.observationId,
txVersion: TxVersion.V0,
});
Versioned Transactions (V0) with Address Lookup Tables are mandatory for complex multi-hop swaps. They allow including more accounts via ALT compression.
What are Versioned Transactions?
Versioned Transactions are a new Solana transaction format introduced in 2022. Unlike the legacy format, they support Address Lookup Tables (ALT) — pre-loaded account lists. This reduces transaction size and bypasses the 64-account limit. Our bots use V0 for complex routes.How to Reduce Latency to Milliseconds
For a competitive bot, latency is measured in milliseconds, not seconds. Here are three key methods:
- Jito bundling. Jito is the MEV infrastructure on Solana. A bundle of transactions is sent directly to the Jito block engine, bypassing standard gossip. This ensures atomic execution and the first slot in the block. Minimum tip is 0.001 SOL, realistically 0.01-0.1 SOL in competitive conditions.
import { searcherClient } from "jito-ts/dist/sdk/block-engine/searcher";
const client = searcherClient(JITO_BLOCK_ENGINE_URL, keypair);
const bundle = new Bundle([tx1, tx2], 5);
await client.sendBundle(bundle);
-
Geyser plugin / Yellowstone. For real-time on-chain data monitoring, we use Geyser gRPC (Yellowstone). Latency 5-20 ms vs 200-500 ms with standard RPC polling.
-
Geographic placement. Solana validator servers are concentrated in specific data centers. Placing your bot nearby (Amsterdam, Frankfurt, Ashburn) reduces network latency by 10-50 ms.
Monitoring and Risk Management
We build transaction tracking via WebSocket subscription — faster than polling. Statuses: processed → confirmed → finalized. On BlockhashNotFound error, automatically fetch a new blockhash and retry. On SlippageToleranceExceeded, recalculate quote with current liquidity. Capital is distributed across separate keypairs per strategy; long-term funds stored on hardware wallet or KMS.
Approach Comparison: Jupiter API vs Direct Integration
| Parameter | Jupiter API | Direct Integration (Raydium SDK) |
|---|---|---|
| Route optimality | High (20+ DEX) | Lower (single protocol) |
| Quote latency | ~100-200ms | ~20-50ms (on-chain) |
| Maintenance | Minimal | SDK updates |
| Complexity | Low | High |
| Customization | Limited | Full |
For most bots, Jupiter API is the right choice: best prices, less code. Direct Raydium integration only when sub-50ms latency or specific pool interaction (LP management, concentrated liquidity range orders) is needed.
What's Included in Turnkey Development
We provide a full cycle:
- Analytics and strategy selection (2-3 days): define latency, volume, and stack requirements.
- Core bot development (1-2 weeks): WebSocket monitoring, quote engine, execution with priority fees, Jito bundling (optional).
- Risk management and monitoring (3-5 days): slippage protection, automatic error handling, Telegram alerts, metrics.
- Optimization (3-5 days): latency profiling, CU and priority fee tuning under real traffic.
- Documentation and training: handover code, architectural documentation, configure dashboard.
- Post-production support: one month of maintenance after launch.
Timeline Estimates
| Bot Type | Timeline |
|---|---|
| Basic (Jupiter API, auto priority fee) | from 1 week |
| Competitive (Jito bundling, Geyser, custom strategies) | 2-3 weeks |
Pricing is calculated individually based on complexity and infrastructure requirements. Our engineers with years of Solana ecosystem experience will assess your project and propose the optimal solution. Contact us to discuss details and get a consultation.
Common Bot Development Mistakes
- Ignoring priority fee — transactions hang for minutes.
- Overusing CU — overpay without priority gain.
- No error handling — funds locked on node failure.
- Storing private keys on server — compromise risks.
Order bot development for your strategy — get a consultation and preliminary estimate.







