Offline First Collaboration
with Event Sourcing
Steven Chan - @stevnchan
Slide 2
Slide 2 text
GoodNotes
Slide 3
Slide 3 text
Syncing is hard
Slide 4
Slide 4 text
What we have tried
Slide 5
Slide 5 text
Apple CloudKit
• Remote database API
• Need to implement syncing with local cache
ourselves
• Designing a correct algorithm to sync two object
graphs is hard
• Limited schema migration support
• Undocumented limit for sharing records
Slide 6
Slide 6 text
Google Firebase
• Real-time database
• Mobile SDKs available
• Offline mode: store updates in a queue
• Performance become worse as the queue
become long
Slide 7
Slide 7 text
Event sourcing to
rescue
Slide 8
Slide 8 text
Event sourcing to rescue
1. Store all changes as events in a single queue
2. Only need to sync the event queue
3. Derive the app state from the event queue
4. Migration = rewrite the derivation function
Slide 9
Slide 9 text
Todo app example
1. {inserted, id123,
“Buy milk”}
2. {completed, id123}
3. {deleted, id123}
Syncing
• Server: maintain an event queue = the source of
truth
• Clients: upload local events to server, download
unseen events, and then update the app state.
• That’s it!
Slide 15
Slide 15 text
Syncing
A
B
C
A
B
C
D
E
F
Client Server
F D
E
Slide 16
Slide 16 text
Syncing
A
B
C
A
B
C
D
E
F
Client Server
F
D
E
Slide 17
Slide 17 text
Syncing
A
B
C
A
B
C
D
E
F
Client Server
F
D
E
Slide 18
Slide 18 text
Conflicts handling
• Pick the latest value by update time
• Pick the value with the largest update count
• Use vector clocks to detect conflicts