ServerlessIRCd Docs

Docs home

ADR-002: Location-of-authority state split

Date: 2025-01-15 (Phase 1) Status: Accepted Supersedes: — Superseded by: —

Context

An IRC server manages several kinds of state: connection records (nick, caps, away status), channel rosters (who is in #foo, with what prefix), channel metadata (topic, modes, ban lists), and the nick registry (nick → connection map). In a single-process ircd all of this lives in one address space, so read-modify-write races are handled with locks or a single event loop.

ServerlessIRCd runs on stateless-per-request compute (Lambda) or per-entity-isolated compute (Durable Objects). There is no global lock. If two connections race to JOIN the same channel, or two clients race to claim the same nick, the outcome must still be correct. Traditional locking is impossible across instances.

Decision

Each piece of state has exactly one authority — the single entity that owns the canonical copy and serializes all mutations to it. Reducers are routed to the authority that owns the state they mutate:

Command family Authority Primary state
Registration (NICK/USER/PASS) Connection entity ConnectionState
PING/PONG, QUIT, AWAY, user MODE Connection entity ConnectionState
JOIN/PART/channel MODE/TOPIC/KICK/INVITE Channel entity ChannelState + roster
PRIVMSG/NOTICE to channel Channel entity Fanout (reads roster)
PRIVMSG/NOTICE to user Sender Connection Nick → Connection route
Nick reservation Registry entity Nick → Connection map

Cross-authority coordination is done via effects, not direct mutation. When a connection accepts a JOIN, the connection-authority reducer emits an ApplyChannelDelta effect that the channel authority consumes. The channel authority is the sole writer of its roster; the connection never touches it directly.

Platform mapping:

Consequences

Positive:

Negative:

References