Skip to content

ADR-007: Tiered Offline Framework

Tiered Offline Framework

A pragmatic, incremental approach to offline support with four tiers of capability.

Mobile applications frequently encounter unreliable network conditions. Without a structured approach to offline support, teams either:

  • Build no offline support (poor UX in low-connectivity environments)
  • Over-engineer full offline sync (expensive and complex for most features)
  • Implement ad-hoc solutions per feature (inconsistent, hard to maintain)
  • When: Establishing offline capability standards for MOFA-based apps
  • Where: Mobile Flutter applications deployed in varied network environments
  • Who: Flutter development teams building production apps
  • Constraints:
    • Not all features need offline support
    • Full offline sync is expensive to implement and maintain
    • Teams need clear guidance on what level of offline support to implement
    • Ferry’s built-in cache provides a natural foundation for read-only offline

Adopt a four-tier offline framework where each feature explicitly declares its offline capability tier. Each tier builds on the previous one.

TierNameCapabilityComplexity
Tier 0Online-onlyNo offline supportNone
Tier 1Read cache fallbackServe stale cached data when offlineLow
Tier 2Offline write queueQueue mutations, sync when onlineMedium
Tier 3Full syncBidirectional sync with conflict resolutionHigh
  • Pragmatic: Most features only need Tier 0 or Tier 1
  • Incremental: Teams can upgrade a feature’s tier as requirements evolve
  • Clear decision criteria: Per-feature decision, not all-or-nothing
  • Leverages existing infrastructure: Ferry cache provides Tier 1 for free
  1. No Offline Framework: Each team decides independently -> Inconsistent, duplicated effort
  2. Mandatory Full Offline: All features must support Tier 3 -> Over-engineering, slow development
  3. Tiered Framework (Chosen): Explicit per-feature decision with clear implementation guides
  • Behavior: Shows error state when offline. No cached data served.
  • Implementation: Default behavior - no additional code needed.
  • Use when: Feature data is highly volatile or requires real-time accuracy (e.g., live voting, real-time dashboards).
  • Behavior: When offline, serves the last successfully fetched data from Ferry’s cache. Shows a “stale data” indicator.
  • Implementation: Ferry’s cache provides this automatically. Add connectivity awareness to show stale indicators.
  • Use when: Feature benefits from showing recent data (e.g., event schedule, attendee list, notification history).
  • Behavior: Tier 1 + mutations are queued locally when offline and synced when connectivity returns.
  • Implementation: Requires a local queue (caching service), background sync service, and conflict detection.
  • Use when: Users need to perform actions offline (e.g., mark attendance, submit forms, send messages).
  • Behavior: Tier 2 + bidirectional sync with conflict resolution. Local data model mirrors server state.
  • Implementation: Requires local database, sync engine, conflict resolution strategy, and version tracking.
  • Use when: App must function fully offline for extended periods (e.g., field work apps, offline-first experiences).
  • Clear decision framework for offline support per feature
  • Reduced over-engineering - most features stay at Tier 0 or 1
  • Incremental adoption - upgrade tiers as needed
  • Consistent patterns across projects
  • Tier assignment requires discipline - teams must explicitly decide per feature
  • Tier 2-3 are complex - requires additional infrastructure (queue, sync engine)
  • Offline Tiers Reference - Detailed implementation reference
  • Offline Setup Guide - How to configure each tier
  • Caching Service Patterns - Foundation for Tier 1-3 (see .claude/skills/code-architecture/architecture/caching-and-offline.md)