P2P Distributed Databases for Mobile: Complete Guide¶
A comprehensive overview of decentralized, peer-to-peer database solutions for building offline-first mobile applications.
Table of Contents¶
- Introduction
- P2P Database Fundamentals
- Major P2P Database Projects
- Feature Comparison Matrix
- Architecture Patterns
- Sync Mechanisms
- Conflict Resolution
- Use Cases by Industry
- Implementation Guide
- Resources
Introduction¶
Why P2P Databases Matter¶
Traditional client-server databases rely on a centralized authority. P2P databases eliminate this dependency:
- Offline-first: Apps work without internet connectivity
- Decentralized: No single point of failure
- Low latency: Local-first operations feel instant
- Privacy: Data can stay on user devices
- Resilience: Network partitions don't break functionality
The P2P Spectrum¶
Centralized (Traditional DB)
↓
Local-first (RxDB, WatermelonDB)
↓
P2P with optional backend (Ditto, ObjectBox)
↓
Pure P2P Mesh (GunDB, OrbitDB)
↓
Fully Decentralized (Blockchain-based)
Different projects occupy different points on this spectrum.
P2P Database Fundamentals¶
Core Concepts¶
1. Local-First¶
Data is stored locally first. Sync happens asynchronously and opportunistically.
Benefits: - Instant reads (microseconds) - Works offline - Battery efficient - Better UX
2. Eventual Consistency¶
All nodes eventually contain the same data, but there's a period where they may differ.
Trade-off: Consistency vs. Availability
3. Conflict Resolution¶
When two users edit the same data offline and both sync, how are conflicts resolved?
Strategies: - Last-write-wins: Simpler, may lose data - CRDTs: Mathematically merge changes - Custom resolution: App-specific logic
4. Merkle Trees¶
Hash-based data structures that enable efficient sync—only changed portions are transmitted.
5. CRDTs (Conflict-Free Replicated Data Types)¶
Data structures that can be independently modified on different nodes and automatically merged:
CRDT Examples:
- Text editing (Operational Transform, Yjs)
- Counters (naturally mergeable)
- Sets (track adds and removes separately)
- Maps (last-write-wins per key)
Major P2P Database Projects¶
1. Ditto ⭐ (Best for Mobile)¶
Type: Commercial P2P mesh database
What It Does¶
Edge-native database with automatic P2P mesh networking via Bluetooth, Wi-Fi, and LAN.
Architecture¶
Device A ←→ (Bluetooth) ←→ Device B
↓ ↓
[Local DB] [Local DB]
↓ ↓
Both ←→ (Wi-Fi) ←→ Cloud (optional)
Key Features¶
- Mesh Networking: Bluetooth, BLE, LAN, P2P Wi-Fi automatic detection
- Built-in Sync: CRDT-based conflict resolution
- Cross-platform: iOS, Android, IoT, server
- Zero Cloud Dependency: Works completely offline
- Data Integrity: Preserves all changes even during simultaneous edits
Code Example¶
// iOS
import Ditto
let ditto = Ditto()
try ditto.startSync()
// Create/read data
var tasks: [Task] = []
let subscription = ditto.store
.collection("tasks")
.findAll()
.subscribe { result in
tasks = result
}
Strengths¶
- Purpose-built for mobile P2P
- Automatic mesh discovery
- CRDT conflicts resolved automatically
- Works over multiple transports
- MongoDB Connector available
Weaknesses¶
- Commercial product (free tier available)
- Smaller community than open-source alternatives
- Opinionated architecture (less flexible customization)
Use Cases¶
- Field Service: Technicians sync data without central server
- Healthcare: Patient data syncs across devices offline
- Delivery/Logistics: Fleet coordination with spotty connectivity
- Aerospace/Defense: Classified data stays on-device
Pricing¶
- Free tier for development
- Pay-per-device for production (contact for details)
2. OrbitDB (Best for IPFS Ecosystem)¶
Type: Open-source P2P database built on IPFS
What It Does¶
Serverless, distributed database using IPFS for storage and Libp2p for peer communication.
Architecture¶
Browser A Browser B Browser C
↓ ↓ ↓
OrbitDB OrbitDB OrbitDB
↓ ↓ ↓
← IPFS Network (globally distributed) →
Key Features¶
- Merkle-CRDTs: Conflict-free writes and merges
- Multiple Database Types:
- Events log (append-only)
- Documents (JSON with key indexing)
- Key-value (like Redis)
- Full Decentralization: No servers required
- Verifiable: All operations cryptographically signed
Code Example¶
import OrbitDB from '@orbitdb/core'
import IPFS from 'ipfs'
const ipfs = await IPFS.create()
const orbitdb = await OrbitDB.create({ ipfs })
// Create a database
const db = await orbitdb.open('my-database', { type: 'events' })
// Add events
await db.add({ text: 'Hello P2P!' })
// Subscribe to changes
const all = await db.all()
db.events.on('join', (peer) => console.log('Peer joined:', peer))
Strengths¶
- Truly decentralized (no servers needed)
- IPFS ecosystem integration
- Open-source (Apache 2.0)
- Verifiable operations
- Works in browser and Node.js
Weaknesses¶
- IPFS overhead (storage/bandwidth)
- Smaller community (specific to IPFS)
- Complex to understand initially
- Desktop/browser focused, limited mobile
- No official mobile SDK
Use Cases¶
- Decentralized Social Networks: No central authority needed
- Web3 Applications: DApps requiring data persistence
- Censorship-resistant Apps: Data can't be remotely deleted
- Collaborative Tools: Like Google Docs but decentralized
Pricing¶
Free and open-source
3. GunDB (Best for True P2P)¶
Type: Open-source decentralized graph database
What It Does¶
Real-time, offline-first, fully decentralized database that works peer-to-peer without mandatory servers.
Architecture¶
Key Features¶
- Graph Database: Relationship-focused (not just key-value)
- WebRTC + WebSocket: P2P over browser and Node.js
- SEA Encryption: Built-in end-to-end encryption
- No Master Server Required: Works as pure mesh
- Automatic Replication: All peers replicate all data they're subscribed to
Code Example¶
import Gun from 'gun'
const gun = Gun()
// Store data
gun.get('user').get('alice').put({
name: 'Alice',
status: 'online'
})
// Real-time subscriptions
gun.get('user').map().on((data, key) => {
console.log(`${key}:`, data)
})
// Encryption example (SEA)
const user = Gun.SEA.pair()
Strengths¶
- True peer-to-peer (no servers required)
- Graph data model (flexible)
- End-to-end encryption built-in
- Real-time collaboration
- Open-source with active community
- Powers production apps (Internet Archive, HackerNoon)
Weaknesses¶
- JavaScript/Node.js only (no native mobile SDKs)
- Complex codebase (harder to extend)
- Learning curve steeper than SQL/document DBs
- Limited query capabilities
- Relay servers become bottlenecks at scale
Use Cases¶
- Decentralized Social: Reddit-like apps, no central authority
- Collaborative Editing: Real-time co-editing
- P2P Chat: Messaging without central server
- Open Data Sharing: Community-owned datasets
Pricing¶
Free and open-source
4. RxDB (Best for React Native + Flexibility)¶
Type: JavaScript local-first database with flexible sync
What It Does¶
Reactive NoSQL database that runs on React Native and web, with pluggable replication backends including WebRTC P2P.
Architecture¶
React Native App
↓
RxDB (SQLite locally)
↓
Sync Engine (pluggable)
↓
├─ HTTP/REST
├─ GraphQL
├─ WebRTC (P2P)
├─ WebSocket
└─ Custom
Key Features¶
- Reactive: RxJS observables for automatic UI updates
- Cross-Platform: Web, React Native, Electron, Node.js
- Pluggable Storage: SQLite, IndexedDB, LevelDB, etc.
- Multiple Replication Plugins:
- GraphQL
- Firebase
- Supabase
- CouchDB
- WebRTC (P2P)
- Offline-First: Works completely offline
Code Example¶
import { createRxDatabase } from 'rxdb'
import { getRxStorageSQLite } from 'rxdb/plugins/storage-sqlite'
// Create database
const db = await createRxDatabase({
name: 'mydatabase',
storage: getRxStorageSQLite()
})
// Create collection
const tasksCollection = await db.addCollections({
tasks: {
schema: { /* schema */ }
}
})
// Reactive queries
tasksCollection.find().observe$.subscribe(tasks => {
console.log('Tasks updated:', tasks)
})
// WebRTC P2P sync
const replicationState = replicateWebRTC({
replicationIdentifier: 'my-sync',
collection: tasksCollection,
pull: { },
push: { }
})
Strengths¶
- Flexibility: Choose your sync protocol
- Reactive: Automatic UI synchronization
- Performance: Fast queries on large datasets
- Mature: Production-ready
- Community: Good ecosystem
- WebRTC P2P: Built-in peer discovery
Weaknesses¶
- JavaScript-centric: No native mobile optimizations
- Setup: More configuration required
- P2P requires signaling: WebRTC needs server for peer discovery
- Learning curve: RxJS and complex config
Use Cases¶
- Progressive Web Apps: Offline-capable websites
- React Native Apps: With flexible sync backends
- Collaborative Apps: Real-time UI updates
- Multi-platform: Same database code everywhere
Pricing¶
Free tier / Enterprise options available
5. Couchbase Lite (Best for Enterprise Mobile)¶
Type: Commercial, embedded database with P2P sync
What It Does¶
Battle-tested mobile database with native SDKs and built-in P2P replication.
Architecture¶
Mobile Device Mobile Device
↓ ↓
Couchbase Lite Couchbase Lite
(embedded) (embedded)
↓ ↓
← P2P Replication (WebSocket) →
↓ ↓
Couchbase Server (optional, for backup)
Key Features¶
- Native SDKs: Swift, Kotlin, Java, .NET, C++
- P2P Replication: Direct device-to-device sync
- JSON Documents: Flexible schema
- SQL++ Queries: SQL-like syntax on documents
- Full-Text Search: Built-in search capabilities
- Encryption: AES-256 at rest and in transit
Code Example¶
// Android
import com.couchbase.lite.*
// Create database
val dbConfig = DatabaseConfiguration()
val database = Database("myapp", dbConfig)
// Peer-to-Peer sync
val config = ReplicatorConfiguration(
database,
URLEndpoint(URI("wss://192.168.1.100:4984/dbname"))
)
config.setPullFilter { doc, flags -> true }
val replicator = Replicator(config)
replicator.start()
// Query
val query = database
.createQuery("SELECT * FROM _ WHERE type='task'")
query.execute { rs ->
rs.forEach { result ->
println(result.getString("name"))
}
}
Strengths¶
- Enterprise-ready: Production-proven
- Native Performance: Optimized for each platform
- P2P Sync: Built-in, no custom code
- Queries: SQL++ is familiar to SQL developers
- Mature: Replaces Realm (MongoDB deprecated mobile)
- Cross-platform: iOS, Android, Web
Weaknesses¶
- Commercial: Requires licensing for some features
- Sync Opinionated: Less flexible customization
- Smaller P2P Community: Mainly server-centric
- Complex Setup: More boilerplate than RxDB
Use Cases¶
- Healthcare Apps: HIPAA-compliant, offline-first medical records
- Enterprise Mobility: Field service, inventory management
- Financial Services: Offline trading, banking
- Mission-Critical: Where reliability is paramount
Pricing¶
- Lite: Free for development
- Enterprise: Paid licensing for production P2P features
6. ObjectBox (Best for Performance)¶
Type: Commercial, high-performance embedded database
What It Does¶
Ultra-fast NoSQL database optimized for edge/mobile with built-in data sync.
Architecture¶
Android/iOS/IoT Device
↓
ObjectBox DB
(10x faster than SQLite)
↓
ObjectBox Sync
↓
Bi-directional sync
Key Features¶
- 10x Performance: Microsecond operations
- Vector Search: On-device embeddings for AI
- Built-in Sync: Minimal configuration
- Multi-platform: Android, iOS, Flutter, IoT
- ACID Compliant: Data integrity
- Minimal Footprint: <1MB binary
Code Example¶
// Android
import io.objectbox.kotlin.boxFor
// Create object
val task = Task(0, "Buy milk", false)
store.boxFor(Task::class).put(task)
// Query
val completedTasks = store.boxFor(Task::class)
.query(Task_.completed.equal(true))
.build()
.find()
// Vector search (for AI)
val similarTasks = store.boxFor(Task::class)
.query()
.nearestNeighbors(Task_.vector, queryVector, 10)
.build()
.find()
// Sync
val syncClient = Sync.client(store, "wss://your-server")
.buildAndStart()
Strengths¶
- Performance: 10x-1000x faster than alternatives
- Battery: Minimal power consumption
- Vector DB: First mobile DB with AI embeddings
- Sync: Built-in, bi-directional
- Free: Database is permanently free
- Proven: Automotive, aerospace, industrial IoT
Weaknesses¶
- Limited Reactivity: Manual observer patterns
- Smaller Community: Fewer examples
- Native Focus: Less JavaScript-friendly
- P2P Limited: Sync server-centric
Use Cases¶
- Automotive: Connected car systems
- Industrial IoT: Sensor networks, edge processing
- Healthcare Wearables: Battery-critical devices
- Field Work: Long-duration offline operations
- AI on Edge: On-device machine learning
Pricing¶
- Database: Free forever
- Sync: Free to self-host, optional managed service
Feature Comparison Matrix¶
| Feature | Ditto | OrbitDB | GunDB | RxDB | Couchbase | ObjectBox |
|---|---|---|---|---|---|---|
| Architecture | P2P Mesh | IPFS | Pure P2P | JS Local | Client-Server | Object DB |
| Mobile SDK | ✅ iOS/Android | ❌ Browser | ⚠️ JS only | ⚠️ JS only | ✅ Native | ✅ Native |
| P2P Support | ✅ Mesh | ✅ Full | ✅ Full | ⚠️ WebRTC | ✅ Limited | ⚠️ Limited |
| Offline-First | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Sync Included | ✅ | ❌ | ✅ | Plugin | ✅ | ✅ |
| Reactivity | ✅ | ❌ | ✅ | ✅ | ❌ | ⚠️ |
| Encryption | ✅ | ✅ | ✅ | Plugin | ✅ | ✅ |
| Performance | Good | Fair | Fair | Good | Good | ⭐⭐⭐ |
| Battery | Good | Fair | Fair | Good | Good | ⭐⭐⭐ |
| Community | Medium | Medium | Large | Large | Large | Small |
| Learning Curve | Medium | Hard | Medium | Hard | Medium | Medium |
| Cost | Commercial | Free | Free | Free | Freemium | Free |
| Vector Search | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ |
| Graph DB | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
| SQL-like | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
Architecture Patterns¶
1. Pure P2P (No Servers)¶
Best for: Censorship-resistant apps, full offline autonomy
Examples: GunDB, pure OrbitDB
Trade-offs: - ✅ No single point of failure - ✅ Full privacy - ❌ Peer discovery complex - ❌ Data redundancy overhead
2. P2P with Optional Backend¶
Best for: Flexible offline + backup
Examples: Ditto, Couchbase Lite, ObjectBox Sync
Trade-offs: - ✅ Works offline - ✅ Cloud backup available - ✅ Peer discovery via server - ❌ Server adds complexity
3. Local-First with Cloud Sync¶
Best for: Optimal UX, existing infrastructure
Examples: RxDB, WatermelonDB
Trade-offs: - ✅ Simpler architecture - ✅ Works offline - ❌ Requires backend - ❌ Limited P2P
4. Hybrid: Multi-Layer Sync¶
Best for: Complex apps requiring different sync strategies
Sync Mechanisms¶
1. Pull-Push (Traditional)¶
How it works: 1. Client pulls changes from server (with timestamp) 2. Server sends only changes after last pull time 3. Client applies changes 4. Client pushes its local changes 5. Server applies and broadcasts
Examples: WatermelonDB, RxDB with REST
Pros: Simple, predictable, easy to understand
Cons: More data transfer, potential conflicts
2. CRDT-Based (Conflict-Free)¶
How it works:
User A edits: "Hello" → "Hello World"
User B edits: "Hello" → "Hello, friend!"
CRDT automatically merges to: "Hello World, friend!"
(No conflict, no manual resolution needed)
Examples: Ditto, GunDB, Yjs
Pros: Automatic conflict resolution, works P2P
Cons: More complex, requires understanding CRDTs
3. Event Sourcing¶
How it works:
Event 1: Created task "A"
Event 2: Added subtask "A1"
Event 3: Completed "A1"
Replay events to reconstruct state
Examples: OrbitDB (events log), some Couchbase implementations
Pros: Full history, auditable
Cons: More storage, complexity
4. Merkle Tree Sync¶
How it works:
A: [1, 2, 3, 4, 5]
B: [1, 2, 3, 6, 7]
Compare hashes:
- Section 1 (1,2,3) ✅ same
- Section 2 (4,5 vs 6,7) ❌ different
Only sync the different section
Examples: Couchbase, some P2P implementations
Pros: Efficient (bandwidth), fast
Cons: Initial complexity
Conflict Resolution¶
Scenario: Two Users Offline¶
Starting state: "Task: Buy groceries"
User A (on phone):
- Changes task to "Buy groceries & cook dinner"
- Completes task
User B (on tablet):
- Changes task to "Buy milk, bread, eggs"
- Uncompletes task
Both reconnect. How do we resolve?
Strategy 1: Last-Write-Wins¶
Resolution: User B's version wins (last to sync)
Result: "Buy milk, bread, eggs" (uncompleted)
⚠️ User A's changes are lost
Implementation:
Used by: Firebase, simple sync
Strategy 2: Custom Resolution Logic¶
Resolution: Merge field-level
- Title: User B's version (more specific)
- Completed: User A's version (more recent action)
Result: "Buy milk, bread, eggs" (completed)
Implementation:
const resolved = {
title: remoteChange.title, // B's specific list
completed: localChange.completed, // A's completion
timestamp: Math.max(local, remote)
}
Used by: Custom backends, complex apps
Strategy 3: CRDT (Automatic)¶
Both changes merged mathematically:
- Text: Operational Transform or Yjs handles it
- Flag: CRDT counter/flag automatically merged
Result: "Buy milk, bread, eggs & cook dinner" (completed)
No manual conflict resolution needed!
Used by: Ditto, GunDB, Yjs, Automerge
Use Cases by Industry¶
Healthcare¶
Requirements: - HIPAA compliance (encryption) - Offline operation (field clinics) - Multi-device sync (doctors, nurses) - Data integrity (lives depend on it)
Best fit: Ditto or Couchbase Lite
Doctor's tablet → P2P with nurse's tablet
↓ ↓
Patient data Patient data
└──────→ Hospital server (backup)
Field Service / Logistics¶
Requirements: - Technician works offline all day - Sync when returning to depot - Multiple techs access same work orders - Offline routing capabilities
Best fit: Ditto or ObjectBox
Technician A (offline in field)
↓
Task management app (fully offline)
↓
Returns to depot → P2P sync with other techs
↓
Cloud sync backup
Retail / POS¶
Requirements: - Fast transactions (no lag) - Works offline during outage - Multiple devices in store - P2P sync between registers
Best fit: ObjectBox or RxDB
Register 1 Register 2 Register 3
↓ ↓ ↓
Transaction Transaction Transaction
↓ ↓ ↓
P2P sync (fast inventory updates)
↓
Cloud backup
Collaborative Apps (Google Docs-style)¶
Requirements: - Real-time collaboration - Offline editing - Automatic conflict resolution - Fast UI updates
Best fit: RxDB + Yjs or native CRDT-based
User A edits locally (RxDB)
User B edits locally (RxDB)
Both users see changes in real-time
CRDT automatically merges conflicts
Decentralized Apps (Web3)¶
Requirements: - No central authority - Censorship resistant - Encrypted data - Verifiable transactions
Best fit: GunDB or OrbitDB
DApp on user's browser
↓
GunDB (no servers)
↓
P2P network
↓
User's data completely encrypted
Immutable history via IPFS
IoT / Sensor Networks¶
Requirements: - Minimal battery usage - Efficient sync (lots of data) - Resource-constrained devices - Possibly headless (no UI)
Best fit: ObjectBox
Hundreds of sensors → ObjectBox (minimal overhead)
↓
Edge gateway (faster processor)
↓
Cloud aggregation
Implementation Guide¶
Phase 1: Selection (1 week)¶
- Define Requirements
- What's your scale? (10 devices? 1,000,000?)
- Is P2P required? (mesh, or client-server OK?)
- Performance requirements? (milliseconds vs microseconds)
- Battery constraints?
-
Team expertise? (JavaScript vs native)
-
Prototype
- Build small test with top 2 candidates
- Measure performance
-
Assess developer experience
-
Select
- Document decision rationale
- Plan timeline
Phase 2: Setup (2-4 weeks)¶
-
Schema Design
-
Sync Strategy
- When to sync? (on app launch, every 30s, manual)
- Conflict resolution approach
-
Data bandwidth optimization
-
Error Handling
Phase 3: Development (4-8 weeks)¶
-
Data Layer Abstraction
-
Offline-First UI
function TaskList() { const [tasks, setTasks] = useState([]) const [syncStatus, setSyncStatus] = useState('idle') useEffect(() => { // Auto-update when data changes const sub = taskRepo.observeTasks() .subscribe(setTasks) return () => sub.unsubscribe() }, []) return ( <> <List items={tasks} /> <SyncStatus status={syncStatus} /> </> ) } -
Testing
describe('Offline sync', () => { it('syncs when reconnected', async () => { // Create data offline await db.saveTask({ title: 'Task A' }) // Simulate reconnection networkManager.reconnect() // Verify sync await waitFor(() => { expect(server.tasks).toContainEqual( expect.objectContaining({ title: 'Task A' }) ) }) }) })
Phase 4: Optimization (2-4 weeks)¶
- Performance Profiling
- Measure sync times
- Profile CPU/memory usage
-
Monitor battery drain
-
Data Optimization
- Pagination for large datasets
- Selective sync (only needed data)
-
Compression for transmission
-
UX Polish
- Conflict UI if needed
- Sync progress visibility
- Graceful degradation
Resources¶
Official Documentation¶
- Ditto: https://docs.ditto.live
- OrbitDB: https://orbitdb.org
- GunDB: https://gun.eco
- RxDB: https://rxdb.info
- Couchbase Lite: https://docs.couchbase.com/couchbase-lite
- ObjectBox: https://docs.objectbox.io
Learning Resources¶
- "Local-First Software" - Philosophy and guide
- "CRDTs Explained" - Understanding conflict-free types
- "P2P Networking Patterns" - Fundamentals
- IETF RFCs on eventual consistency and distributed systems
Tools & Libraries¶
- Yjs: CRDT for collaborative editing
- Automerge: JSON-like data with CRDTs
- Libp2p: P2P networking primitives
- IPFS: Distributed file system (integrates with OrbitDB)
Conclusion¶
Choosing a P2P database is about balancing:
- Decentralization vs. Simplicity
- Offline capability vs. Consistency
- Performance vs. Flexibility
- Complexity vs. Features
For mobile development, the landscape is:
- Just need offline-first? → RxDB or WatermelonDB
- Want P2P mesh? → Ditto
- Need maximum performance? → ObjectBox
- Building decentralized app? → GunDB or OrbitDB
- Enterprise with existing backend? → Couchbase Lite
Start with a proof-of-concept, measure what matters to your users, and choose accordingly.