ArchitectureAdvanced

Peer-to-Peer (P2P): Decentralized Architecture

TT
TopicTrick Team
Peer-to-Peer (P2P): Decentralized Architecture

Peer-to-Peer (P2P): Decentralized Architecture

Peer-to-peer (P2P) architecture eliminates the central server: every node in the network is both a client and a server. It requests resources from peers and simultaneously serves resources to other peers. This design was popularised by BitTorrent for file sharing, powers blockchain networks like Bitcoin and Ethereum, and underlies modern distributed storage systems like IPFS.

Understanding P2P architecture requires mastering the distributed data structures (DHTs), consensus mechanisms, and network protocols that replace the coordination role normally played by a central server.


Client-Server vs. Peer-to-Peer

text
Client-Server:
  Client A ──► Server ◄── Client B
               │
               └── If server fails, all clients lose access

Peer-to-Peer:
  Node A ◄──► Node B ◄──► Node C
    │                        │
    └────────────────────────┘
    If Node A goes offline, B and C continue serving each other
PropertyClient-ServerPeer-to-Peer
Single point of failureYes (the server)No
ScalabilityLimited by server capacityScales with number of nodes
LatencyConsistent (fast server)Variable (depends on peers)
AvailabilityDepends on server uptimeIncreases with more peers
Bandwidth costPaid by operatorDistributed across all peers
CoordinationCentralised, simpleDistributed, complex
PrivacyServer knows all trafficVariable
Censorship resistanceLowHigh

P2P sacrifices consistency and predictable performance for resilience, decentralisation, and scalability that is funded by the participants, not the operator.


Distributed Hash Tables (DHT)

In client-server, a directory service (DNS, a database) maps names to locations. In P2P, a Distributed Hash Table (DHT) provides this mapping without any central server.

How DHT works

Each node in the network is assigned a node ID (a random 160-bit number in BitTorrent's Kademlia DHT). Each piece of data is assigned a key (a hash of the content). The DHT stores key → location mappings distributed across nodes: node N stores data for keys numerically close to its own ID.

text
Node IDs: 001, 017, 042, 089, 156, 201, 240 (simplified to 8-bit)
                    ↑
Key 044 is closest to node 042 → node 042 stores "which peer has this data"

Finding who has key 044:
1. You ask your nearest neighbour
2. They return the node closer to 044 than themselves
3. Repeat 4-5 hops until you reach the node responsible for key 044
4. That node tells you which peers currently have the data
text
Lookup: "Who has chunk 044?"
You (ID=001) ──► Node 017 ──► Node 042 (responsible) ──► "Peer 156 has it"
                                         4-5 hops maximum in a 1,000,000 node network

This logarithmic lookup is why DHT-based P2P networks like BitTorrent can locate data in a network of a million nodes with just 20 messages.

BitTorrent DHT (Kademlia)

text
// Simplified lookup pseudocode (Kademlia)
function findNode(targetId) {
  // Start with k closest known nodes to targetId
  let candidates = routingTable.kClosest(targetId);
  let visited = new Set();

  while (true) {
    // Query each candidate for their k closest to targetId
    const newNodes = await Promise.all(
      candidates.filter(n => !visited.has(n.id))
                .map(n => n.findNode(targetId))
    );

    candidates.forEach(n => visited.add(n.id));
    const allNodes = [...candidates, ...newNodes.flat()];
    const nextBest = kClosest(allNodes, targetId);

    if (JSON.stringify(nextBest) === JSON.stringify(candidates)) break;
    candidates = nextBest;
  }

  return candidates;  // k closest nodes to targetId
}

Gossip Protocols

In a centralised system, when data changes (a new Bitcoin transaction), the server knows immediately. In P2P, information must spread without a central broadcaster. Gossip protocols solve this:

  1. Node A receives a new transaction
  2. Node A selects 3 random peers and tells them
  3. Each peer selects 3 random peers and tells them
  4. Each of those selects 3 more...

After just 20 rounds, a network of 1,000,000 nodes has received the message. The fan-out grows exponentially: 3^20 = 3.5 billion — more than enough to cover any realistic network.

typescript
// Gossip protocol implementation
class GossipNode {
  private peers: Set<string> = new Set();
  private seen: Set<string> = new Set();   // Message IDs already processed
  private fanout = 3;  // Number of peers to forward to per round

  async gossip(message: { id: string; payload: unknown }) {
    if (this.seen.has(message.id)) return;  // Deduplicate
    this.seen.add(message.id);

    // Process the message locally
    this.handleMessage(message.payload);

    // Forward to random subset of peers
    const targetPeers = [...this.peers]
      .sort(() => Math.random() - 0.5)
      .slice(0, this.fanout);

    await Promise.all(
      targetPeers.map(peer =>
        this.sendToPeer(peer, message).catch(() => {})  // Ignore failed peers
      )
    );
  }

  private handleMessage(payload: unknown) {
    console.log('Received:', payload);
  }

  private async sendToPeer(peerId: string, message: unknown): Promise<void> {
    // Send over WebRTC, WebSocket, or custom protocol
  }
}

Gossip protocols are eventually consistent — every node will receive the message, but not at the exact same time. Bitcoin uses this to broadcast transactions across 10,000+ nodes in seconds.


Blockchain: P2P Consensus

Blockchain extends P2P with a consensus mechanism that enables nodes that do not trust each other to agree on a shared state (which transactions have occurred, in what order).

text
Block structure:
┌────────────────────────────────────┐
│ Block #1000                        │
│ Previous hash: 0000abc...          │
│ Merkle root: ff34de...             │
│ Timestamp: 1713436800              │
│ Nonce: 38492817                    │
│ Transactions: [tx1, tx2, tx3, ...] │
└────────────────────────────────────┘
         │ SHA256(SHA256(block header))
         â–¼
  block hash: 00000xyz...   ← must start with N zeros (Proof of Work)
         │
         â–¼ becomes "Previous hash" in Block #1001

Changing any historical block would change its hash, which changes the next block's hash, which cascades through the entire chain. Every node in the network would reject the tampered chain because it would not match their copy.

Merkle trees for efficient verification

Bitcoin uses Merkle trees to let lightweight clients verify that a specific transaction is in a block without downloading the entire block:

text
Transactions: [tx1, tx2, tx3, tx4]

Merkle Tree:
        root = H(H12 + H34)
       /              \
  H12 = H(H1+H2)    H34 = H(H3+H4)
   /        \          /        \
 H1=H(tx1) H2=H(tx2) H3=H(tx3) H4=H(tx4)

To prove tx3 is in the block, only provide: [H4, H12, root]
Verifier computes: H(H(H(tx3) + H4) + H12) == root? → yes, tx3 is included

IPFS: P2P Web

IPFS (InterPlanetary File System) is a content-addressed P2P file system. Instead of URLs that identify location (https://server.com/file), IPFS uses content identifiers (CIDs) that identify content:

bash
# Add a file to IPFS
ipfs add index.html
# Returns: QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG

# The CID is a hash of the content
# Anyone with the CID can retrieve the file from any IPFS node that has it:
ipfs cat QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG

# Access via HTTP gateway
curl https://ipfs.io/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG

Key property: the content can never change without the CID changing. There is no way to silently update a file at the same IPFS address — any change produces a different CID.

Hosting a static site on IPFS

bash
# Build your site
npm run build

# Add the entire directory to IPFS
ipfs add -r ./dist
# Returns CID for the root directory

# Pin to Pinata or Fleek to ensure availability (not just on your node)
curl -X POST "https://api.pinata.cloud/pinning/pinByHash" \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d '{"hashToPin": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"}'

WebRTC: Browser-to-Browser P2P

WebRTC enables direct peer-to-peer connections between browsers — video calls, screen sharing, and file transfer without a server handling the media:

typescript
// Simple WebRTC peer connection
const peerConnection = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' }  // STUN server for NAT traversal
  ]
});

// Data channel for arbitrary data
const channel = peerConnection.createDataChannel('messages');
channel.onmessage = (event) => console.log('Received:', event.data);

// Create offer (initiating peer)
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);

// Exchange offer/answer via a signalling server (small centralised component)
// Then the media flows directly peer-to-peer

Note: WebRTC still requires a signalling server to exchange connection metadata (offer/answer/ICE candidates), but the actual media and data flows directly between peers. Video calls using WebRTC do not pass through a server — latency is dramatically lower than a server-relayed connection.


P2P Use Cases in Production Engineering

Use caseP2P technologyWhy P2P
Software update distributionIPFS, BitTorrent (Windows Update)Reduces CDN bandwidth cost
Video conferencingWebRTCLow latency direct connections
Decentralised storageFilecoin, Storj, IPFSCensorship-resistant, no central operator
Blockchain applicationsBitcoin, Ethereum networkTrustless consensus
Edge computing coordinationGossip protocolsSelf-organising networks
Mesh networkinglibp2pResilient community networks

Frequently Asked Questions

Q: Is P2P inherently slower than client-server?

For small networks of peers with slow connections, yes. For large, well-seeded networks, P2P can be faster — BitTorrent distributes the bandwidth cost across all seeders, so popular files (Linux ISOs, software releases) can be downloaded faster via torrent than from a single server. The trade-off is unpredictability: download speed depends on the health of the swarm.

Q: How does a new node join a P2P network?

Most P2P protocols use a bootstrap node list — a small set of well-known, stable nodes maintained by the network operators. The new node contacts a bootstrap node, which provides a list of active peers. From there, the DHT lookup mechanism takes over. Bitcoin hardcodes DNS seeds; Ethereum uses a list of bootnodes. Once the node has discovered enough peers, it no longer needs the bootstrap nodes.

Q: Is all P2P traffic illegal?

P2P is a network architecture, not a legal category. BitTorrent is the same protocol used for pirating movies and distributing Linux distributions, academic papers via Sci-Hub, and Microsoft Windows updates. The protocol is neutral. IPFS powers censorship-resistant archives of publicly important content. WebRTC powers Zoom. Legality depends entirely on the content, not the protocol.

Q: How does blockchain prevent the same token from being spent twice?

The double-spend problem is solved by the consensus mechanism. All transactions are broadcast to all nodes via gossip. Miners/validators collect transactions and include them in blocks. Once a transaction is included in a confirmed block (6+ blocks deep in Bitcoin), the network's consensus makes it computationally infeasible to revert — it would require recomputing more proof-of-work than the honest majority of the network's combined hash power.


Key Takeaway

P2P architecture replaces the central server with a distributed network where every node contributes to the shared resource. DHTs enable decentralised lookup without a directory server. Gossip protocols propagate information to all nodes exponentially fast. Blockchain extends these with consensus to create tamper-evident shared state among untrusted parties. In 2026, P2P is production infrastructure: WebRTC powers video calls, IPFS hosts censorship-resistant content, and gossip protocols coordinate distributed databases and container orchestration systems. The architecture is not primarily about ideology — it solves real engineering problems: bandwidth cost distribution, resilience without a single point of failure, and coordination among parties who do not trust a central authority.

Read next: Pipe and Filter: Data Processing Pipelines →


Part of the Software Architecture Hub — engineering the descent.