Real-time Server-Sent Events (SSE) stream for NEAR blockchain blocks. Powered by neardata.xyz.
Use the free hosted service at live.near.tools
Stream from latest block:
curl -N https://live.near.toolsJavaScript/TypeScript:
const eventSource = new EventSource("https://live.near.tools")
eventSource.addEventListener("block", (event) => {
const block = JSON.parse(event.data)
console.log("Block", event.lastEventId, block)
})
eventSource.addEventListener("ping", (event) => {
console.log("Keep-alive ping")
})
// Automatic reconnection with resume support
eventSource.onerror = () => {
console.log("Connection lost, reconnecting...")
// Browser automatically sends Last-Event-ID header to resume
}Resume from specific block:
curl -N "https://live.near.tools?from_height=170727400"Server-Sent Events endpoint for real-time block streaming.
Query Parameters:
from_height(optional) - Resume stream from block height (exclusive)
Response Headers:
Content-Type: text/event-streamCache-Control: no-cache
Event Format:
event: block
id: 170727400
data: {"block_height":170727400,"block_hash":"...","prev_block_hash":"...",...}
event: block
id: 170727401
data: {"block_height":170727401,...}
Health check endpoint. Returns "ok" as JSON.
- Real-time streaming - SSE endpoint for live NEAR block data
- Automatic catch-up - Clients can resume from any block height
- Finality guarantee - Only streams finalized blocks
- Horizontally scalable - Scale SSE servers independently with Redis
- Distributed architecture - Separate ingester and server components
- Batch processing - Efficiently handles multiple new blocks per poll
- Redis-backed buffer - 256 recent blocks cached for fast catch-up
- Production-ready - Built for reliability, self-hosting, and Kubernetes
Want to run your own instance? Deploy with Docker Compose or build from source.
The service uses a distributed architecture with Redis for horizontal scaling:
# Start all services (Redis + Ingester + Server)
docker compose up -d
# Scale SSE servers for high traffic
docker compose up -d --scale server=3This starts:
- Redis - Block storage and streaming (port 6380)
- Ingester - Fetches blocks from neardata.xyz and publishes to Redis
- Server - Serves SSE streams to clients (port 8080)
Server available at http://localhost:8080
# Build
cargo build --release
# Run ingester (fetches blocks, publishes to Redis)
MODE=ingester \
REDIS_URL=redis://localhost:6379 \
NEARDATA_BASE=https://mainnet.neardata.xyz \
POLL_RETRY_MS=1000 \
cargo run --release
# Run server (serves SSE streams from Redis)
MODE=server \
REDIS_URL=redis://localhost:6379 \
BIND_ADDR=0.0.0.0 \
BIND_PORT=8080 \
cargo run --releaseAll configuration via environment variables:
| Variable | Description | Default | Used By |
|---|---|---|---|
MODE |
Runtime mode: ingester or server |
Required | Both |
REDIS_URL |
Redis connection URL | redis://localhost:6379 |
Both |
NEARDATA_BASE |
neardata.xyz API base URL | https://mainnet.neardata.xyz |
Ingester |
POLL_RETRY_MS |
Milliseconds between finality checks | 1000 |
Ingester |
BIND_ADDR |
Server bind address | 0.0.0.0 |
Server |
BIND_PORT |
Server bind port | 8080 |
Server |
RUST_LOG |
Log level (tracing filter) | near_stream=info,tower_http=info |
Both |
The service automatically retries failed requests with exponential backoff:
- Max retries: 5 attempts
- Backoff: Exponentially increases (1s, 2s, 4s, 8s, 16s)
- Triggers: 429 (rate limit), 5xx (server errors), network failures
- Jitter: Prevents thundering herd on retry
For testnet:
# In docker-compose.yml, update ingester environment:
NEARDATA_BASE=https://testnet.neardata.xyzFor high-traffic (many SSE clients):
# Scale SSE servers horizontally
docker compose up -d --scale server=5If consistently hitting rate limits:
# In docker-compose.yml, update ingester environment:
POLL_RETRY_MS=2000 # Poll less frequentlyFor verbose debugging:
RUST_LOG=near_stream=debug,tower_http=debugDistributed architecture with Redis for horizontal scaling:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NEAR Stream (Split) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββ΄βββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ
β Ingester (1x) β β Server (Nx) β
β β β β
β - Polls β β - Catch-up β
β neardata.xyz β β from Redis β
β - Fetches β β - Subscribe to β
β blocks β β new blocks β
β - Publishes to β β - Serve SSE β
β Redis Streams β β to clients β
ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β β
β ββββββββββββββββ β
βββββββΆβ Redis ββββββββββββ
β Streams β
β β
β - 256 blocks β
β - Auto-trim β
β - Pub/sub β
ββββββββββββββββ
β
βΌ
SSE Clients
-
Ingester (single instance)
- Polls neardata.xyz for finalized blocks
- Handles skipped blocks and rate limiting
- Publishes to Redis Streams
- Auto-trims to maintain 256 block buffer
-
Server (horizontally scalable)
- Reads catch-up blocks from Redis
- Subscribes to new blocks via Redis Streams
- Serves SSE streams to clients
- Scale independently:
docker compose up --scale server=N
-
Redis Streams
- Persistent block buffer (256 blocks)
- Pub/sub for real-time distribution
- Automatic trimming (LRU eviction)
- Single source of truth
- Ingester polls neardata.xyz every ~1s for latest finalized block
- Batch catch-up: If multiple blocks finalized, fetches all sequentially
- Publish: Each block published to Redis Streams
- Auto-trim: Redis maintains last 256 blocks
- SSE Servers:
- New client connects
- Server reads catch-up blocks from Redis
- Server subscribes to Redis for new blocks
- Streams both via SSE to client
- Limited history: Only 256 most recent blocks cached in Redis
- Older blocks require fetching from neardata.xyz directly
- Sufficient for reconnection and catch-up scenarios
- Single chain: Configure for mainnet OR testnet, not both
- Rate limits: Respects neardata.xyz API limits (~1s poll interval)
- Redis dependency: Both ingester and servers require Redis connection
This is a public good project. Contributions welcome!
MIT
Built with:
- axum - Web framework
- tokio - Async runtime
- redis-rs - Redis client with Streams support
- tracing - Structured logging
- reqwest-retry - Automatic retry with exponential backoff
- neardata.xyz - NEAR block data API