Skip to content

Module llm streaming Architecture

github-actions[bot] edited this page Sep 1, 2026 · 3 revisions

LLM Streaming Module β€” Architecture

Overview

The LLM streaming module provides real-time streaming infrastructure for large language model responses within ThemisDB, enabling efficient token-level streaming to clients with flow-control and error recovery capabilities.

Design Principles

  1. Token-Level Streaming: Tokens sent to client as soon as available (no buffering)
  2. Backpressure Awareness: Respects client receive window; buffers on congestion
  3. Connection Resilience: Graceful handling of client disconnections and network failures
  4. Cancellation Support: Clients can cancel in-progress streams cleanly
  5. Observable: All streaming events logged with correlation IDs

Architecture Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LLM Inference Engine                                       β”‚
β”‚  β€’ Produces tokens as they are generated                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  StreamDispatcher (Request Routing)                         β”‚
β”‚  β€’ Route LLM requests to streaming implementation           β”‚
β”‚  β€’ Manage stream lifecycle (open, active, close)            β”‚
β”‚  β€’ Track active streams and concurrent connections         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TokenBuffer (Aggregation & Batching)                       β”‚
β”‚  β€’ Buffer tokens for network efficiency                     β”‚
β”‚  β€’ Batching based on size/time threshold                    β”‚
β”‚  β€’ Preserve token order and metadata                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  BackpressureController (Flow Control)                      β”‚
β”‚  β€’ Monitor client receive window                            β”‚
β”‚  β€’ Apply backpressure when buffer full                      β”‚
β”‚  β€’ Implement exponential backoff on congestion              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  StreamingServer (Protocol Handler)                         β”‚
β”‚  β€’ gRPC streaming endpoint                                  β”‚
β”‚  β€’ HTTP Server-Sent Events (SSE)                            β”‚
β”‚  β€’ Connection management & lifecycle                        β”‚
β”‚  β€’ Timeout enforcement                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β–Ό
                   Network
                       β”‚
                       β–Ό
                  Streaming Client

Core Components

StreamingServer

Purpose: Protocol handler for streaming responses over gRPC or HTTP.

Responsibilities:

  • Accept streaming requests (gRPC or HTTP SSE)
  • Manage connection lifecycle (open, active, close)
  • Enforce per-stream timeouts
  • Send tokens to client with metadata
  • Handle client disconnection gracefully

Public API:

class StreamingServer {
  Result<> startStream(const LLMRequest& req, StreamWriter* writer);
  Result<> sendToken(const Token& token);
  void cancelStream(const StreamId& id);
};

StreamDispatcher

Purpose: Route LLM requests to streaming implementation.

Responsibilities:

  • Create new stream for each LLM request
  • Coordinate with LLM inference engine
  • Manage stream state transitions
  • Track active streams
  • Clean up closed streams

Key Contracts:

  • dispatch(request) β†’ StreamId β€” Create new stream
  • getStream(id) β†’ Stream* β€” Lookup active stream
  • closeStream(id) β€” Terminate stream

TokenBuffer

Purpose: Aggregate tokens for efficient network transmission.

Approach:

  • Buffer tokens until size threshold or time deadline reached
  • Batch multiple tokens into single network message
  • Preserve token order and metadata
  • Configurable batching heuristics

Configuration:

  • Batch size threshold (default: 10 tokens)
  • Max latency threshold (default: 100 ms)
  • Buffer capacity (default: 1000 tokens)

Performance:

  • Reduces network roundtrips by 10-100x
  • Maintains latency < 100 ms for small batches

BackpressureController

Purpose: Implement flow control to respect client receive window.

Approach:

  • Monitor client acknowledgments and window size
  • Pause token sending when buffer full
  • Implement exponential backoff during congestion
  • Resume when client acknowledges

Flow Control Model:

Token Available
  β”‚
  β”œβ”€β–Ί Check client receive window
  β”‚
  β”œβ”€β–Ί If space available:
  β”‚   └─► Send token immediately
  β”‚
  └─► If buffer full:
      β”œβ”€β–Ί Add to backpressure queue
      β”œβ”€β–Ί Notify LLM (slow producer)
      └─► Wait for client acknowledgment

Data Flow

Token Emission Pipeline

LLM Inference Engine
  β”‚ produces token
  β–Ό
StreamDispatcher.onToken(token)
  β”‚ get active stream
  β–Ό
TokenBuffer.addToken(token)
  β”‚ check batching criteria
  β”œβ”€β–Ί If size threshold reached:
  β”‚   └─► flush batch
  β”œβ”€β–Ί If time threshold reached:
  β”‚   └─► flush batch
  └─► If capacity exceeded:
      └─► apply backpressure
          β”‚
          β–Ό
      BackpressureController
        β”‚ wait for client window
        β–Ό
      StreamingServer.sendBatch(tokens)
        β”‚ send to client
        β–Ό
      Network β†’ Client

Concurrency Model

Thread Safety

  1. Per-Stream State: Protected by stream-specific mutex

    • Token buffer state
    • Backpressure state
    • Stream lifecycle flags
  2. Global Stream Registry: Protected by read-write lock

    • Enables fast lookup of active streams
    • Minimal contention for stream creation/deletion
  3. Token Emission: Lock-free where possible

    • Atomic token counter
    • Compare-and-swap for stream state transitions

Synchronization Primitives

  • std::mutex for stream-specific critical sections
  • std::shared_mutex for stream registry
  • std::condition_variable for backpressure signaling
  • std::atomic<> for stream counters

Performance Characteristics

Target Latencies (P99)

  • Token Enqueue: < 1 ms
  • Batch Formation: < 100 ms (batching deadline)
  • Network Send: < 50 ms
  • End-to-End (token β†’ client): < 200 ms
  • Cancellation Propagation: < 100 ms

Throughput

  • Token Throughput: > 100 tokens/sec per stream
  • Concurrent Streams: β‰₯ 100 active streams
  • Aggregate Throughput: 10k+ tokens/sec

Resource Consumption

  • Per-Stream Memory: ~10 MB (including buffers)
  • Token Buffer Overhead: ~100 bytes per token
  • Total Memory (100 streams): ~1 GB

Error Handling

Graceful Degradation

  1. Client Disconnection β†’ Detect via write failure; clean up stream
  2. Network Timeout β†’ Retry with exponential backoff
  3. Backpressure Timeout β†’ Close stream with error
  4. Buffer Overflow β†’ Return backpressure error to LLM producer

Error Codes (E7300–E7399)

  • E7300: Stream not found
  • E7301: Cancellation requested
  • E7302: Backpressure buffer exceeded
  • E7303: Token send timeout
  • E7304: Invalid token sequence

Integration Points

LLM Inference Engine

Streaming receives tokens from LLM inference as they are produced:

  • Token callback: onToken(token, finish_reason)
  • LLM can check backpressure: isBackpressured() β†’ bool

Client Protocols

  • gRPC: ServerWriter streaming
  • HTTP: Server-Sent Events (SSE)

See Also


ThemisDB 1.9.0-beta Β· Home Β· Module-Index Β· GitHub Β· Issues

ThemisDB Wiki

🏠 Overview

πŸš€ Getting Started

πŸ“– Tutorials

πŸ“— User Guide

βš™οΈ Operations & Security

πŸ“Ÿ Ops Runbooks

πŸ—οΈ Architecture

πŸ“ ADRs

πŸ”§ Contributing

πŸ“‹ Governance

πŸ” Audit

🧩 Plugins

πŸ”Œ Adapters

πŸ’‘ Examples

πŸ“¦ Client SDKs

πŸŽ“ Training

πŸ› οΈ Tools

πŸ€– Developer LLM Wiki

Clone this wiki locally