Sugavanesh Murugesan Backend Craftsman & System Designer

SpacetimeDB - A New Paradigm for Backend Development

Introduction

SpacetimeDB rethinks how we build backend systems by making the database the execution engine itself. Designed with real-time applications and games in mind, it eliminates the network boundary between backend and storage.

What It Brings New to the Table

  • Module-based performance boost: Native module support written in languages like C# and compiled to WASM gives ultra-low latency.
  • Better SDK structure: Clean abstraction and binding generation simplify integration.
  • Distributed sync: Built-in peer-to-peer synchronization of data across distributed nodes, unlike traditional client-server models.

Purpose of SpacetimeDB

SpacetimeDB aims to be a drop-in backend replacement for game developers and real-time apps. It’s also excellent for rapid prototyping of scalable, high-performance systems.

Getting Started with Development

Basics & Initialization

# Initialize your module in C#
spacetime init spacetime-modules --lang csharp
spacetime build

# Publish your module
spacetime publish --project-path server unichat

Setting up Client (React + TS)

npm create vite@latest unichat-client -- --template react-ts
cd unichat-client
npm install
npm run dev

Add dependencies

npm install react-router-dom@latest
npm install @clockworklabs/spacetimedb-sdk
npm install react-oidc-context oidc-client-ts
npm install @auth0/auth0-react

Generate TS Bindings

spacetime generate --lang typescript --out-dir src/module_bindings --project-path ../spacetime-modules

Sample C# Reducer Example

using Spacetime;

[SpacetimeModule]
public partial class ChatModule : SpacetimeModule
{
    [Reducer]
    public static void SendMessage(
        Context ctx,
        string message,
        string roomId)
    {
        var chatRoom = ChatRoom.FirstOrDefault(r => r.Id == roomId);
        if (chatRoom == null)
        {
            throw new SpacetimeException("Room not found");
        }

        var newMessage = new Message
        {
            Sender = ctx.Identity.Id,
            Content = message,
            Timestamp = SystemTime.Now()
        };

        chatRoom.Messages.Add(newMessage);
    }
}

Modules vs SDK Performance

Modules (WASM compiled logic) perform significantly better than pure SDK usage. For performance-critical systems, modules are the way to go.

Fullstack Auth Flow with SpacetimeDB and Auth0

UCAC (User Centric Access Control)

Introduces fine-grained, user-scoped control for row-level operations.

RBAC for Admins

Global-level control using Role Based Access Control and policies.

Internal Architecture

Includes a WASM execution layer that runs reducer logic inside the DB engine itself, providing secure, high-perf execution.

WASM Layer Benefits

  • Fast, safe execution
  • Language-agnostic module support
  • Sandboxed logic tightly coupled with DB state

Comparison with Traditional Backends

  • Removes need for external app + DB communication
  • Lower latency
  • Native replication and sync
  • Less glue code and deployment complexity

DevX (Developer Experience)

SpacetimeDB’s DX rivals modern backend frameworks, but with built-in real-time sync and persistence.

Performance and Architecture Thoughts

While performance is key, it’s more about removing bottlenecks like network I/O and reducing SPOFs (Single Points of Failure).

Things I Miss or Wish For

  • Scaling is DB-style, not traditional backend-style
  • Could benefit from an engine model like TigerBeetleDB for multi-node WASM exec

Struggles Encountered

Auth0 Integration Issue

While building Unichat, a real-time chat application using SpacetimeDB, I integrated Auth0 for authentication. Initially, SpacetimeDB couldn’t verify Auth0’s issued JWTs due to a failure in handling the provider’s well-known JWKS URL for public key discovery.

This caused the server to reject valid Auth0 tokens. As a workaround, I patched the token_validation.rs file locally. Fortunately, this issue was resolved officially in SpacetimeDB’s alpha build as of April 17, 2025.

Here’s a brief of how my app handles authentication:

Backend Reducers (C#)

[Table(Name = "user", Public = true)]
public partial class User {
  [PrimaryKey] public Identity id;
  public string? name;
}

[Table(Name = "message", Public = true)]
public partial class Message {
  [PrimaryKey] public ulong id;
  public Identity sender;
  public Identity receiver;
  public string content = "";
  public Timestamp timestamp;
}

[Reducer]
public static void RegisterUser(ReducerContext ctx, string name) {
  var user = ctx.Db.user.id.Find(ctx.Sender);
  if (user is null) {
    ctx.Db.user.Insert(new User { id = ctx.Sender, name = name });
  }
}

[Reducer]
public static void SendMessage(ReducerContext ctx, Identity to, string content) {
  ctx.Db.message.Insert(new Message {
    id = ctx.Db.message.Count + 1,
    sender = ctx.Sender,
    receiver = to,
    content = content,
    timestamp = ctx.Timestamp
  });
}

[Reducer]
public static void SetName(ReducerContext ctx, string name) {
  name = ValidateName(name);
  var user = ctx.Db.user.id.Find(ctx.Sender);
  if (user is not null) {
    user.name = name;
    ctx.Db.user.id.Update(user);
  }
}

private static string ValidateName(string name) {
  if (string.IsNullOrEmpty(name)) {
    throw new Exception("Names must not be empty");
  }
  return name;
}

Frontend Connection (React + TS)

const { getAccessTokenSilently } = useAuth0();
const token = await getAccessTokenSilently({
  authorizationParams: {
    audience: 'https://your-auth-audience-url'
  }
});

await spacetimeService.connectWithToken(token);
await spacetimeService.registerUser("DefaultName");

Now that the validation bug has been fixed upstream, integration with Auth0 works seamlessly out of the box.

Notes on Future Adoption and Stability

While SpacetimeDB is extremely promising, developers should be aware that the project is evolving rapidly and may introduce breaking API changes in upcoming releases. Especially as it moves toward production readiness, internal structures, SDK interfaces, and even WASM runtime behaviors may shift.

Despite its initial positioning for game development, SpacetimeDB has strong potential in niche, latency-sensitive backend use cases beyond gaming — such as collaborative editing, IoT coordination, real-time dashboards, or multiplayer educational platforms. Its unified DB+logic architecture can simplify traditionally complex system designs in these domains.

References & Further Reading

Conclusion

SpacetimeDB represents a fundamental shift—a backend engine and database merged into one, removing traditional server‑DB boundaries. For backend engineers, this means writing and deploying business logic inside the database itself via WASM reducers, unlocking ultra‑low latency and greatly simplified operations.

While the platform is young and subject to change, any team building real‑time, stateful, distributed applications should absolutely explore it. With commercial adoption (e.g., BitCraft) and growing community support, SpacetimeDB is poised to reshape backend design—and I’m excited to see where it goes next.