Skip to content

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.timezone and profile.personal.timezone beats one profile.timezone with 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 sync parameter removed; desktop and mobile are independent stored values. Write-path sync is implicit in the UI (mobile-matches-desktop by default) but the storage is explicit.
Last updated · 470 distilled / 1,213 read