SLOTDocumentation

Introduction

SLOT is a sub-slot timing synchronization engine for Solana. It eliminates timing-related transaction failures by analyzing slot phase lifecycles and firing transactions at optimal windows.

SLOT increases transaction landing rates from ~61% to ~94.7% during peak congestion by holding transactions until the next OPEN phase.
Jump to Quick Start

> WHY SLOT?

Every 400ms, Solana produces a new slot with four phases: OPEN, FILLING, PACKING, SEALING. Most failures happen because transactions arrive during the wrong phase — not because of insufficient fees.

PROBLEMCAUSEFAILURE RATE
Stale SlotTX lands after leader finished packing~31%
Boundary CollisionTX hits gap between slots~18%
Leader RotationTX routes to outgoing leader~12%
CU ContentionTX arrives at peak density~22%

Combined, 83% of transaction failures are timing-related. SLOT solves all of them.

Quick Start

Get running in under 60 seconds.

> STEP 1: INSTALL

terminal
npm install @slot/sdk

> STEP 2: INITIALIZE

app.ts
import { Slot } from '@slot/sdk'

const slot = new Slot({
  rpcUrl: 'https://api.mainnet-beta.solana.com',
  strategy: 'aggressive',
})

> STEP 3: FIRE

app.ts
const result = await slot.fire(transaction, {
  wallet,
  maxHoldMs: 2000,
  retries: 3,
})

console.log(result)
// {
//   status: 'confirmed',
//   phase: 'OPEN',
//   holdMs: 258,
//   slot: 284712039,
//   signature: '5Kz9...'
// }
The strategy option controls how aggressively SLOT waits. Use 'conservative' for time-sensitive TXs.

Installation

> REQUIREMENTS

DEPENDENCYVERSIONREQUIRED
Node.js>= 18.0.0Yes
@solana/web3.js>= 1.87.0Yes
TypeScript>= 5.0Recommended

> NPM

terminal
npm install @slot/sdk

> YARN

terminal
yarn add @slot/sdk

> PNPM

terminal
pnpm add @slot/sdk

> PYTHON

terminal
pip install slot-sdk
Python SDK is in beta. Some features may differ from TypeScript. Check the changelog.

Slot Phases

Every Solana slot (400ms) passes through four distinct phases.

SLOT LIFECYCLE (400ms)
OPEN
FILLING
PACKING
SEALING
0ms100ms200ms300ms400ms
PHASETIMELAND RATERECOMMENDATION
OPEN0-100ms94%Best window — fire here
FILLING100-200ms81%Good — acceptable risk
PACKING200-300ms47%Risky — hold if possible
SEALING300-400ms11%Dead zone — never fire

> READING PHASE STATE

phase-check.ts
const phase = await slot.getCurrentPhase()

console.log(phase)
// {
//   name: 'OPEN',
//   slot: 284712039,
//   elapsed: 42,
//   remaining: 358,
//   landRate: 0.94,
//   confidence: 0.97
// }

Hold Engine

The Hold Engine buffers transactions and waits for the next optimal phase window before firing.

HOLD ENGINE FLOW
TX IN
ANALYZE
HOLD
PHASE CHECK
FIRE

> STRATEGIES

STRATEGYMAX HOLDDESCRIPTION
aggressive2000msWaits up to 5 slots for OPEN phase
moderate800msWaits up to 2 slots for OPEN or FILLING
conservative400msFires at next non-SEALING phase
instant0msNo hold — fire immediately (baseline)
hold-config.ts
const result = await slot.fire(transaction, {
  wallet,
  strategy: 'aggressive',
  maxHoldMs: 2000,
  onHold: (phase, elapsed) => {
    console.log(`Holding... phase=${phase.name} elapsed=${elapsed}ms`)
  },
  onFire: (phase) => {
    console.log(`Fired at ${phase.name} (slot ${phase.slot})`)
  },
})
Setting maxHoldMs too high can cause timeouts. For DEX swaps, use 'moderate' or lower.

Architecture

Five layers, zero wasted transactions.

CLIENT SDK

TypeScript / Python entry point.

L1
PHASE TRACKER

Real-time slot phase analysis via leader schedule.

L2
HOLD ENGINE

Buffers TXs. Fires at optimal window.

L3
FEE CALIBRATOR

Phase-aware priority fee optimization. -83% overpayment.

L4
ON-CHAIN PROGRAM

Timing state gating. Verifies phase on-chain.

L5

Client SDK

> CONSTRUCTOR

constructor.ts
import { Slot } from '@slot/sdk'

const slot = new Slot(options: SlotOptions)
OPTIONTYPEDEFAULTDESCRIPTION
rpcUrlstringSolana RPC endpoint
strategyStrategy'moderate'Hold strategy preset
maxHoldMsnumber800Max hold duration (ms)
retriesnumber3Retry attempts
commitmentstring'confirmed'Commitment level
wsUrlstringautoWebSocket endpoint

> METHODS

slot.fire(tx, opts?)

Submit a transaction with timing optimization.

fire-result.ts
interface FireResult {
  status: 'confirmed' | 'failed' | 'timeout'
  phase: PhaseName
  holdMs: number
  slot: number
  signature: string
  retries: number
  fee: number
}

slot.getCurrentPhase()

Get real-time phase state without submitting.

slot.subscribe(callback)

Stream phase updates via WebSocket.

subscribe.ts
const unsub = slot.subscribe((phase) => {
  console.log(`Phase: ${phase.name} | Slot: ${phase.slot}`)
  if (phase.name === 'OPEN') {
    // optimal window
  }
})

unsub()

Configuration

> ENVIRONMENT VARIABLES

.env
SLOT_RPC_URL=https://api.mainnet-beta.solana.com
SLOT_WS_URL=wss://api.mainnet-beta.solana.com
SLOT_STRATEGY=aggressive
SLOT_MAX_HOLD_MS=2000
SLOT_RETRIES=3
SLOT_LOG_LEVEL=info

> STRATEGY PRESETS

PRESETHOLDPHASESUSE CASE
aggressive2000msOPEN onlyMaximum landing rate
moderate800msOPEN, FILLINGBalanced
conservative400msOPEN, FILLING, PACKINGTime-sensitive
instant0msAnyBaseline

> CUSTOM STRATEGY

custom-strategy.ts
const slot = new Slot({
  rpcUrl: process.env.SLOT_RPC_URL,
  strategy: {
    targetPhases: ['OPEN'],
    maxHoldMs: 1200,
    feeMultiplier: 1.5,
    retries: 5,
    retryDelay: 100,
    backoff: 'exponential',
  },
})
Custom strategies override preset values. Unspecified options fall back to 'moderate' defaults.

API Reference

API access requires holding $SLOT tokens. Tier determines rate limits.

> BASE URL

endpoint
https://api.slot.systems/v1

> ENDPOINTS

METHODPATHDESCRIPTION
GET/phaseCurrent slot phase state
GET/phase/historyPhase history (last 100 slots)
POST/fireSubmit timed transaction
GET/status/:sigCheck TX status
WS/ws/phasesReal-time phase stream
GET/healthAPI health check

> GET /phase

response.json
{
  "slot": 284712039,
  "phase": "OPEN",
  "elapsed_ms": 42,
  "remaining_ms": 358,
  "land_rate": 0.94,
  "leader": "dv1ZAG...",
  "next_leader": "Certus...",
  "timestamp": 1740700800000
}

> RATE LIMITS

TIERREQUIREMENTRATE LIMIT
PUBLICFree2 req/s
STANDARD100K $SLOT10 req/s
PRO500K $SLOT50 req/s
ENTERPRISE2M $SLOTUnlimited
Exceeding rate limits returns 429 with a Retry-After header.

SLOT DOCUMENTATION · MIT LICENSE · 2026