title: Explicit state over implicit sync type: concept created: 2026-04-24 updated: 2026-04-24 tags: [preferences, state-management, cross-platform, schema-design, sync, derivation-rules, explicit-state, predictability] sources: [2026-03-19-slack-how-slack-rebuilt-notifications] related: concepts/preference-schema-decoupling, concepts/cross-platform-preference-parity, concepts/mental-model-preference-coherence, concepts/read-time-preference-translation, systems/slack-notifications-2-0
Explicit state over implicit sync¶
Explicit state over implicit sync is the storage- schema discipline of representing cross-platform (or cross-client, or cross-device) state as independent explicit values per context, rather than one shared value plus a derivation-rule that clients apply to compute effective state.
Canonical framing from the 2026-03-19 How Slack Rebuilt Notifications post:
"Clarity beats cleverness. Removing the sync parameter and storing explicit desktop and mobile values made behavior predictable."
Slack is explicitly naming the cost of implicit sync
parameters as a storage anti-pattern: a sync flag + a
single value is compact, but clients must replicate the
derivation rule to compute what the user will actually
see. Every divergence in how that rule is implemented
across clients is a bug surface.
The anti-pattern: implicit sync¶
Typical shape of the anti-pattern:
pref: everything | mentions | nothing // shared
sync_mobile: true | false // "does mobile follow desktop?"
To determine mobile behavior, a client must:
1. Read pref (on desktop, in shared store).
2. Read sync_mobile (on desktop, in shared store).
3. Apply the derivation rule ("if sync_mobile then
mobile = pref else mobile = mobile_local").
4. Fall through to a local override if sync is off.
Every client must implement step 3 identically. Every future change to the derivation rule requires coordinated updates across all clients. Every cache layer must understand the rule or risk returning stale pre-derivation values. The derivation rule itself becomes load-bearing infrastructure — invisibly coupled to every client version, every sync protocol, every storage migration.
The preferred shape: explicit state¶
desktop: everything | mentions // what to do on desktop
mobile: everything | mentions | nothing // what to do on mobile
- Each platform has its own stored value.
- Clients read their own value and apply it.
- No derivation rule — the effective state is the stored state.
- Sync semantics (mobile-matches-desktop-by-default) are implemented at the write path: when the user changes the desktop value, the server/UI writes the same change to the mobile value unless the user has explicitly diverged.
The schema is wider; each client's code is simpler; reasoning about state is direct.
Write-path sync beats read-path derivation¶
The canonical implementation trade-off: sync at write, not at read.
- Write-path sync: when the user changes the desktop preference, the write call also updates the mobile preference (unless the user has explicitly opted out of the sync). Both values are stored explicitly.
- Read-path derivation: store one value + a sync flag, derive the mobile value at read time.
Write-path sync is preferred because:
- Predictability: every read returns the stored value; no client has to implement the rule.
- Caching simplicity: cache layers serve stored values; no rule-aware invalidation.
- Schema evolvability: adding a new platform means adding a new column, not extending a multi-client derivation rule.
- Cross-client consistency: no version-skew divergence in how clients interpret the derivation rule.
Override semantics are explicit¶
The one place implicit behavior remains is the intended default-sync behavior: when the user first sets a preference, does it apply to both platforms? Slack's answer: "Mobile should match desktop by default, with the option to override when needed." This is implemented as write-path sync — changing desktop also changes mobile until the user has diverged. The divergence itself is an explicit action (set mobile to a different value); once diverged, the system remembers the divergence.
Generalisation beyond preferences¶
The principle applies wherever cross-context state is stored:
- Cross-shard state in databases — explicit per-shard state + write-path reconciliation beats implicit global state + read-path resolution.
- Feature flags per client — explicit per-client evaluation state beats implicit "if user matches global rule and client matches client rule and..." derivations.
- User-profile settings — storing explicit
profile.work.timezoneandprofile.personal.timezonebeats oneprofile.timezonewith a sync-policy derivation.
Trade-offs¶
- Storage cost: schema is wider. For small preference sets (Slack's 3 columns), trivial; for large fan-outs (e.g. per-channel preferences across millions of channels per user), can be material.
- Write amplification: each write that should sync touches N rows instead of 1. For preferences, rare and small; for high-frequency state, can be load-bearing.
- Default-management complexity: the system must remember whether a divergence was explicit or residual, to know when future global changes should propagate.
For user-visible preferences — low write frequency, high read frequency, high stakes for predictability — the explicit-state trade is almost always right.
Seen in¶
- systems/slack-notifications-2-0 — canonical
instance. Legacy
syncparameter removed;desktopandmobileare independent stored values. Write-path sync is implicit in the UI (mobile-matches-desktop by default) but the storage is explicit.
Related¶
- concepts/preference-schema-decoupling — the companion schema-axis discipline.
- concepts/cross-platform-preference-parity — the user-facing property this discipline enables.
- concepts/mental-model-preference-coherence — the user-side justification.
- concepts/read-time-preference-translation — the migration mechanism that lets you move an existing schema from implicit-sync to explicit-state without disrupting users.