---
title: "Deploy SpacetimeDB"
description: "Database that runs your app's logic and streams live query results"
category: "Other"
url: https://railway.com/deploy/spacetimedb-server
---

# Deploy SpacetimeDB

Database that runs your app's logic and streams live query results

**[Deploy SpacetimeDB on Railway](https://railway.com/template/spacetimedb-server)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/spacetimedb-server/manifest.json

- **Creator:** A3A
- **Category:** Other

## Template content

### gateway https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/caddy.svg

- **Source:** https://github.com/gridalpha/spacetimedb-railway
- **Health check:** /healthz
- **Public domain:** Yes

### spacetimedb https://raw.githubusercontent.com/clockworklabs/SpacetimeDB/master/docs/static/images/icons/spacetimedb-icon.svg

- **Source:** https://github.com/gridalpha/spacetimedb-railway
- **Health check:** /v1/health

## Documentation

# Deploy and Host SpacetimeDB on Railway

SpacetimeDB is a relational database that runs your application's logic inside the database itself. Instead of a database, a backend and a socket layer, you publish one *module* — tables and reducer functions compiled to WebAssembly from Rust, C#, TypeScript or C++ — and clients connect straight to it over a WebSocket, subscribing to SQL queries that push updates as rows change.

Deploy SpacetimeDB on Railway with this template and you get a `spacetimedb` service running the standalone node from the official `clockworklabs/spacetime` image, its commitlog and JWT signing keys on a volume at `/stdb`, behind a Caddy `gateway`. The gateway matters: a bare node authenticates nobody, so anyone who found the URL could publish a module onto it. It publishes only what clients need — identity issuance, the subscription WebSocket, module HTTP handlers, read-only schema lookups — and serves the full API under a private admin path only you know. Source: [github.com/gridalpha/spacetimedb-railway](https://github.com/gridalpha/spacetimedb-railway).

![The public Caddy gateway in front of the private SpacetimeDB node and its volume](https://res.cloudinary.com/rroe4rtk/image/upload/v1788777721/spacetimedb-architecture.png)

## Getting Started with SpacetimeDB on Railway

SpacetimeDB has no web console — you drive it with the `spacetime` CLI from [spacetimedb.com/install](https://spacetimedb.com/install). Once the deploy is live, copy the `gateway` service's public domain and read `STDB_ADMIN_PATH` from its variables; that is the prefix your admin URL is built from:

```
spacetime server add --url https:/// railway
spacetime server ping railway
```

`spacetime init` scaffolds a `person` table with `add` and `say_hello` reducers — enough to prove the whole path:

```
spacetime init --lang rust my-app &amp;&amp; cd my-app
spacetime publish --server railway my-app
spacetime call --server railway my-app add "Ada Lovelace"
spacetime sql --server railway my-app "SELECT * FROM person"
```

If the query returns the row you inserted, the deployment works. Clients then connect to the plain public domain with no admin path and no credential. `https:///v1/health` returns `200` in a browser; any administrative path returns a JSON `403`.

![Schema of a published SpacetimeDB module showing its public person table](https://res.cloudinary.com/rroe4rtk/image/upload/v1788777723/spacetimedb-module-schema.png)

![The gateway refusing an administrative route on the public surface](https://res.cloudinary.com/rroe4rtk/image/upload/v1788777724/spacetimedb-gateway-policy.png)

## About Hosting SpacetimeDB

Conventional realtime stacks put a database, a stateless API and a WebSocket fan-out layer in a row, and most of the code and latency is the plumbing between them. SpacetimeDB removes the middle: reducers run inside the database as serialisable transactions, and each subscription is a live SQL query pushed on commit.

- **Modules in Rust, C#, TypeScript or C++**, compiled to WebAssembly and published in one command
- **Live subscriptions** — clients subscribe to `SELECT` queries and get row deltas over a WebSocket
- **Reducers as the only write path**, each one ACID transaction with the caller in `ctx.sender`
- **Row-level security**, and built-in identity that OIDC providers such as Auth0 or Clerk can extend
- **Client SDKs** for Rust, C#, TypeScript, Unity and Unreal, generated from your schema

Self-host it when the data must sit on infrastructure you control, when a game server must sit near your players, or when a container costs less than metered capacity.

## Why Deploy SpacetimeDB on Railway

- No Dockerfile, volume permissions or proxy config to write yourself
- The administrative API is gated by default rather than open to the internet
- Private networking between gateway and database, with one public service
- Managed TLS, custom domains and one-click redeploys from Git
- The volume keeps databases and identity signing keys across deploys

## Common Use Cases

- **Multiplayer game backends** needing authoritative world state at low latency, with no game server to operate
- **Collaborative apps** — whiteboards, editors, planning tools — where people mutate the same documents and see each other's changes at once
- **Live dashboards** driven by subscriptions, not polling
- **Simulations** whose tick loop belongs beside the data

## Dependencies for SpacetimeDB

- **`spacetimedb`** — the standalone node, from `clockworklabs/spacetime:latest` (2.10.0 at time of writing). Private, port 3000, with a volume at `/stdb` holding the commitlog, control database and JWT keypair.
- **`gateway`** — Caddy, from `caddy:2-alpine`, the only public service. It decides which routes are anonymous and tunnels the full API under `STDB_ADMIN_PATH`.

No external database, cache or object store: SpacetimeDB is the database.

### Environment Variables Reference

| Variable | Description | Required |
|---|---|---|
| `STDB_ADMIN_PATH` | Secret path prefix the full API is served under. Generated for you | Yes |
| `STDB_PUBLIC_HTTP_CALL` | Publish `/v1/database//call/` anonymously. Default `false` | No |
| `STDB_PUBLIC_HTTP_SQL` | Publish `/v1/database//sql` anonymously. Default `false` | No |
| `STDB_LOG_LEVEL` | Server log level. Default `info` | No |
| `STDB_MODULE_HTTP` | Whether modules may make outbound HTTP requests. Default `true` | No |
| `STDB_PAGE_POOL_MAX_SIZE` | Page pool ceiling in bytes. Unset means half the memory limit | No |
| `PORT` | Port the node listens on. Default `3000` | No |

### Deployment Dependencies

- [github.com/gridalpha/spacetimedb-railway](https://github.com/gridalpha/spacetimedb-railway) · upstream [clockworklabs/SpacetimeDB](https://github.com/clockworklabs/SpacetimeDB) · image `clockworklabs/spacetime` · [docs](https://spacetimedb.com/docs)
- Publishing needs the `spacetime` CLI plus your language's toolchain — Rust with the `wasm32-unknown-unknown` target, .NET 8, or Node for TypeScript.

## Server Requirements to Self-Host SpacetimeDB

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2–4 vCPU |
| RAM | 1 GB | 4 GB or more |
| Storage | 5 GB volume | 20 GB+, sized to the commitlog |
| Runtime | Linux container, x86-64 or arm64 | — |

Hot table data is kept in memory and every transaction appended to a commitlog, so RAM should exceed your working set and storage grows with write volume, not row count. The page pool defaults to 8 GB upstream; this template caps it at half the memory limit. Raise the volume before it fills — a full commitlog refuses writes.

## Self-Hosting SpacetimeDB Outside Railway

The published image runs the server directly. Give it a volume and a JWT key directory, and keep both across restarts or every identity token you issued becomes invalid:

```
docker run -d --name spacetimedb -p 3000:3000 -v stdb:/stdb \
  -e SPACETIMEDB_DISABLE_DISK_LOGGING=1 \
  --entrypoint /opt/spacetime/spacetimedb-standalone \
  clockworklabs/spacetime:latest start --data-dir /stdb/data \
  --jwt-pub-key-path /stdb/keys/id_ecdsa.pub \
  --jwt-priv-key-path /stdb/keys/id_ecdsa \
  --listen-addr 0.0.0.0:3000 --non-interactive
```

The image runs as the unprivileged `spacetime` user, so `/stdb` must be writable by it. On Linux, `curl -sSf https://install.spacetimedb.com | sh` installs the server without Docker. Either way, never expose port 3000 on its own — front it with a reverse proxy that blocks database creation, as upstream's self-hosting guide describes.

## How Much Does SpacetimeDB Cost?

SpacetimeDB is published under the Business Source License 1.1, converting to AGPL v3 with a linking exception in 2031. Its Additional Use Grant allows free production use of a single instance provided you are not reselling it as a database service — exactly what this template deploys — so there is no licence fee and no seat count. On Railway you pay only for the compute, memory and volume the two services use. Clockwork Labs also runs Maincloud, a managed option with a free tier and a Pro plan from $25/month.

## FAQ

**What is SpacetimeDB?**
A relational database that also runs your application code. You publish a WebAssembly module of tables and reducers, and clients connect to the database over a WebSocket rather than to a backend server.

**What does this Railway template deploy?**
A private SpacetimeDB standalone node with a persistent volume, and a public Caddy gateway that publishes the client routes and keeps the admin API behind a secret path.

**Why does the template include a gateway instead of exposing SpacetimeDB directly?**
A standalone node performs no server-level authentication — database creation is open to any caller, so a bare public URL lets strangers run their own modules on it. Upstream's self-hosting guide recommends this reverse-proxy allow-list; the template ships it configured.

**How do I publish a module to my self-hosted SpacetimeDB on Railway?**
`spacetime server add --url https:/// railway`, then `spacetime publish --server railway ` from the module directory. Re-running it updates.

**Can my game clients connect without the admin path?**
Yes, and they should. The subscription WebSocket, identity issuance and schema lookups are open on the plain public domain — point your SDK at `https://`, no secret needed.

**Will my data survive a redeploy?**
Yes. Databases, the commitlog and the JWT signing keypair live on the volume at `/stdb`, so identities already issued to clients keep working after the container is recreated.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/spacetimedb-server
