Skip to main content
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]:
CellPeers
cell-0A, B, C
cell-1D, E, F
cell-2G, 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

ParameterTypeDefaultDescription
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

PeersFormulacellSize
5minimum2
100100/100 = 1 → minimum2
500500/100 = 55
1,0001000/100 = 1010
5,0005000/100 = 5050
10,00010000/100 = 100 → capped50
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

PropertyCalculation
uptimeDate.now() - joinedAt
avgRttAverage of rttSamples (∞ if empty)
isStaleDate.now() - lastSeen > 30000
healthScoreComposite score 0.0 - 1.0

Health Score Formula

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
}
PeersCellsTTL
5058
2002023
1,000100103
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

1

Intra-cell Message

Message from a peer in my cell is delivered locally, and bridges forward to neighboring cells
2

Inter-cell Message

Message from a neighboring cell is injected into local cell and forwarded to other neighbors
3

Deduplication

Already seen messages (tracked in seen set) are not processed again
4

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);

Network Information

// 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

PeersCellsMax HopsConnectionsTraditional Mesh
10010~10~459~4,950
1,000100~100~4,599~499,500
10,000200~150~45,999~49,995,000
Large scale1,000+~150 (max)LinearQuadratic

Connection Formula

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 CaseConfiguration
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();

GenosRTC Architecture

Core P2P networking layer

Cells Topology

Deep dive into cellular mesh topology