Skip to main content

Overview

S2S (S2 Streaming) is a binary framing protocol optimized for streaming records to and from S2. It provides:
  • Bi-directional streaming - Continuous reads and writes in both directions
  • Compression - Built-in support for gzip and zstd compression
  • Efficiency - Protocol buffer encoding with minimal overhead
  • Error handling - Graceful termination with error details

When to Use S2S

Choose S2S over REST or SSE when:
  • You need bi-directional streaming (streaming appends)
  • You want lower latency than HTTP request/response
  • You need higher throughput with compression
  • You’re building real-time data pipelines
For simple use cases, consider:
  • REST API - Single reads or writes, simpler integration
  • Server-Sent Events (SSE) - Read-only streaming with standard tools

Protocol Specification

Frame Structure

S2S uses length-prefixed frames with the following structure:
Length (3 bytes)
  • Big-endian unsigned integer
  • Specifies size of FLAGS + PAYLOAD
  • Does NOT include the 3-byte length prefix itself
  • Maximum: 2 MiB (enforced limit)
Flags (1 byte)
Payload
  • Protocol buffer message (regular frames)
  • Status code + JSON body (terminal frames)

Regular Frame

Carries a Protocol Buffer message:
  • Terminal bit = 0
  • Compression bits indicate algorithm
  • Payload is a Protocol Buffer message

Terminal Frame

Signals end of stream with error details:
  • Terminal bit = 1
  • Status code is HTTP status (2 bytes, big-endian)
  • Body is JSON-encoded error message
After receiving or sending a terminal frame, the session must be closed. No further frames should be sent or expected.

Compression

S2S supports three compression algorithms:

Compression Selection

The server selects compression based on the Accept-Encoding header:
  • Zstd is preferred for best compression and speed
  • Gzip is used as fallback if zstd is not supported
  • None is used if no encoding is specified

Compression Threshold

Messages smaller than 1 KiB are not compressed (compression flag = 0) even if an algorithm is selected. This avoids compression overhead for small payloads.

Message Types

Read Session Messages

Server sends ReadBatch messages:
Example flow:
  1. Client opens S2S read session
  2. Server sends frames containing ReadBatch messages
  3. Each batch contains one or more records
  4. Server sends heartbeats (empty batches) every 5-15 seconds
  5. Session continues until error or client closes

Append Session Messages

Client sends AppendInput, server responds with AppendAck:
Example flow:
  1. Client opens S2S append session
  2. Client sends frames containing AppendInput messages
  3. Server responds with frames containing AppendAck messages
  4. Process continues for streaming writes
  5. Either side can send terminal frame to end session

Initiating a Session

Read Session

Open a streaming read:
Response:

Append Session

Open a streaming append:
Response:

Error Handling

Terminal Messages

When an error occurs, the server sends a terminal frame: Example terminal frame payload:

Common Error Codes

Retry Strategy

For transient errors (5xx), implement exponential backoff:

Frame Encoding Example

Encoding a ReadBatch with 2 records:

Frame Decoding Example

Protocol Buffer Definitions

S2S uses Protocol Buffers v3. Full definitions:

StreamPosition

AppendRecord

SequencedRecord

See the full protocol buffer definitions in the S2 repository.

SDK Support

S2 SDKs provide automatic S2S protocol handling:

Rust SDK

The SDK handles frame encoding/decoding, compression negotiation, and error handling automatically.

Performance Characteristics

Compression Ratios

Typical compression ratios for log data:
  • Zstd: 5-10x compression
  • Gzip: 4-8x compression
  • None: 1x (no compression)

Latency

  • Frame overhead: ~4 bytes per message (length + flags)
  • Network RTT: Depends on client location
  • Compression: 1-5ms for typical messages

Throughput

S2S can sustain:
  • Reads: 100+ MB/s per session with compression
  • Writes: 50+ MB/s per session with compression
Actual performance depends on record size, compression ratio, and network conditions.

Best Practices

1. Enable Compression

Always request compression for production workloads:

2. Batch Records

Batch multiple records per frame to reduce overhead:

3. Handle Terminal Frames

Always check for terminal frames and handle gracefully:

4. Implement Heartbeat Detection

For read sessions, detect heartbeats (empty batches) to confirm liveness:

5. Use Connection Pooling

Reuse connections when possible, but open new sessions for each streaming operation.

Limitations

  • Maximum frame size: 2 MiB (enforced)
  • Maximum batch size: 1000 records or 1 MiB of metered data
  • Heartbeat interval: 5-15 seconds (server-controlled)

Next Steps

API Overview

Learn about S2 API structure and endpoints

SDK Reference

Use the Rust SDK for automatic S2S handling