Tables
Tables are the way to store data in SpacetimeDB. All data in SpacetimeDB is stored in memory for extremely low latency and high throughput access. SpacetimeDB also automatically persists all data to disk.
Why Tables
Tables are the fundamental unit of data organization in SpacetimeDB, just as files are the fundamental unit in Unix. However, tables possess greater generality than files. Unix requires a separate filesystem concept to organize and describe files. SpacetimeDB, by contrast, describes itself: it stores the representation of tables and their schemas in tables called system tables (such as st_table and st_column).
You can query these system tables directly:
SELECT * FROM st_table;
SELECT * FROM st_column;
You can query system tables, but you should not modify them directly. Make schema changes through the normal definition mechanisms in your module code.
Tables and Data-Oriented Design
The relational model underlying tables represents the logical endpoint of data-oriented design. Patterns such as Entity Component Systems (ECS) implement a strict subset of relational capabilities. Tables give you the full power of relational theory: over fifty years of proven techniques for organizing and querying data efficiently.
The central principle of data-oriented design holds that the purpose of any program is to transform data from one form to another. Tables provide a principled, universal representation for that data, giving you:
- Efficient access patterns through indexes
- Data integrity through constraints
- Flexible queries through relational operations
- Real-time synchronization through subscriptions
For further discussion of this philosophy, see The Zen of SpacetimeDB.
Physical and Logical Independence
A core goal of the relational model is separating logical access patterns from physical data representation. When you write a subscription query, you express what data you need, not how the database should retrieve it. This separation allows SpacetimeDB to change the physical representation of your data for performance reasons without requiring you to rewrite your queries.
The clearest example is indexing. When you add an index to a column, you change how SpacetimeDB physically organizes that data. It builds an additional data structure to accelerate lookups. But your subscription queries continue to work unchanged. The same query that previously scanned the entire table now uses the index automatically. You improve performance by modifying the schema, not the queries.
This independence extends beyond indexes. SpacetimeDB can change internal storage formats, memory layouts, and access algorithms across versions. Your queries remain stable because they operate at the logical level (rows and columns) rather than the physical level of bytes and pointers.
Table Decomposition
A common concern when designing relational schemas is whether to consolidate data into fewer large tables or distribute it across many smaller ones. In traditional SQL databases, joins require verbose query syntax and incur significant execution cost. This friction pushes developers toward denormalized schemas with fewer, wider tables.
SpacetimeDB operates under different constraints. Your reducers interact with tables through programmatic APIs rather than SQL strings. A join operation reduces to an index lookup: you retrieve a row from one table, extract a key value, and use that key to find related rows in another table. With all data resident in memory, these lookups often complete in nanoseconds.
Consider the following schema for a game application:
Consolidated approach (not recommended):
Player
├── id
├── name
├── position_x, position_y, velocity_x, velocity_y (updates: 60Hz)
├── health, max_health, mana, max_mana (updates: occasional)