gRPC subscribers provide the lowest latency and highest throughput for account updates using Yellowstone or Laser gRPC streaming infrastructure. They are ideal for high-frequency trading and applications requiring maximum performance.
Overview
gRPC subscribers extend WebSocket subscribers with gRPC streaming capabilities:
- Yellowstone gRPC - Geyser plugin-based streaming
- Laser gRPC - High-performance streaming service
- Lower latency than WebSocket subscriptions
- Higher throughput than polling
- Requires dedicated gRPC infrastructure
GrpcConfigs
Configuration for gRPC connections.
Yellowstone Configuration
type YellowstoneGrpcConfigs = {
client?: 'yellowstone';
endpoint: string;
token: string;
commitmentLevel?: CommitmentLevel;
enableReconnect?: boolean;
channelOptions?: ConstructorParameters<typeof Client>[2];
};
Client type (defaults to yellowstone if not specified)
Authentication token for the gRPC service
Commitment level for updates (PROCESSED, CONFIRMED, or FINALIZED)
Whether to enable automatic reconnection on connection loss
gRPC channel options for advanced configuration
Laser Configuration
type LaserGrpcConfigs = {
client: 'laser';
endpoint: string;
token: string;
commitmentLevel?: CommitmentLevel;
enableReconnect?: boolean;
channelOptions?: LaserstreamConfig['channelOptions'];
};
Must be ‘laser’ for Laser gRPC client
Example Configurations
// Yellowstone configuration
const yellowstoneConfig: GrpcConfigs = {
client: 'yellowstone',
endpoint: 'https://grpc.mainnet.yellowstone.com:443',
token: 'your-auth-token',
commitmentLevel: CommitmentLevel.CONFIRMED,
enableReconnect: true,
};
// Laser configuration
const laserConfig: GrpcConfigs = {
client: 'laser',
endpoint: 'https://laser.drift.com:443',
token: 'your-auth-token',
commitmentLevel: CommitmentLevel.CONFIRMED,
enableReconnect: true,
};
grpcUserAccountSubscriber
Subscribe to user account updates via gRPC.
Constructor
new grpcUserAccountSubscriber(
grpcConfigs: GrpcConfigs,
program: Program,
userAccountPublicKey: PublicKey,
resubOpts?: ResubOpts
)
gRPC connection configuration
Anchor program instance for the Drift protocol
Public key of the user account to subscribe to
Options for automatic resubscription
Example Usage
import {
grpcUserAccountSubscriber,
CommitmentLevel
} from '@drift-labs/sdk';
import { Program } from '@coral-xyz/anchor';
import { PublicKey } from '@solana/web3.js';
// Configure gRPC connection
const grpcConfig = {
endpoint: 'https://grpc.mainnet.drift.com:443',
token: 'your-auth-token',
commitmentLevel: CommitmentLevel.CONFIRMED,
enableReconnect: true,
};
// Create gRPC subscriber
const userPubkey = new PublicKey('...');
const subscriber = new grpcUserAccountSubscriber(
grpcConfig,
program,
userPubkey,
{
resubTimeoutMs: 30_000,
logResubMessages: true,
}
);
// Listen for updates
subscriber.eventEmitter.on('userAccountUpdate', (userAccount) => {
console.log('User account updated via gRPC:', userAccount);
console.log('Total positions:', userAccount.perpPositions.length);
});
subscriber.eventEmitter.on('error', (error) => {
console.error('gRPC subscription error:', error);
});
// Subscribe
await subscriber.subscribe();
// Get current data
const { data: userAccount, slot } = subscriber.getUserAccountAndSlot();
console.log('Current user account at slot', slot);
// Cleanup
await subscriber.unsubscribe();
grpcDriftClientAccountSubscriber
Subscribe to Drift protocol accounts (state, markets, oracles) via gRPC.
Constructor
new grpcDriftClientAccountSubscriber(
grpcConfigs: GrpcConfigs,
program: Program,
perpMarketIndexes: number[],
spotMarketIndexes: number[],
oracleInfos: OracleInfo[],
shouldFindAllMarketsAndOracles: boolean,
delistedMarketSetting: DelistedMarketSetting,
resubOpts?: ResubOpts
)
gRPC connection configuration
Anchor program instance for the Drift protocol
Array of perpetual market indexes to subscribe to
Array of spot market indexes to subscribe to
Array of oracle information to subscribe to
shouldFindAllMarketsAndOracles
Whether to automatically discover and subscribe to all markets
delistedMarketSetting
DelistedMarketSetting
required
How to handle delisted markets
Options for automatic resubscription
Example Usage
import {
grpcDriftClientAccountSubscriber,
DelistedMarketSetting,
CommitmentLevel
} from '@drift-labs/sdk';
// Configure gRPC connection
const grpcConfig = {
client: 'yellowstone' as const,
endpoint: 'https://grpc.mainnet.yellowstone.com:443',
token: 'your-auth-token',
commitmentLevel: CommitmentLevel.CONFIRMED,
enableReconnect: true,
};
// Create gRPC subscriber for all markets
const driftSubscriber = new grpcDriftClientAccountSubscriber(
grpcConfig,
program,
[], // perpMarketIndexes - will be auto-discovered
[], // spotMarketIndexes - will be auto-discovered
[], // oracleInfos - will be auto-discovered
true, // shouldFindAllMarketsAndOracles
DelistedMarketSetting.Discard,
{
resubTimeoutMs: 30_000,
logResubMessages: true,
}
);
// Listen for events
driftSubscriber.eventEmitter.on('stateAccountUpdate', (state) => {
console.log('State updated via gRPC:', state);
});
driftSubscriber.eventEmitter.on('perpMarketAccountUpdate', (market) => {
console.log('Perp market updated:', market.marketIndex);
console.log('Market price:', market.amm.historicalOracleData.lastOraclePrice);
});
driftSubscriber.eventEmitter.on('spotMarketAccountUpdate', (market) => {
console.log('Spot market updated:', market.marketIndex);
});
driftSubscriber.eventEmitter.on('oraclePriceUpdate', (pubkey, source, data) => {
console.log('Oracle update via gRPC:', {
price: data.price.toString(),
slot: data.slot.toString(),
confidence: data.confidence.toString(),
});
});
// Subscribe to all accounts
await driftSubscriber.subscribe();
// Get state account
const { data: state } = driftSubscriber.getStateAccountAndSlot();
console.log('Exchange status:', state.exchangeStatus);
// Get specific market
const solPerpMarket = driftSubscriber.getMarketAccountAndSlot(0);
if (solPerpMarket) {
console.log('SOL-PERP funding rate:', solPerpMarket.data.amm.lastFundingRate);
}
// Dynamically add a market
await driftSubscriber.addPerpMarket(5);
// Cleanup
await driftSubscriber.unsubscribe();
grpcAccountSubscriber
Generic gRPC account subscriber for any account type.
Creating a Subscriber
const subscriber = await grpcAccountSubscriber.create<AccountType>(
grpcConfigs: GrpcConfigs,
accountName: string,
program: Program,
accountPublicKey: PublicKey,
decodeBuffer?: (buffer: Buffer) => AccountType,
resubOpts?: ResubOpts,
clientProp?: Client
)
gRPC connection configuration
Name of the account type (e.g., ‘state’, ‘market’)
Public key of the account to subscribe to
decodeBuffer
(buffer: Buffer) => AccountType
Optional custom buffer decoder function
Options for automatic resubscription
Optional pre-configured gRPC client to reuse
Example Usage
import { grpcAccountSubscriber } from '@drift-labs/sdk';
import { PublicKey } from '@solana/web3.js';
// Create gRPC subscriber for state account
const statePublicKey = await getDriftStateAccountPublicKey(program.programId);
const stateSubscriber = await grpcAccountSubscriber.create<StateAccount>(
{
endpoint: 'https://grpc.mainnet.drift.com:443',
token: 'your-auth-token',
commitmentLevel: CommitmentLevel.CONFIRMED,
},
'state',
program,
statePublicKey
);
// Subscribe with callback
await stateSubscriber.subscribe((state: StateAccount) => {
console.log('State account updated:', state);
console.log('Exchange paused:', state.exchangePaused);
});
// Get current data
const { data: state, slot } = stateSubscriber.dataAndSlot;
console.log('State at slot', slot, ':', state);
// Cleanup
await stateSubscriber.unsubscribe();
Other gRPC Subscribers
The SDK provides gRPC subscribers for various account types:
grpcUserStatsAccountSubscriber
import { grpcUserStatsAccountSubscriber } from '@drift-labs/sdk';
const statsSubscriber = new grpcUserStatsAccountSubscriber(
grpcConfig,
program,
userStatsPublicKey
);
await statsSubscriber.subscribe();
grpcInsuranceFundStakeAccountSubscriber
import { grpcInsuranceFundStakeAccountSubscriber } from '@drift-labs/sdk';
const stakeSubscriber = new grpcInsuranceFundStakeAccountSubscriber(
grpcConfig,
program,
stakeAccountPublicKey
);
await stakeSubscriber.subscribe();
Latency Comparison
| Method | Typical Latency | Use Case |
|---|
| gRPC | 10-50ms | High-frequency trading |
| WebSocket | 50-200ms | Real-time applications |
| Polling | 500-5000ms | Background monitoring |
Throughput
gRPC subscribers can handle:
- 1000+ updates per second
- Multiple concurrent account streams
- Lower overhead than WebSocket subscriptions
Resource Usage
- Network: Lower bandwidth than polling
- CPU: Moderate (protocol buffer decoding)
- Memory: Similar to WebSocket subscribers
Connection Management
Automatic Reconnection
Enable automatic reconnection on connection loss:
const grpcConfig = {
endpoint: 'https://grpc.example.com:443',
token: 'your-token',
enableReconnect: true, // Enable auto-reconnect
commitmentLevel: CommitmentLevel.CONFIRMED,
};
Manual Reconnection
Handle reconnection manually:
subscriber.eventEmitter.on('error', async (error) => {
console.error('Connection lost:', error);
// Wait before reconnecting
await new Promise(resolve => setTimeout(resolve, 5000));
// Resubscribe
try {
await subscriber.unsubscribe();
await subscriber.subscribe();
console.log('Reconnected successfully');
} catch (err) {
console.error('Reconnection failed:', err);
}
});
Best Practices
- Use connection pooling - Reuse gRPC clients across multiple subscribers
- Enable reconnection - Set
enableReconnect: true for production
- Monitor connection health - Listen to error events
- Choose appropriate commitment - Use CONFIRMED for balance of speed and safety
- Handle backpressure - Process updates quickly to avoid buffer overflow
- Secure credentials - Store gRPC tokens securely
Advantages Over WebSocket
- Lower latency - Direct streaming from validator
- Higher throughput - More efficient protocol
- Better error handling - Built-in reconnection
- Type safety - Protocol buffer schemas
- Multiplexing - Multiple streams over single connection
Infrastructure Requirements
Running Your Own gRPC Server
To run your own Yellowstone gRPC server:
- Set up a Solana validator with Geyser plugin
- Install and configure Yellowstone gRPC plugin
- Configure authentication tokens
- Set up SSL/TLS certificates
- Configure firewall and network access
Using Hosted Services
Alternatively, use hosted gRPC services:
- Triton - Managed Yellowstone gRPC infrastructure
- Helius - gRPC streaming service
- Custom providers - Various RPC providers offer gRPC endpoints
Troubleshooting
Connection Errors
// Check endpoint and token
if (error.message.includes('authentication')) {
console.error('Invalid token or endpoint');
}
// Check network connectivity
if (error.message.includes('connection')) {
console.error('Cannot reach gRPC endpoint');
}
Slow Updates
// Monitor update latency
let lastUpdate = Date.now();
subscriber.eventEmitter.on('update', () => {
const latency = Date.now() - lastUpdate;
if (latency > 1000) {
console.warn('High update latency:', latency, 'ms');
}
lastUpdate = Date.now();
});
Memory Leaks
// Always unsubscribe when done
try {
// Use subscriber
await subscriber.subscribe();
// ... do work ...
} finally {
// Cleanup
await subscriber.unsubscribe();
}