Last updated: March 15, 2026

Tor circuits route your traffic through exactly three relays, the guard node (knows your IP but not destination), middle node (knows neither origin nor destination), and exit node (knows destination but not origin), such that no single relay sees your complete path. This three-hop design encrypts traffic at each layer and balances anonymity with performance, making it computationally infeasible for passive adversaries to trace your connection from origin to destination even if they control some network infrastructure.

Table of Contents

The Three-Hop Tor Circuit

Every Tor connection passes through exactly three relays: the entry guard (or guard node), the middle node, and the exit node. This three-hop design provides a balance between anonymity and performance.

                  
   Client         Guard          Middle           Exit        
  (Your IP)           Node               Node                 Node        
                  
                                                                
         Encrypted      Encrypted      Encrypted    
                                                                
                   Knows only             Knows only            Knows origin
                   client IP               guard IP             (via TLS metadata)

Why Three Relays?

Using three hops rather than more provides several advantages:

Circuit Construction Process

The Tor protocol uses a sophisticated key exchange mechanism to build circuits. Here’s how it works:

  1. Establishing the Circuit

When you connect to Tor, your client performs a Diffie-Hellman key exchange with each relay in sequence:

Simplified circuit extension (pseudo-code)
def extend_circuit(circuit, relay_info):
    # Create handshake with new relay
    public_key = generate_keypair()

    # Diffie-Hellman with relay
    shared_secret = diffie_hellman(
        public_key,
        relay_info.identity_key
    )

    # Derive session keys
    keys = derive_keys(shared_secret)

    # Add hop to circuit
    circuit.add_hop(relay_info, keys)

    return circuit
  1. Onion Encryption Layers

Each relay only decrypts one layer of encryption, revealing only where to forward the traffic next. This creates the “onion” effect:


  Layer 3 (Exit Node)  Decrypts this layer               
    
  Layer 2 (Middle Node)  Decrypts this layer             
    
  Layer 1 (Guard Node)  Decrypts this layer              
    
  Layer 0 (Your Client)  Original encrypted payload     

  1. Cell Structure

Tor uses fixed-size cells (512 bytes) for all communications. Each cell contains:

// Tor cell structure (simplified)
struct tor_cell {
    uint16_t circuit_id;    // Circuit identifier
    uint8_t  command;       // RELAY_BEGIN, RELAY_DATA, etc.
    uint8_t  payload[509];  // Encrypted payload
};

Visualizing Circuit Paths

You can visualize your current Tor circuit using the Tor Browser or by querying the Tor control port.

Using Tor Browser

  1. Click the shield icon in the Tor Browser toolbar
  2. View the “Circuit” section to see your current path
  3. Each relay shows its nickname, IP (partially obscured), and country

Programmatic Access

Connect to the Tor control port to programmatically inspect circuits:

Enable control port in torrc
ControlPort 9051
CookieAuthentication 1

Connect via socat or netcat
echo -e "AUTHENTICATE\r\nGETINFO circuit-status\r\nQUIT" | nc localhost 9051
Using Stem library (Python)
from stem import Controller

with Controller.from_port(port=9051) as controller:
    controller.authenticate()

    # Get all circuits
    for circuit in controller.get_circuits():
        print(f"Circuit {circuit.id}:")
        for i, hop in enumerate(circuit.path):
            print(f"  Hop {i+1}: {hop[0]} ({hop[1]})")

This outputs something like:

Circuit 12:
  Hop 1: Unnamed (86.123.45.67) [Germany]
  Hop 2: DCHubRelays03 (193.56.78.90) [Netherlands]
  Hop 3: tor4you (45.67.89.123) [France]

Circuit Lifetime and Renewal

Tor circuits don’t last forever. The default circuit lifetime is 10 minutes, after which Tor builds a new circuit. This limits the amount of traffic correlation an attacker can perform.

Configuration Options

You can adjust circuit behavior in your torrc:

Build new circuit every N seconds (default: 600)
MaxCircuitDirtime 600

Number of concurrent circuits (default: 1)
MaxClientCircuitsPending 1

Use only entry guards that have been stable for N days
NumEntryGuards 3

Understanding Guard Nodes

Guard nodes (also called entry guards) are a critical security feature. Instead of choosing random entry points each time, Tor clients select a small set of stable relays as permanent guards.

This prevents certain attacks:

Guard Selection Algorithm

Simplified guard selection logic
def select_guards(relays, config):
    # Filter stable, fast relays
    candidates = [r for r in relays
                  if r.is_stable and r.is_fast
                  and r.bandwidth > config.min_bandwidth]

    # Select weighted by bandwidth
    guards = weighted_selection(candidates, config.num_guards)

    return guards

Exit Node Considerations

The exit node is where Tor traffic meets the regular internet. This position carries unique risks:

Common Exit Node Ports

Most Tor relays allow these common ports:

Typical exit policy (most permissive)
accept *:80, *:443    # HTTP, HTTPS
accept *:22           # SSH
accept *:853          # DNS over TLS
reject *:*            # Reject everything else

Building Applications with Tor

For developers integrating Tor, the Stem library provides excellent Python bindings:

from stem import Signal
from stem.control import Controller

Start a new Tor circuit for each request
def tor_request(url, session):
    with Controller.from_port(port=9051) as controller:
        controller.authenticate()

        # Signal Tor to create new identity
        controller.signal(Signal.NEWNYM)

        # Configure session to use Tor
        session.proxies = {
            'http': 'socks5h://127.0.0.1:9050',
            'https': 'socks5h://127.0.0.1:9050'
        }

        return session.get(url)

Security Considerations

Understanding Tor circuit limitations helps you use it effectively:

Frequently Asked Questions

Who is this article written for?

This article is written for developers, technical professionals, and power users who want practical guidance. Whether you are evaluating options or implementing a solution, the information here focuses on real-world applicability rather than theoretical overviews.

How current is the information in this article?

We update articles regularly to reflect the latest changes. However, tools and platforms evolve quickly. Always verify specific feature availability and pricing directly on the official website before making purchasing decisions.

Are there free alternatives available?

Free alternatives exist for most tool categories, though they typically come with limitations on features, usage volume, or support. Open-source options can fill some gaps if you are willing to handle setup and maintenance yourself. Evaluate whether the time savings from a paid tool justify the cost for your situation.

Can I trust these tools with sensitive data?

Review each tool’s privacy policy, data handling practices, and security certifications before using it with sensitive data. Look for SOC 2 compliance, encryption in transit and at rest, and clear data retention policies. Enterprise tiers often include stronger privacy guarantees.

What is the learning curve like?

Most tools discussed here can be used productively within a few hours. Mastering advanced features takes 1-2 weeks of regular use. Focus on the 20% of features that cover 80% of your needs first, then explore advanced capabilities as specific needs arise.

Related Articles