Cells is a P2P cellular mesh protocol that organizes peers into interconnected cells to achieve efficient and scalable broadcast communication. This revolutionary architecture enables GenosDB to scale to tens of thousands of simultaneous peers while maintaining low latency.
Introduction
Traditional mesh topology connects every peer to every other peer, creating O(N²) connections. For 100 peers, this means ~10,000 connections—quickly becoming impractical.
Cells solves this by:
Cellular Architecture : Peers grouped into cells with bridges connecting adjacent cells
Dynamic Cell Size : Automatically adjusts based on network size
Health Scoring : Intelligent bridge selection based on health metrics
Dynamic TTL : Message time-to-live calculated based on topology
Deduplication : Duplicate message prevention with tracking sets
Heartbeat : Periodic synchronization and cleanup of inactive peers
Key Features
Linear Scalability Connection complexity reduces from O(N²) to O(N)
Automatic Sizing Cell size adapts dynamically to network growth
Redundant Bridges Multiple bridges between cells for fault tolerance
Health Metrics Intelligent bridge selection based on latency and stability
Architecture
Cell Topology
Peers are organized into linear cells based on their position in the sorted roster:
cell-0 ←──→ cell-1 ←──→ cell-2 ←──→ cell-3 ←──→ cell-4
│ │ │ │ │
peers peers peers peers peers
Peer-to-Cell Assignment
Peers are assigned to cells using a simple formula:
const cellIndex = Math . floor ( peerIndex / cellSize );
const cellId = `cell- ${ cellIndex } ` ;
Example with cellSize = 3 and 9 sorted peers [A, B, C, D, E, F, G, H, I]:
Cell Peers cell-0 A, B, C cell-1 D, E, F cell-2 G, H, I
Bridges
Bridges are peers selected to connect adjacent cells. Only bridges can forward messages between cells.
cell-0 cell-1
┌─────┐ ┌─────┐
│ A │ │ D │
│ B ●──┴────────┴─● E │ ← B and E are bridges
│ C │ │ F │
└─────┘ └─────┘
Bridge Selection
Bridges are selected from the “edge group” (peers at the boundary between two cells) and ranked by healthScore:
const edgeGroup = roster . slice (
Math . min ( cellA , cellB ) * cellSize ,
( Math . max ( cellA , cellB ) + 1 ) * cellSize
);
// Sort by health score and select top N
const bridges = edgeGroup
. sort (( a , b ) => getHealth ( b ) - getHealth ( a ))
. slice ( 0 , bridgesPerEdge );
Configuration
Basic Setup
import { gdb } from 'genosdb' ;
// Cells with default options
const db = await gdb ( 'mydb' , { rtc: { cells: true } });
// Cells with custom options
const db = await gdb ( 'mydb' , {
rtc: {
cells: {
cellSize: 'auto' , // or fixed number
bridgesPerEdge: 2 , // redundancy
maxCellSize: 50 , // cap for auto mode
targetCells: 100 , // target number of cells
debug: false // enable logging
}
}
});
// With custom relay + cells
const db = await gdb ( 'mydb' , {
rtc: {
relayUrls: [ 'wss://my-relay.com' ],
cells: { cellSize: 10 }
}
});
Access Room and Mesh
const room = db . room ;
const mesh = room . mesh ;
const selfId = db . selfId ;
Parameters
Parameter Type Default Description cellSize'auto' | number'auto'Number of peers per cell. Auto mode calculates dynamically bridgesPerEdgenumber2Number of bridges between adjacent cells maxCellSizenumber50Maximum peers per cell in auto mode targetCellsnumber100Target number of cells in the network debugbooleanfalseEnables debug logs in console
Dynamic Cell Size
When cellSize: 'auto', the cell size is calculated automatically:
const computeOptimalCellSize = ( peerCount , targetCells , maxCellSize ) => {
if ( peerCount < 10 ) return 2 ;
const computed = Math . ceil ( peerCount / targetCells );
return Math . max ( 2 , Math . min ( maxCellSize , computed ));
}
Calculation Table
Peers Formula cellSize 5 minimum 2 100 100/100 = 1 → minimum 2 500 500/100 = 5 5 1,000 1000/100 = 10 10 5,000 5000/100 = 50 50 10,000 10000/100 = 100 → capped 50
The cellSize is recalculated on each refreshState() to adapt to network changes.
Metrics System (PeerMetrics)
Each peer has associated metrics used for bridge selection:
class PeerMetrics {
peerId // Unique peer ID
joinedAt // Initial connection timestamp
lastSeen // Last recorded activity
rttSamples [] // Last 10 latency samples
stability // 0.0 - 1.0 (decreases with reconnections)
reconnects // Reconnection counter
isResponsive // true if responded to last ping
connectedCells // Set of cells where peer has been seen
}
Computed Properties
Property Calculation uptimeDate.now() - joinedAtavgRttAverage of rttSamples (∞ if empty) isStaleDate.now() - lastSeen > 30000healthScoreComposite score 0.0 - 1.0
healthScore =
( rttScore * 0.25 ) + // 25%: Low latency = better
( uptimeScore * 0.25 ) + // 25%: Longer connected = better
( stabilityScore * 0.30 ) + // 30%: Fewer reconnections = better
( responsivenessScore * 0.20 ) // 20%: Responds to pings = better
Bridge Selection The peers with the highest health scores are elected as bridges, ensuring reliable inter-cell communication.
Dynamic TTL
The message Time-To-Live is calculated based on network size:
const dynamicTTL = () => {
const totalCells = Math . ceil ( roster . length / cellSize );
return Math . min ( 150 , totalCells + 3 ); // Capped at 150
}
Peers Cells TTL 50 5 8 200 20 23 1,000 100 103 5,000+ 147+ 150 (max)
TTL decreases by 1 per hop. Messages with TTL ≤ 0 are not forwarded.
Message Flow
Internal Message Types
| Type | Purpose |
|------|---------||
| state | Peer state broadcast (cell, bridges, health) |
| msg | User message (payload from mesh.send()) |
| ping | Latency measurement request |
| pong | Ping response with timestamp |
Message Structure
{
t : 'msg' , // Type
id : 'abc:123:456' , // Unique ID (selfId:timestamp:seq)
ttl : 53 , // Time-to-live
data : { ... }, // Payload
origin : 'peer-abc' , // Originating peer
originCell : 'cell-0' // Origin cell
}
Routing Logic
Intra-cell Message
Message from a peer in my cell is delivered locally, and bridges forward to neighboring cells
Inter-cell Message
Message from a neighboring cell is injected into local cell and forwarded to other neighbors
Deduplication
Already seen messages (tracked in seen set) are not processed again
TTL Decrement
TTL is decremented at each hop. Messages with TTL ≤ 0 are dropped
┌─────────────────────────────────────────────────────────────┐
│ Peer A sends message from cell-0 │
├─────────────────────────────────────────────────────────────┤
│ │
│ cell-0 ──→ cell-1 ──→ cell-2 ──→ cell-3 │
│ │ B01 │ B12 │ B23 │ │
│ ↓ ↓ ↓ ↓ │
│ [A,B,C] [D,E] [F,G,H] [I,J] │
│ │
│ Route: A → cell-0 → B01 → cell-1 → B12 → cell-2 → ... │
└─────────────────────────────────────────────────────────────┘
Heartbeat System
The system periodically broadcasts state and cleans up inactive peers:
const HEARTBEAT_INTERVAL = 5000 ; // 5 seconds
const PEER_TIMEOUT = 30000 ; // 30 seconds
setInterval (() => {
sendState (); // Broadcast current state
// Remove stale peers
for ( const [ id , metrics ] of peerMetrics ) {
if ( metrics . isStale ) {
peerInfo . delete ( id );
peerMetrics . delete ( id );
}
}
}, HEARTBEAT_INTERVAL );
Public API
Messaging
// Send broadcast message
mesh . send ({ type: 'chat' , text: 'Hello world' });
// Receive messages
const unsubscribe = mesh . on ( 'message' , ( data , fromPeerId ) => {
console . log ( `Message from ${ fromPeerId } :` , data );
});
// Stop listening
unsubscribe ();
State Inspection
const state = mesh . getState ();
// {
// cellId: "cell-2",
// isBridge: true,
// bridges: ["cell-1", "cell-3"],
// cellSize: 5,
// dynamicTTL: 23,
// totalCells: 20,
// knownCells: 18,
// health: {
// cellId: "cell-2",
// memberCount: 5,
// avgHealth: 0.85,
// responsiveRatio: 1.0
// }
// }
Metrics
// Metrics for a specific peer
const metrics = mesh . getMetrics ( peerId );
// { uptime, avgRtt, healthScore, isStale, stability, ... }
// Cell health
const health = mesh . getCellHealth ( 'cell-2' );
// { cellId, memberCount, avgHealth, responsiveRatio }
// Ping a peer (returns RTT in ms)
const rtt = await mesh . ping ( peerId );
// Info for all known peers
const peerInfo = mesh . getPeerInfo ();
// Map<peerId, { cell, isBridge, bridges }>
// Roster of active peers (not stale)
const roster = mesh . getStableRoster ();
// ['peer-a', 'peer-b', 'peer-c', ...]
// Known cells
const cells = mesh . getKnownCells ();
// Map<cellId, { lastSeen, peerId }>
// Current cellSize
const size = mesh . getCellSize ();
// 5
Events
// Room events
room . on ( 'peer:join' , peerId => { ... });
room . on ( 'peer:leave' , peerId => { ... });
// Mesh events
room . on ( 'mesh:state' , state => {
// Own state updated
// { cellId, isBridge, bridges, dynamicTTL, cellSize }
});
room . on ( 'mesh:peer-state' , data => {
// Remote peer state received
// { id, cell, bridges, health, timestamp }
});
room . on ( 'mesh:health' , healthData => {
// Cell health update
// { cellId, isBridge, health: { memberCount, avgHealth, ... } }
});
Scalability Analysis
Peers Cells Max Hops Connections Traditional Mesh 100 10 ~10 ~459 ~4,950 1,000 100 ~100 ~4,599 ~499,500 10,000 200 ~150 ~45,999 ~49,995,000 Large scale 1,000+ ~150 (max) Linear Quadratic
connections ≈ (peers × cellSize) + (cells × bridgesPerEdge × 2)
Massive Reduction Compared to traditional mesh (N × (N-1) / 2), the cellular architecture achieves 100x to 1000x reduction in connections for large networks.
Use Case Recommendations
Use Case Configuration General chat (< 100 peers) { rtc: true } (traditional mesh)Real-time games { rtc: { cells: { cellSize: 5, bridgesPerEdge: 2 } } }IoT / Sensors { rtc: { cells: { cellSize: 'auto', targetCells: 200 } } }Low latency priority { rtc: { cells: { cellSize: 3, bridgesPerEdge: 2 } } }High scale (1000+ peers) { rtc: { cells: { cellSize: 'auto', maxCellSize: 100 } } }
Complete Example
import { gdb } from 'genosdb' ;
async function main () {
// Connect with cells enabled
const db = await gdb ( 'my-app' , {
rtc: {
cells: { cellSize: 'auto' , bridgesPerEdge: 2 }
}
});
const room = db . room ;
const mesh = room . mesh ;
const selfId = db . selfId ;
// Listen for events
room . on ( 'peer:join' , id => console . log ( 'New peer:' , id ));
room . on ( 'peer:leave' , id => console . log ( 'Peer left:' , id ));
room . on ( 'mesh:state' , state => {
console . log ( `I'm in ${ state . cellId } , bridge: ${ state . isBridge } ` );
});
// Receive messages
mesh . on ( 'message' , ( data , from ) => {
console . log ( `[ ${ from } ]:` , data );
});
// Send message
document . getElementById ( 'sendBtn' ). onclick = () => {
const text = document . getElementById ( 'input' ). value ;
mesh . send ({ type: 'chat' , text , author: selfId });
};
// Monitoring
setInterval (() => {
const state = mesh . getState ();
console . log ( `Cells: ${ state . totalCells } , TTL: ${ state . dynamicTTL } ` );
}, 10000 );
}
main ();
Related Pages
GenosRTC Architecture Core P2P networking layer
Cells Topology Deep dive into cellular mesh topology