Overview

Entry monitoring provides access to the fundamental execution units of the Solana blockchain. Entries contain batches of transactions and their execution results, offering the lowest-level view of blockchain activity.
Prerequisites: This guide assumes you’ve completed the Yellowstone gRPC Quickstart and have a working stream setup.
Advanced topic: Entry monitoring is primarily useful for deep blockchain analysis, debugging, and specialized use cases. Most applications should use transaction or account monitoring instead.

What are Entries?

Fundamental blockchain unitsEntries are the basic building blocks that validators use to construct blocks:
  • Transaction batches: Groups of transactions executed together
  • Execution order: Deterministic transaction ordering within entries
  • Hash chains: Cryptographic linking between entries
  • Timing information: When entries were created and processed
const subscribeRequest: SubscribeRequest = {
  entry: {
    entrySubscribe: {} // Subscribe to all entries
  },
  commitment: CommitmentLevel.CONFIRMED
};

Implementation Example

Basic Entry Monitoring

import { StreamManager } from './stream-manager'; // From quickstart guide

async function monitorEntries() {
  const streamManager = new StreamManager(
    "your-grpc-endpoint",
    "your-api-key",
    handleEntryUpdate
  );

  const subscribeRequest: SubscribeRequest = {
    entry: {
      entrySubscribe: {} // Subscribe to all entries
    },
    commitment: CommitmentLevel.CONFIRMED
  };

  console.log('Starting entry monitoring...');
  await streamManager.connect(subscribeRequest);
}

function handleEntryUpdate(data: any): void {
  if (data.entry) {
    const entry = data.entry;
    
    console.log('\n📋 Entry Details:');
    console.log(`  Slot: ${entry.slot}`);
    console.log(`  Index: ${entry.index || 'N/A'}`);
    console.log(`  Hash: ${entry.hash || 'N/A'}`);
    console.log(`  Num Hashes: ${entry.numHashes || 'N/A'}`);
    
    if (entry.transactions?.length > 0) {
      console.log(`\n  📦 Entry Transactions (${entry.transactions.length}):`);
      
      entry.transactions.forEach((tx: any, index: number) => {
        console.log(`    ${index + 1}. ${tx.signature || 'No signature'}`);
        console.log(`       Vote: ${tx.isVote ? 'Yes' : 'No'}`);
        
        // Show transaction status if available
        if (tx.meta) {
          const status = tx.meta.err ? 'Failed' : 'Success';
          console.log(`       Status: ${status}`);
          if (tx.meta.fee) {
            console.log(`       Fee: ${tx.meta.fee} lamports`);
          }
        }
      });
    } else {
      console.log(`  📦 No transactions in this entry`);
    }
    
    // Check if this is a tick entry (no transactions)
    if (entry.tick !== undefined) {
      console.log(`  ⏱️  Tick Entry: ${entry.tick ? 'Yes' : 'No'}`);
    }
  }
}

// Start monitoring
monitorEntries().catch(console.error);

Entry Analysis Example

Advanced analysis of entry patterns:
let entryStats = {
  totalEntries: 0,
  totalTransactions: 0,
  tickEntries: 0,
  largestEntry: 0,
  slotsProcessed: new Set<number>()
};

function analyzeEntry(data: any): void {
  if (data.entry) {
    const entry = data.entry;
    entryStats.totalEntries++;
    entryStats.slotsProcessed.add(entry.slot);
    
    const txCount = entry.transactions?.length || 0;
    entryStats.totalTransactions += txCount;
    
    if (txCount === 0 || entry.tick) {
      entryStats.tickEntries++;
    }
    
    if (txCount > entryStats.largestEntry) {
      entryStats.largestEntry = txCount;
      console.log(`\n🔥 New largest entry: ${txCount} transactions in slot ${entry.slot}`);
    }
    
    // Log stats every 100 entries
    if (entryStats.totalEntries % 100 === 0) {
      console.log('\n📊 Entry Statistics:');
      console.log(`  Total Entries: ${entryStats.totalEntries}`);
      console.log(`  Total Transactions: ${entryStats.totalTransactions}`);
      console.log(`  Tick Entries: ${entryStats.tickEntries}`);
      console.log(`  Slots Processed: ${entryStats.slotsProcessed.size}`);
      console.log(`  Avg Tx/Entry: ${(entryStats.totalTransactions / entryStats.totalEntries).toFixed(2)}`);
      console.log(`  Largest Entry: ${entryStats.largestEntry} transactions`);
    }
  }
}

Entry Data Structure

Understanding the entry data format:

Performance Considerations

Volume Characteristics

High-frequency data stream
  • Very high message rate
  • Continuous stream during network activity
  • Each entry contains multiple transactions
  • Requires efficient processing

Processing Efficiency

Optimize for performance
  • Process entries asynchronously
  • Batch entry analysis
  • Focus on specific data fields
  • Use sampling for large-scale analysis

Common Use Cases

Analyze transaction batching efficiency
function analyzeBatching(entry: any): void {
  const txCount = entry.transactions?.length || 0;
  
  if (txCount > 50) {
    console.log(`Large batch: ${txCount} transactions in entry ${entry.index}`);
  }
  
  // Track batching patterns
  const batchSizes = new Map<number, number>();
  const currentCount = batchSizes.get(txCount) || 0;
  batchSizes.set(txCount, currentCount + 1);
}

Filtering and Optimization

Entry monitoring currently doesn’t support specific filters, so all entries are streamed. To manage this:
Optimization strategies:
  • Client-side filtering: Process only entries matching your criteria
  • Sampling: Analyze every Nth entry for statistical analysis
  • Time-based analysis: Focus on specific time periods
  • Slot-based filtering: Only process entries from certain slots
  • Transaction type filtering: Focus on entries with specific transaction types
Example client-side filtering:
function handleFilteredEntries(data: any): void {
  if (data.entry) {
    const entry = data.entry;
    
    // Only process entries with transactions
    if (entry.transactions?.length > 0) {
      // Only process entries with non-vote transactions
      const hasNonVoteTransactions = entry.transactions.some((tx: any) => !tx.isVote);
      
      if (hasNonVoteTransactions) {
        processImportantEntry(entry);
      }
    }
  }
}

Best Practices

Troubleshooting

Next Steps

Remember: Entry monitoring is a specialized tool for advanced blockchain analysis. For most applications, transaction, account, or block monitoring will be more appropriate and efficient.