Mobile System Design
Design mobile-first systems with offline capabilities.
Mobile System Design
Learn to design mobile-first systems that work seamlessly across different devices and network conditions.
What You'll Learn
- Mobile-First Architecture: Design for mobile constraints
- Offline-First Design: Handle network connectivity issues
- Data Synchronization: Keep data consistent across devices
- Push Notifications: Real-time communication strategies
- Performance Optimization: Minimize battery and data usage
- Cross-Platform Considerations: iOS, Android, and web compatibility
Preview Chapter: Offline-First Mobile App
Design a note-taking app that works seamlessly offline and syncs when connectivity is restored.
Mobile-Specific Challenges
Network Connectivity:
- Intermittent connectivity
- Slow networks (2G/3G)
- Data usage concerns
- Battery optimization
Device Constraints:
- Limited storage space
- Battery life considerations
- Screen size variations
- Platform differences
User Expectations:
- Instant responsiveness
- Offline functionality
- Seamless sync
- Cross-device consistency
Offline-First Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Mobile App │ │ Sync Service │ │ Backend API │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Local DB │ │◄──►│ │ Sync Queue │ │◄──►│ │ Main DB │ │
│ │ (SQLite) │ │ │ │ │ │ │ │ │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Conflict │ │ │ │ Retry Logic │ │ │ │ Version │ │
│ │ Resolution │ │ │ │ │ │ │ │ Control │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Data Synchronization Strategy
1. Local-First Storage:
-- Local SQLite Schema
CREATE TABLE notes (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
created_at INTEGER,
updated_at INTEGER,
sync_status TEXT DEFAULT 'pending',
server_version INTEGER DEFAULT 0
);
CREATE TABLE sync_queue (
id INTEGER PRIMARY KEY,
operation TEXT NOT NULL, -- 'create', 'update', 'delete'
entity_type TEXT NOT NULL,
entity_id TEXT NOT NULL,
data TEXT NOT NULL,
created_at INTEGER,
retry_count INTEGER DEFAULT 0
);
2. Conflict Resolution:
function resolveConflict(localNote, serverNote) {
// Last-write-wins with timestamp comparison
if (localNote.updated_at > serverNote.updated_at) {
return {
...localNote,
server_version: serverNote.server_version + 1,
sync_status: 'pending'
};
} else {
return {
...serverNote,
sync_status: 'synced'
};
}
}
3. Sync Algorithm:
async function syncNotes() {
const pendingNotes = await getPendingNotes();
const serverNotes = await fetchServerNotes();
for (const localNote of pendingNotes) {
const serverNote = serverNotes.find(n => n.id === localNote.id);
if (serverNote) {
// Conflict resolution
const resolvedNote = resolveConflict(localNote, serverNote);
await updateLocalNote(resolvedNote);
} else {
// Upload new note
await uploadNote(localNote);
}
}
// Download new notes from server
const newServerNotes = serverNotes.filter(serverNote =>
!pendingNotes.some(localNote => localNote.id === serverNote.id)
);
for (const serverNote of newServerNotes) {
await saveLocalNote(serverNote);
}
}
Push Notification Strategy
Real-time Updates:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Server │───▶│ Push Service│───▶│ Mobile │
│ │ │ (FCM/APNs) │ │ App │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ WebSocket │ │ Message │ │ Background │
│ Connection │ │ Queue │ │ Processing │
└─────────────┘ └─────────────┘ └─────────────┘
Notification Types:
- Data sync notifications: Trigger background sync
- Real-time collaboration: Show live updates
- System notifications: App updates, maintenance
- User notifications: Comments, mentions, shares
Performance Optimization
1. Lazy Loading:
// Load notes in batches
async function loadNotes(offset = 0, limit = 20) {
const notes = await db.query(`
SELECT * FROM notes
ORDER BY updated_at DESC
LIMIT ? OFFSET ?
`, [limit, offset]);
return notes;
}
2. Image Optimization:
// Compress images before upload
function compressImage(file, maxWidth = 800, quality = 0.8) {
return new Promise((resolve) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
const ratio = Math.min(maxWidth / img.width, maxWidth / img.height);
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob(resolve, 'image/jpeg', quality);
};
img.src = URL.createObjectURL(file);
});
}
3. Background Sync:
// Service Worker for background sync
self.addEventListener('sync', (event) => {
if (event.tag === 'notes-sync') {
event.waitUntil(syncNotes());
}
});
Course Structure
1. Mobile-First Architecture (45 minutes)
- Design principles
- Platform considerations
- Performance constraints
- User experience patterns
2. Offline-First Design (45 minutes)
- Local storage strategies
- Data synchronization
- Conflict resolution
- Network state management
3. Real-time Features (45 minutes)
- Push notifications
- WebSocket connections
- Live collaboration
- Background processing
4. Performance Optimization (45 minutes)
- Lazy loading
- Caching strategies
- Image optimization
- Battery efficiency
Design Patterns
1. Repository Pattern:
class NotesRepository {
async getNotes() {
// Try local first, then sync if needed
const localNotes = await this.localDB.getNotes();
if (this.shouldSync()) {
await this.syncWithServer();
return await this.localDB.getNotes();
}
return localNotes;
}
}
2. Observer Pattern:
class SyncManager {
constructor() {
this.observers = [];
}
subscribe(observer) {
this.observers.push(observer);
}
notifySyncStatus(status) {
this.observers.forEach(observer => observer(status));
}
}
3. Strategy Pattern:
class SyncStrategy {
constructor(strategy) {
this.strategy = strategy;
}
async sync() {
return await this.strategy.execute();
}
}
class OnlineSyncStrategy {
async execute() {
// Full sync with server
}
}
class OfflineSyncStrategy {
async execute() {
// Queue for later sync
}
}
Common Interview Questions
1. How would you design a mobile app that works offline?
2. How do you handle data synchronization conflicts?
3. What strategies would you use to minimize battery usage?
4. How would you implement real-time collaboration?
5. How do you handle different screen sizes and orientations?
What's Next
After mastering mobile system design, you'll be able to create apps that work seamlessly across all devices and network conditions. You'll understand the unique challenges of mobile development and how to design systems that provide excellent user experiences regardless of connectivity.
Mobile System Design
Design mobile-first systems with offline capabilities.