IDC

Community

Databases that push messages to each other, with no polling: a transactional outbox, signed delivery that retries until it lands, and exactly-once apply on the other side. Rust and C# speak it too.

  • TypeScript
npm i @pogly/spacetimedb-idc

This module adds reliable, event-driven messaging between separate SpacetimeDB databases, filling the gap until the platform ships native inter-database communication. It sits inside each participating database and handles sending, receiving, retrying, and deduplicating messages so that changes in one database can trigger reactions in another without polling.

  • Sharded game worlds: a player character crossing from one world shard to another needs to transfer ownership atomically, with no risk of duplication or loss during a crash.
  • Microservice-style backends: an order database and an inventory database need to stay in sync in real time, with each side reacting to the other's changes as events rather than on a polling schedule.
  • Collaborative multi-tenant apps: a front-end database and a backend processing database need to exchange work items reliably, with guaranteed exactly-once application of each message.
  • Live data mirroring: one database maintains a local mirror of a subset of another database's state, updated automatically whenever the source changes.
  • Auction or marketplace systems: items or bids must move between databases with a clear ownership handoff, where the item is live in exactly one place at all times.

When a database wants to send a message to a peer, it records the message in a local outbox table as part of the same transaction that makes the underlying change. This means the message and the change are always consistent: either both exist or neither does. A scheduled background task then picks up pending outbox entries and delivers them to the peer over HTTP, retrying with increasing delays if the peer is unavailable, and stopping only once the peer confirms the message was durably applied.

On the receiving side, each incoming message is checked against a record of already-applied message identifiers before anything is written. Because that check and the resulting change happen in the same transaction, a message that arrives more than once (due to a retry) has its effect applied exactly once. The receiving database can also queue reply messages in that same transaction, making the communication fully event-driven in both directions with no timers running during normal operation.

For cases where an entity must live in exactly one database at a time, the module provides a structured ownership handoff. The source database locks the entity, offers it to the destination, waits for acceptance, deletes its own copy, and only then signals the destination to make the entity live. Every step is a single local transaction plus a durable message, so a crash at any point simply resumes from where it left off rather than leaving a duplicate or a gap.

Related modules

Webhooks

Verified inbound webhooks (GitHub, Twitch EventSub, Stripe, Discord, Standard Webhooks) handled exactly once, and signed outbound webhooks from a transactional outbox with retries.

Lethalchip0/wk

Authz

Roles, scopes and grants for multi-user modules: wildcard permissions, role inheritance, scope trees, expiring grants, invite links, an audit log and row-level security, with no privilege escalation.

Lethalchip0/wk

Cron

Schedules recurring tasks in a SpacetimeDB module using calendar expressions or fixed intervals. Supports time zones, per-job arguments, failure limits, and runtime schedule changes.

SpacetimeDB0/wk
Submodule

Edit details

One short paragraph describing the module.

A few bullets for scenarios where this is a good fit.

A few short paragraphs at the conceptual level.