Skip to content

Design Discord's Message Storage, stage 5 of 9: break it

The message with no author

In this store, UPDATE and INSERT are both upserts: they write the given columns with a timestamp. Conflicts are resolved per column by last write wins.

System so far· 5 parts
12345CLIENTMembersSERVICEAPI serversSERVICEGatewaySERVICEMessagedata serviceDATABASEMessage cluster

Select a component to see what it is responsible for and which state it owns.

  1. 1Members → API servers: Send, load history, jump
  2. 2API servers → Gateway: New message event
  3. 3Gateway → Members: Push to online members
  4. 4API servers → Message data service: Query by channel (hash-routed)
  5. 5Message data service → Message cluster: Read and write one partition
  • Request / response
  • Asynchronous
  • Server push

What you need to know

0 of 2 checks done
  1. In this store, writes are blind upserts: an UPDATE doesn't check whether the row exists; it just writes the given columns with a timestamp. Conflicts are resolved per column by last write wins (LWW): each cell keeps its newest value. See Conflict resolution and convergence.

    A row is a collection of cells, not a single value.

  2. Think first

    A delete at time T1 writes a tombstone for the row. An edit at T2 > T1 writes the body and edited_at columns. What does a reader see?