Skip to content

Real-Time Market Data & SSE Architecture

📡 Real-Time Market Data & SSE Architecture

Section titled “📡 Real-Time Market Data & SSE Architecture”

Delivering real-time cryptocurrency price updates directly to the browser poses distinct engineering challenges:

  1. Connecting the browser directly to multiple external WebSockets exhausts browser resources, triggers CORS complications, and leaks user portfolio interests to third-party exchanges.
  2. Polling REST APIs frequently triggers rate-limits (429 Too Many Requests).

To solve this, Kryptofolio implements a centralized Server-Sent Events (SSE) architecture orchestrated entirely by the Hono backend.


flowchart TD
    subgraph Frontend ["Vue 3 Frontend"]
        UI["UI Widgets (Live Price & Portfolio Equity)"]
        BffAdapter["BffMarketDataAdapter (EventSource)"]
    end

    subgraph Backend ["Hono Backend Server"]
        SSEEndpoint["GET /api/market/stream (SSE)"]
        Orchestrator["MarketDataOrchestrator"]
        PriceHistory["IPriceHistoryPort (Cache & Parquet)"]

        Provider1["Kraken WS Adapter (Active)"]
        Provider2["Binance WS Adapter (Standby)"]
    end

    subgraph Exchanges ["External Crypto Exchanges"]
        KrakenWS["Kraken WebSocket API v2"]
        BinanceWS["Binance WebSocket Stream"]
    end

    UI --> BffAdapter
    BffAdapter -->|Single EventSource Connection| SSEEndpoint
    SSEEndpoint --> Orchestrator

    Orchestrator -->|Hot-swaps active feed| Provider1
    Orchestrator -.->|Disabled| Provider2

    KrakenWS ==>|Live Ticks| Provider1
    Provider1 --> Orchestrator

    Orchestrator -->|1. Flush to Cache & History| PriceHistory
    Orchestrator -->|2. Broadcast Tick Payload| SSEEndpoint

The frontend opens exactly one persistent HTTP connection using standard HTML5 EventSource (/api/market/stream). All active asset ticks (e.g. BTC/EUR, ETH/EUR, SOL/USD) travel through this single multiplexed stream.

Users can change their preferred market provider in the Settings or Vault view (e.g., switching from Kraken to Binance or CoinGecko):

  1. The backend MarketDataOrchestrator cleanly tears down the active Kraken WebSocket session.
  2. It establishes a connection to the newly selected provider.
  3. It resumes streaming ticks down the existing SSE pipe.
  4. The frontend requires zero reconnection logic or UI interruption.

Every live price tick broadcast through SSE is concurrently flushed to the backend IPriceHistoryPort:

  • Guarantees that subsequent REST calls (GET /api/metrics/kpis) evaluate portfolios using the exact same price snapshot currently visible in live UI ticker widgets.
  • Writes partitioned historical ticks to Apache Parquet files on disk for long-term time-series analysis.

📦 Client-Side Composable (useMarketStream)

Section titled “📦 Client-Side Composable (useMarketStream)”

The frontend interacts with market data via a Vue composable:

import { useMarketStream } from '@/composables/queries/useMarketStream';
export function useLivePortfolio() {
const { isConnected, latestTicks } = useMarketStream();
const btcPrice = computed(() => latestTicks.value['BTC/EUR']?.price);
return { isConnected, btcPrice };
}