(D) Data Model
Data flow, state management, caching, and data synchronization patterns
The Data Model phase defines how data flows through your system, how it's stored, cached, and synchronized. This is where you make decisions about state management, data fetching, and persistence.
Why Data Model Matters
Good data modeling:
- Reduces redundant requests - Efficient caching and deduplication
- Improves UX - Fast, responsive interfaces
- Handles edge cases - Offline, sync, conflicts
- Scales efficiently - Optimized data flow
Key Data Model Decisions
1. Data Fetching Strategies
When to use each pattern:
Fetch-on-Render:
- Simple apps
- No caching needed
- Low traffic
Fetch-Then-Render:
- Parallel requests
- Better than sequential
- Still blocks on data
Render-as-You-Fetch:
- Progressive loading
- Best UX
- Complex implementation
Relevant Content:
- Data Fetching Strategies - Complete data fetching guide
- Parallel and Dependent Queries - Query coordination
- Request Deduplication - Prevent duplicate requests
- Caching Patterns - Cache strategies
- Optimistic Updates - Instant UI updates
- Prefetching Strategies - Preload data
- Pagination Strategies - Large datasets
- Polling and Real-Time Sync - Periodic updates
Decision Framework:
Use Fetch-on-Render if:
✅ Simple app
✅ No caching needed
✅ Low traffic
Use Fetch-Then-Render if:
✅ Parallel requests needed
✅ Better than sequential
✅ Can wait for all data
Use Render-as-You-Fetch if:
✅ Progressive loading
✅ Best UX required
✅ Complex app2. State Management
Global State Patterns:
Flux Architecture (Redux):
- Complex global state
- Time-travel debugging
- Predictable updates
- Large teams
Atom-Based State (Recoil, Jotai):
- Fine-grained reactivity
- Component-level state
- Performance optimization
- Simpler mental model
Signals:
- Maximum performance
- Fine-grained updates
- Reactive primitives
State Machines (XState):
- Complex workflows
- UI state machines
- Predictable transitions
Relevant Content:
- Flux Architecture - Redux patterns
- Atom-Based State - Recoil, Jotai
- Signals - Solid.js signals
- State Machines Advanced - XState patterns
- State and Logic Overview - Complete guide
Decision Framework:
Use Redux if:
✅ Complex global state
✅ Need debugging tools
✅ Large team
Use Recoil/Jotai if:
✅ Fine-grained reactivity
✅ Component-level state
✅ Simpler mental model
Use Signals if:
✅ Maximum performance
✅ Fine-grained updates
Use XState if:
✅ Complex workflows
✅ UI state machines3. State Persistence
When to persist:
- User preferences
- Form drafts
- Offline data
- Cache data
Storage Options:
LocalStorage:
- Simple key-value
- Synchronous API
- 5-10MB limit
- String only
IndexedDB:
- Complex data structures
- Large storage (GBs)
- Asynchronous API
- Structured data
SessionStorage:
- Tab-scoped
- Cleared on close
- Similar to LocalStorage
Relevant Content:
- Persistence Strategies - State persistence patterns
- State and Logic Overview - State management
Decision Framework:
Use LocalStorage if:
✅ Simple key-value
✅ Small data (< 5MB)
✅ String data
Use IndexedDB if:
✅ Complex structures
✅ Large data (GBs)
✅ Structured data
✅ Async operations4. State Synchronization
Cross-Tab Synchronization:
BroadcastChannel API:
- Simple cross-tab communication
- Browser-native
- Limited browser support
Storage Events:
- Listen to storage changes
- Cross-tab sync
- LocalStorage/SessionStorage only
Shared Web Workers:
- Complex synchronization
- Background processing
- Advanced use cases
Relevant Content:
- Sync Across Tabs - Cross-tab synchronization
- State and Logic Overview - State management
Decision Framework:
Use BroadcastChannel if:
✅ Simple sync needed
✅ Modern browsers
✅ Cross-tab communication
Use Storage Events if:
✅ LocalStorage sync
✅ Simple use cases
✅ Wide browser support5. Optimistic Updates
When to use:
- Instant feedback needed
- Network latency high
- User actions (likes, follows)
- Non-critical operations
Pattern:
- Update UI immediately
- Send request to server
- Replace with server response
- Rollback on error
Relevant Content:
- Optimistic Updates - Optimistic UI patterns
- Optimistic UI Patterns - Advanced optimistic updates
Decision Framework:
Use Optimistic Updates if:
✅ Instant feedback needed
✅ Non-critical operations
✅ Can rollback on error
✅ Good UX improvement
Avoid if:
❌ Critical operations (payments)
❌ Complex rollback logic
❌ Data consistency critical6. Undo/Redo
When to use:
- User actions need reversal
- Complex workflows
- Document editing
- Form interactions
Relevant Content:
- Undo/Redo Implementation - History management
Decision Framework:
Use Undo/Redo if:
✅ User actions reversible
✅ Complex workflows
✅ Document editing
✅ Form interactions7. Caching Strategies
Cache Patterns:
Memory Cache:
- Fast access
- Limited size
- Lost on refresh
SWR (Stale-While-Revalidate):
- Show cached, update in background
- Great UX
- Automatic revalidation
React Query:
- Powerful caching
- Request deduplication
- Background updates
- Optimistic updates
Normalized Cache:
- Single source of truth
- No duplication
- Complex relationships
Relevant Content:
- Caching Patterns - Cache strategies
- Data Fetching Strategies - Complete guide
Decision Framework:
Use Memory Cache if:
✅ Simple caching
✅ Small data
✅ Fast access needed
Use SWR if:
✅ Stale-while-revalidate
✅ Automatic revalidation
✅ Great UX
Use React Query if:
✅ Powerful caching
✅ Request deduplication
✅ Background updates
Use Normalized Cache if:
✅ Complex relationships
✅ Single source of truth
✅ No duplication8. File Handling
File Operations:
Upload:
- Chunked uploads
- Progress tracking
- Resume capability
- Error handling
Download:
- Streaming downloads
- Progress tracking
- Large files
Processing:
- Image compression
- File hashing
- Preview generation
Relevant Content:
- File Upload Architecture - File upload design
- Files and Binaries - File handling patterns
- File Chunking - Chunked uploads
- Image Compression - Image optimization
- File Hashing - File integrity
- File Preview Factory - Preview generation
Decision Framework:
Use Chunked Upload if:
✅ Large files (> 10MB)
✅ Resume capability
✅ Progress tracking
Use Streaming if:
✅ Large downloads
✅ Memory efficient
✅ Progress trackingData Model Checklist
Use this checklist when designing data flow:
Data Fetching
- Fetching strategy chosen
- Caching strategy defined
- Request deduplication implemented
- Error handling defined
State Management
- State management pattern chosen
- Global vs local state defined
- State persistence strategy
- State synchronization strategy
Caching
- Cache strategy chosen
- Cache invalidation defined
- Cache size limits
- Cache persistence
Optimistic Updates
- Optimistic updates needed?
- Rollback strategy defined
- Error handling
Persistence
- Persistence strategy chosen
- Storage mechanism (LocalStorage/IndexedDB)
- Data migration strategy
- Cleanup strategy
Synchronization
- Cross-tab sync needed?
- Sync strategy chosen
- Conflict resolution
Common Patterns
Simple App
Data Model:
- Fetch-on-render
- Local state only
- No persistence
- Basic error handlingMedium App
Data Model:
- React Query/SWR
- Global state (Redux/Recoil)
- LocalStorage persistence
- Optimistic updates
- Cross-tab syncComplex App
Data Model:
- Render-as-you-fetch
- Normalized cache
- Complex state management
- IndexedDB persistence
- Advanced sync
- Undo/redoTrade-offs
Redux vs Recoil
Redux:
- ✅ Predictable
- ✅ Time-travel debugging
- ✅ Large ecosystem
- ❌ Boilerplate
- ❌ Learning curve
Recoil:
- ✅ Fine-grained reactivity
- ✅ Simpler mental model
- ✅ Better performance
- ❌ Smaller ecosystem
- ❌ Newer technology
SWR vs React Query
SWR:
- ✅ Simpler API
- ✅ Smaller bundle
- ✅ Vercel-backed
- ❌ Less features
React Query:
- ✅ More features
- ✅ Better TypeScript
- ✅ More control
- ❌ Larger bundle
LocalStorage vs IndexedDB
LocalStorage:
- ✅ Simple API
- ✅ Synchronous
- ✅ Wide support
- ❌ Size limit
- ❌ String only
IndexedDB:
- ✅ Large storage
- ✅ Structured data
- ✅ Async operations
- ❌ Complex API
- ❌ Browser support
Next Steps
After defining data model, move to:
- Interface (I) - Design UI/UX
- Optimizations (O) - Improve performance
Remember: Good data modeling is invisible to users—they just see fast, responsive interfaces.