Skip to main content
ChainStream provides multi-chain real-time on-chain data streams through Kafka Streams. Compared to GraphQL Subscriptions and WebSocket, Kafka Streams is designed for latency-sensitive, high-reliability server-side application scenarios, offering lower latency and stronger fault tolerance for data consumption.

Protobuf Schema Repository

Official ChainStream Protobuf Schema definitions, supporting Go and Python, including all message types for EVM, Solana, and TRON.

Support Matrix

All chains also support token-supplies, token-prices, token-holdings, token-market-caps, trade-stats Topics. See full Topic list for details.

Kafka Streams vs WebSocket Selection Guide

When to Choose Kafka Streams

Latency Sensitive

Latency is the primary concern, application deployed on cloud or dedicated servers

Message Reliability

Cannot accept losing any messages, requires durable and reliable data consumption

Complex Processing

Need to perform complex computation, filtering, or formatting beyond pre-processing capabilities

Horizontal Scaling

Need multi-instance horizontal scaling for consumption capacity

When to Choose WebSocket

Rapid Prototyping

Building prototypes, development speed is the primary factor

Unified Interface

Application needs both historical and real-time data with unified query and subscription interface

Browser-side

Application consumes data directly in browser (Kafka Streams only supports server-side)

Dynamic Filtering

Need to dynamically filter data based on page content

Comparison Summary


Credential Acquisition

Kafka Streams uses independent authentication credentials and requires contacting the ChainStream team to apply for access.
1

Contact to Apply

Send an email to support@chainstream.io to apply for Kafka Streams access
2

Receive Credentials

After approval, you will receive the following credential information:
  • Username
  • Password
  • Broker address list
3

Configure Connection

Configure your Kafka client connection using the received credentials

Connection Configuration

Broker Address

The Broker address will be provided along with your credentials after your application is approved. Do not use any unauthorized addresses for connection.

SASL_SSL Connection Configuration


Topic Naming Convention & Complete List

Naming Convention

Topics follow this naming pattern:
Where {chain} includes: sol, bsc, eth, tron

Message Types

Complete Topic List

The following Topics apply to all supported chains (replace {chain} with sol, bsc, eth):
For complete Protobuf Schema and Topic mappings, refer to the streaming_protobuf repository.

Consumption Modes & Offset Management

Two core configurations to consider when subscribing to topics:

Offset Strategy Selection

Consumers need to decide where to start reading messages after connecting to Kafka. Two common strategies:
Start from the current latest position on each connection, suitable for scenarios only caring about real-time data. No historical message replay on reconnection.

Group ID Rules

Deploying multiple instances with the same Group ID enables failover and load balancing—messages from the same topic will only be consumed by one instance in the Group, with Kafka automatically distributing partitions among instances.
It’s recommended to have an independent consumer for each topic, as different topics have different message parsing logic.

Quick Start: First Consumer in 5 Minutes

The following example shows how to consume the eth.dex.trades topic and parse DEX trade data.
1

Get Protobuf Schema

Clone the Schema definitions from the official repository:
Or add as a Git submodule to your project:
2

Install Dependencies

3

Configure and Consume


Core Data Structures

All message types share these base structures (defined in common/common.proto):

Base Structures

Block information:

Main Message Types

Topic: {chain}.dex.trades
Trade Core Fields:TradeProcessed Enhanced Fields (processed topic):
Topic: {chain}.tokens, {chain}.tokens.created
Token Core Fields:
Topic: {chain}.balances
Balance Core Fields:
Topic: {chain}.dex.pools
DexPool Core Fields:
Topic: {chain}.candlesticks
Topic: {chain}.trade-stats
Topic: {chain}.token-holdings
Topic: {chain}.token-prices
Topic: {chain}.token-supplies
For complete Protobuf definitions, refer to the streaming_protobuf repository.

Message Characteristics & Considerations

Developers need to be aware of the following message characteristics when consuming Kafka Streams:
Stream does not pre-filter, containing all messages and complete data within the topic. This means consumers need sufficient network throughput, server performance, and efficient parsing code.
Messages for the same token or same account arrive strictly in block order. This means the event stream for a specific token or wallet address is ordered, making it easy to track state changes. However, message arrival order between different tokens/accounts is not guaranteed.
The same message may be delivered multiple times. If duplicate processing causes issues, consumers need to maintain cache or storage for idempotent processing.
ChainStream guarantees the integrity of each message. Messages will not be split. Regardless of how many transactions a block contains, the message you receive is a complete data unit.
Messages use Protobuf encoding, more compact than JSON. Consumers need to use the corresponding language’s Protobuf library for parsing.

Latency Model

Kafka Streams latency depends on the processing stages data passes through in the pipeline. Different topics from the same chain have different latencies:

Broadcasted vs Committed

Pipeline Latency

Each transformation layer from blockchain node to Kafka topic (parsing, structuring, enrichment) introduces approximately 100-1000ms latency:
  • raw topic: Lowest latency, closest to raw node data
  • transactions topic: Parsed and structured
  • dextrades topic: Relatively higher latency, but richer data
If latency is your primary concern, prefer topics closest to raw data that you can effectively parse.

Best Practices

Parallel Partition Consumption

Kafka topics are divided into multiple partitions, each partition needs parallel reading to maximize throughput. Message partition keys are set to token address or wallet address (unified across all chains), ensuring:
  • All events for the same token route to the same partition, guaranteeing order
  • All balance changes for the same wallet route to the same partition, facilitating state tracking
Recommend allocating an independent thread for each partition for load balancing.

Continuous Consumption, Don’t Block Main Loop

Consumer’s read loop should run continuously, avoiding backlog from message processing blocking. If messages need processing, adopt async processing mode: main loop handles reading, processing logic delegated to worker threads.

Message Processing Efficiency

Batch processing can reduce overhead, but requires balancing batch size and latency. In Go, use channel + worker group for concurrent processing.

Chain-Specific Documentation

EVM Streams

Ethereum, BSC, Base, Polygon, Optimism

Solana Streams

Solana high-throughput data streams

TRON Streams

TRON network data streams

Real-time Streaming

WebSocket real-time data integration guide

Authentication Guide

Get Access Token