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
Select a component to see what it is responsible for and which state it owns.
- 1Members → API servers: Send, load history, jump
- 2API servers → Gateway: New message event
- 3Gateway → Members: Push to online members
- 4API servers → Message data service: Query by channel (hash-routed)
- 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
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.
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?Check
The race is rare. What's the cheaper fix?