# SpacetimeDB Networking and Communication Protocols: A Complete Technical Guide

> Explore SpacetimeDB networking and communication protocols including WebSocket BSATN JSON HTTP APIs and PostgreSQL wire compatibility for real-time data.

- Repository: [Clockwork Labs/SpacetimeDB](https://github.com/clockworklabs/SpacetimeDB)
- Tags: deep-dive
- Published: 2026-03-09

---

**SpacetimeDB uses WebSocket connections (v1 binary BSATN or text JSON, plus v2 for event tables), HTTP APIs for stateless reducer calls, and PostgreSQL wire protocol compatibility to enable real-time database subscriptions and client communication.**

SpacetimeDB provides a rich set of network-enabled APIs that let clients, services, and tools communicate with a running database instance. According to the clockworklabs/SpacetimeDB source code, the architecture supports multiple protocols optimized for different use cases, from real-time game clients to standard SQL tooling.

## WebSocket Protocol Architecture

The primary communication channel for SpacetimeDB is WebSocket, designed to handle bidirectional real-time updates, reducer calls, and subscription management over a persistent connection.

### WebSocket v1 Binary (BSATN)

The binary WebSocket protocol uses the subprotocol identifier `v1.bsatn.spacetimedb` and encodes messages using BSATN (Binary Spacetime Algebraic Notation). This is the most efficient format for production use.

The low-level plumbing lives in [`sdks/rust/src/websocket.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/sdks/rust/src/websocket.rs), which implements the Tokio/Tungstenite connection, message framing, compression, and reconnection logic. The binary protocol constant is defined in [`crates/client-api-messages/src/websocket/v1.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/client-api-messages/src/websocket/v1.rs):

```rust
// From crates/client-api-messages/src/websocket/v1.rs
pub const BIN_PROTOCOL: &str = "v1.bsatn.spacetimedb";

```

### WebSocket v1 Text (SATS-JSON)

For debugging or language runtimes without binary support, the text protocol `v1.json.spacetimedb` uses SATS-JSON encoding. The same [`websocket.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/websocket.rs) module handles both formats, switching the message encoder based on the selected subprotocol during the handshake.

### WebSocket v2 for Event Tables

Introduced in SpacetimeDB 2.0, the v2 protocol supports event tables and a streamlined message model. The v2 message types are defined in [`client-api-messages/src/websocket/v2.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/client-api-messages/src/websocket/v2.rs), providing enhanced capabilities for complex subscription patterns.

### Connection Lifecycle and Identity

When a client opens a WebSocket connection via `GET /v1/database/<module>/subscribe`, the server creates a **connection instance** identified by a `ConnectionId` that persists for the session duration.

Two logical channels share the same TCP socket:

- **Request/Response** – Client-initiated calls such as `CallReducer` and `Subscribe`
- **Push** – Server-initiated subscription updates, row changes, and event table notifications

The subscription semantics, including ordering guarantees and message channel behavior, are documented in [`docs/versioned_docs/version-1.12.0/00200-core-concepts/00400-subscriptions/00200-subscription-semantics.md`](https://github.com/clockworklabs/SpacetimeDB/blob/main/docs/versioned_docs/version-1.12.0/00200-core-concepts/00400-subscriptions/00200-subscription-semantics.md).

**Lifecycle reducers** `client_connected` and `client_disconnected` run once per connection, providing module authors with hooks into connection events as documented in [`docs/static/llms.md`](https://github.com/clockworklabs/SpacetimeDB/blob/main/docs/static/llms.md).

## HTTP Database API for Stateless Operations

For one-off procedural calls and token-based authentication, SpacetimeDB exposes an HTTP API that mirrors WebSocket functionality for simple cases:

```bash

# Subscribe endpoint upgrades to WebSocket

GET /v1/database/:name_or_identity/subscribe

# Invoke a reducer statelessly

POST /v1/database/:name_or_identity/reducer

# One-shot database dump

GET /v1/database/:name_or_identity/snapshot

```

Headers such as `Authorization: Bearer <token>` and `Sec-WebSocket-Protocol` are defined in the HTTP API documentation at [`docs/versioned_docs/version-1.12.0/00300-resources/00200-reference/00200-http-api/00300-database.md`](https://github.com/clockworklabs/SpacetimeDB/blob/main/docs/versioned_docs/version-1.12.0/00300-resources/00200-reference/00200-http-api/00300-database.md).

## PostgreSQL Wire Protocol Compatibility

SpacetimeDB implements the native PostgreSQL wire protocol, allowing standard `psql` clients or any PostgreSQL driver to connect directly. The server acts as a thin wrapper around the same subscription engine, translating PG messages into internal `WebSocketMessage` types.

The implementation entry point resides in [`crates/pg/src/pg_server.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/pg/src/pg_server.rs), utilizing the `pgwire` crate for protocol handling:

```bash
psql "host=localhost port=5432 dbname=my_module user=spacetimedb"

```

## Internal RPC and Subscription Mechanics

Beyond client-facing protocols, SpacetimeDB uses a custom RPC system for internal communication between the host and database instances. This handles subscription management, metrics collection, and intra-process message passing.

The subscription message handling and ordering guarantees are implemented in `crates/core/src/subscription/*`, while network traffic metrics—including WebSocket request/response counts, payload sizes, and compression timings—are tracked in [`crates/core/src/worker_metrics/mod.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/core/src/worker_metrics/mod.rs).

## Client SDK Implementation Patterns

All language SDKs abstract the low-level protocol details while exposing consistent APIs for connection management.

### Rust SDK Connection Handling

The Rust SDK in [`sdks/rust/src/websocket.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/sdks/rust/src/websocket.rs) spawns a background Tokio task running `WsConnection::connect`. The `DbConnection` object exposes `subscribe`, `call_reducer`, and event callbacks while handling automatic reconnection and compression negotiation (supporting none, deflate, and zstd via [`sdks/rust/src/compression.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/sdks/rust/src/compression.rs)).

### TypeScript and Game Engine SDKs

The TypeScript SDK leverages the browser's native `WebSocket` API with automatic compression negotiation. Unity and Unreal SDKs wrap the low-level socket in engine-friendly components, advancing the connection each frame to process incoming messages.

## Summary

- **WebSocket protocols** (`v1.bsatn.spacetimedb`, `v1.json.spacetimedb`, and `v2`) provide real-time bidirectional communication for subscriptions and reducer calls, implemented in [`sdks/rust/src/websocket.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/sdks/rust/src/websocket.rs) and `crates/client-api-messages/src/websocket/`.
- **HTTP API** offers stateless endpoints for reducer invocation and snapshots, documented in the HTTP Database API reference.
- **PostgreSQL wire protocol** compatibility allows standard SQL tools to connect via [`crates/pg/src/pg_server.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/pg/src/pg_server.rs).
- **Internal RPC** handles subscription management and metrics in `crates/core/src/subscription/` and [`crates/core/src/worker_metrics/mod.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/core/src/worker_metrics/mod.rs).
- **Compression** (deflate, zstd) and **connection lifecycle reducers** (`client_connected`, `client_disconnected`) provide production-ready optimization and hooks.

## Frequently Asked Questions

### What protocol does SpacetimeDB use for real-time updates?

SpacetimeDB uses WebSocket connections as the primary protocol for real-time updates. Clients can choose between the binary `v1.bsatn.spacetimedb` format for efficiency or `v1.json.spacetimedb` for debugging. Version 2 of the protocol introduces enhanced support for event tables and streamlined message models in SpacetimeDB 2.0.

### How does SpacetimeDB handle compression in WebSocket connections?

The Rust SDK in [`sdks/rust/src/compression.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/sdks/rust/src/compression.rs) automatically negotiates compression during the WebSocket handshake, supporting none, deflate, and zstd algorithms. Compression is applied per-message to reduce bandwidth for subscription updates and reducer calls. Metrics for compression timing and payload sizes are tracked in [`crates/core/src/worker_metrics/mod.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/core/src/worker_metrics/mod.rs).

### Can I use standard PostgreSQL tools with SpacetimeDB?

Yes, SpacetimeDB implements the native PostgreSQL wire protocol in [`crates/pg/src/pg_server.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/pg/src/pg_server.rs), allowing you to connect using standard tools like `psql`, pgAdmin, or any PostgreSQL driver. The server translates PG messages into internal WebSocket messages, enabling SQL queries against your module's tables while maintaining compatibility with existing database tooling.

### What is the difference between BSATN and SATS-JSON formats?

**BSATN** (Binary Spacetime Algebraic Notation) is the binary encoding used by the `v1.bsatn.spacetimedb` WebSocket subprotocol, offering compact, efficient serialization for production use. **SATS-JSON** is the text-based JSON encoding used by `v1.json.spacetimedb`, defined in the same protocol files but human-readable for debugging or environments without binary support. Both formats are handled by the SDK's [`websocket.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/websocket.rs) module, which switches encoders based on the negotiated subprotocol.