Skip to content

Hub and Spoke Network

Introduction

The hub and spoke network topology is a foundational architecture pattern where all traffic between nodes (spokes) flows through a central point (the hub), rather than connecting every node directly to every other node. Originally popularized in airline routing and telecommunications, this pattern is now a cornerstone of cloud networking, enterprise WAN design, and distributed systems architecture — enabling centralized control, simplified management, and cost-effective scaling of network infrastructure.

Core Concepts

The Fundamental Model

Imagine an airline system: instead of offering direct flights between every pair of cities (which would require thousands of routes), the airline establishes a central airport — the hub. All passengers fly into the hub and then transfer to their destination spoke. This dramatically reduces the number of required connections from O(n²) in a full mesh to O(n) in a hub-and-spoke model.

The same principle applies to computer networks. In a hub and spoke topology:

  • The hub is a central network node (a data center, cloud VPC, transit gateway, or router) that manages, inspects, and routes traffic.
  • The spokes are remote sites, branch offices, VPCs, or microservice clusters that connect to the hub but not directly to each other.
  • All inter-spoke communication is mediated by the hub.

Why Not Full Mesh?

A full mesh topology connects every node to every other node. While this provides maximum redundancy and minimal latency, the number of connections grows quadratically:

  • 5 nodes → 10 connections
  • 10 nodes → 45 connections
  • 50 nodes → 1,225 connections
  • 100 nodes → 4,950 connections

Hub and spoke reduces this to n - 1 connections (one per spoke to the hub), making it vastly simpler to manage, secure, and monitor.

Key Properties

PropertyHub and SpokeFull MeshStar (Simple)
Connectionsn - 1n(n-1)/2n - 1
Centralized control✅ Yes❌ No✅ Yes
Single point of failure⚠️ Hub❌ None⚠️ Center
ScalabilityHighLowHigh
Inter-spoke latencyHigher (2 hops)Lower (1 hop)Higher (2 hops)
Security enforcementCentralizedDistributedCentralized

Hub and Spoke vs. Star Topology

While visually similar, hub and spoke differs from a simple star topology in intent and capability. A star topology merely describes the physical shape — one center, many endpoints. Hub and spoke implies intelligent routing, policy enforcement, and traffic management at the hub. The hub is not a passive switch; it is an active participant that inspects, filters, transforms, and routes traffic.

Traffic Flow Patterns

Spoke-to-Hub Communication

The most common pattern. Spokes access shared services hosted in or behind the hub — databases, identity providers, API gateways, internet egress points, or centralized logging systems.

Spoke-to-Spoke Communication (Transitive Routing)

When Spoke A needs to communicate with Spoke B, traffic flows through the hub. This is called transitive routing and is a defining characteristic of the topology.

Internet Egress via Hub

A common pattern centralizes all internet-bound traffic through the hub, where security appliances (firewalls, IDS/IPS, proxy servers) inspect outbound traffic.

Cloud Implementations

AWS Hub and Spoke with Transit Gateway

AWS Transit Gateway is the canonical implementation of hub and spoke in AWS. Before Transit Gateway, connecting multiple VPCs required individual VPC peering connections (creating a partial mesh). Transit Gateway acts as a regional network hub.

Key AWS Transit Gateway features:

  • Route tables: Control which spokes can communicate with which other spokes
  • Attachments: VPCs, VPN connections, Direct Connect gateways, peering connections
  • Multi-account support: Works across AWS accounts via AWS Resource Access Manager (RAM)
  • Bandwidth: Supports up to 50 Gbps per AZ per attachment

Azure Hub and Spoke with Virtual WAN

Azure implements hub and spoke natively through Azure Virtual WAN or manually through VNet peering with a central hub VNet. The hub VNet typically contains an Azure Firewall, VPN Gateway, and ExpressRoute Gateway.

GCP Hub and Spoke with Shared VPC

Google Cloud uses Shared VPC and VPC Network Peering to achieve hub and spoke. A host project contains the shared network resources, and service projects (spokes) attach to it.

Enterprise Network Design

Multi-Region Hub and Spoke

Large organizations often deploy regional hubs connected to each other, creating a hierarchical hub and spoke architecture. Each region has its own hub that manages local spokes, while inter-regional traffic flows between hubs.

Segmentation and Route Tables

One of the hub's most powerful capabilities is network segmentation through route table manipulation. By controlling which routes are propagated to which spokes, the hub can enforce isolation policies.

In this configuration, Production and Development environments can both reach Shared Services, but they cannot reach each other — enforced at the network level.

Implementation with Infrastructure as Code

The following Java example demonstrates creating an AWS hub and spoke topology using the AWS SDK for Java, provisioning a Transit Gateway with VPC attachments:

java
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.*;
import java.util.List;

public class HubAndSpokeProvisioner {

    private final Ec2Client ec2;

    public HubAndSpokeProvisioner(Ec2Client ec2) {
        this.ec2 = ec2;
    }

    /**
     * Creates a Transit Gateway (the hub) with default route table association
     * and propagation enabled.
     */
    public String createTransitGateway(String description) {
        CreateTransitGatewayRequest request = CreateTransitGatewayRequest.builder()
                .description(description)
                .options(TransitGatewayRequestOptions.builder()
                        .autoAcceptSharedAttachments(AutoAcceptSharedAttachmentsValue.ENABLE)
                        .defaultRouteTableAssociation(
                                DefaultRouteTableAssociationValue.ENABLE)
                        .defaultRouteTablePropagation(
                                DefaultRouteTablePropagationValue.ENABLE)
                        .dnsSupport(DnsSupportValue.ENABLE)
                        .build())
                .tagSpecifications(TagSpecification.builder()
                        .resourceType(ResourceType.TRANSIT_GATEWAY)
                        .tags(Tag.builder().key("Name").value("central-hub-tgw").build())
                        .build())
                .build();

        CreateTransitGatewayResponse response = ec2.createTransitGateway(request);
        String tgwId = response.transitGateway().transitGatewayId();
        System.out.println("Transit Gateway (Hub) created: " + tgwId);
        return tgwId;
    }

    /**
     * Attaches a VPC (spoke) to the Transit Gateway (hub).
     * Requires at least one subnet ID per AZ.
     */
    public String attachSpoke(String transitGatewayId, String vpcId,
                               List<String> subnetIds, String spokeName) {
        try {
            CreateTransitGatewayVpcAttachmentRequest request =
                    CreateTransitGatewayVpcAttachmentRequest.builder()
                            .transitGatewayId(transitGatewayId)
                            .vpcId(vpcId)
                            .subnetIds(subnetIds)
                            .tagSpecifications(TagSpecification.builder()
                                    .resourceType(
                                            ResourceType.TRANSIT_GATEWAY_ATTACHMENT)
                                    .tags(Tag.builder()
                                            .key("Name")
                                            .value("spoke-" + spokeName)
                                            .build())
                                    .build())
                            .build();

            CreateTransitGatewayVpcAttachmentResponse response =
                    ec2.createTransitGatewayVpcAttachment(request);

            String attachmentId = response.transitGatewayVpcAttachment()
                    .transitGatewayAttachmentId();
            System.out.printf("Spoke '%s' (VPC: %s) attached: %s%n",
                    spokeName, vpcId, attachmentId);
            return attachmentId;

        } catch (Ec2Exception e) {
            System.err.printf("Failed to attach spoke '%s': %s%n",
                    spokeName, e.awsErrorDetails().errorMessage());
            throw e;
        }
    }

    /**
     * Creates a custom route table for network segmentation.
     */
    public String createSegmentRouteTable(String transitGatewayId,
                                           String segmentName) {
        CreateTransitGatewayRouteTableRequest request =
                CreateTransitGatewayRouteTableRequest.builder()
                        .transitGatewayId(transitGatewayId)
                        .tagSpecifications(TagSpecification.builder()
                                .resourceType(
                                        ResourceType.TRANSIT_GATEWAY_ROUTE_TABLE)
                                .tags(Tag.builder()
                                        .key("Name")
                                        .value("segment-" + segmentName)
                                        .build())
                                .build())
                        .build();

        CreateTransitGatewayRouteTableResponse response =
                ec2.createTransitGatewayRouteTable(request);

        String routeTableId = response.transitGatewayRouteTable()
                .transitGatewayRouteTableId();
        System.out.printf("Segment route table '%s' created: %s%n",
                segmentName, routeTableId);
        return routeTableId;
    }

    /**
     * Adds a static route to direct traffic from one segment to a specific
     * spoke attachment.
     */
    public void addStaticRoute(String routeTableId, String destinationCidr,
                                String attachmentId) {
        CreateTransitGatewayRouteRequest request =
                CreateTransitGatewayRouteRequest.builder()
                        .transitGatewayRouteTableId(routeTableId)
                        .destinationCidrBlock(destinationCidr)
                        .transitGatewayAttachmentId(attachmentId)
                        .build();

        ec2.createTransitGatewayRoute(request);
        System.out.printf("Route %s → %s added to table %s%n",
                destinationCidr, attachmentId, routeTableId);
    }

    public static void main(String[] args) {
        Ec2Client ec2 = Ec2Client.builder().build();
        HubAndSpokeProvisioner provisioner = new HubAndSpokeProvisioner(ec2);

        // Step 1: Create the Hub (Transit Gateway)
        String tgwId = provisioner.createTransitGateway(
                "Central hub for multi-VPC networking");

        // Step 2: Attach Spokes (VPCs)
        // In practice, wait for TGW to become 'available' before attaching
        String prodAttachment = provisioner.attachSpoke(
                tgwId, "vpc-0abc123prod",
                List.of("subnet-0abc1", "subnet-0abc2"), "production");

        String devAttachment = provisioner.attachSpoke(
                tgwId, "vpc-0abc123dev",
                List.of("subnet-0def1", "subnet-0def2"), "development");

        String sharedAttachment = provisioner.attachSpoke(
                tgwId, "vpc-0abc123shared",
                List.of("subnet-0ghi1", "subnet-0ghi2"), "shared-services");

        // Step 3: Create segmented route tables
        String prodRouteTable = provisioner.createSegmentRouteTable(
                tgwId, "production");
        String devRouteTable = provisioner.createSegmentRouteTable(
                tgwId, "development");

        // Step 4: Add routes — prod can reach shared, dev can reach shared,
        //         but prod and dev cannot reach each other
        provisioner.addStaticRoute(prodRouteTable, "10.4.0.0/16",
                sharedAttachment);
        provisioner.addStaticRoute(devRouteTable, "10.4.0.0/16",
                sharedAttachment);

        System.out.println("Hub and spoke topology provisioned successfully!");
    }
}

Security at the Hub

The hub is the natural enforcement point for security policies. Because all traffic transits through it, you can apply centralized security controls without duplicating them across every spoke.

Centralized Firewall Inspection

This pattern is called "inspection VPC" or "bump in the wire". All east-west (spoke-to-spoke) and north-south (spoke-to-internet) traffic is routed through a dedicated firewall VPC attached to the hub.

Addressing the Single Point of Failure

The most significant drawback of hub and spoke is that the hub becomes a single point of failure. Strategies to mitigate this include:

High Availability Patterns

Managed services like AWS Transit Gateway are inherently highly available across multiple Availability Zones. For self-managed hubs, deploy redundant routers/firewalls across AZs with automatic failover.

Decision Framework: When to Use Hub and Spoke

Hybrid Approaches

In practice, pure hub and spoke is often combined with selective direct connections for high-traffic spoke pairs. This creates a partial mesh where most traffic flows through the hub, but performance-critical paths get dedicated connections.

This hybrid approach gives you the management benefits of hub and spoke while avoiding the latency penalty for high-throughput connections.

Best Practices

  1. Use managed hub services: Cloud providers offer Transit Gateway (AWS), Virtual WAN (Azure), and Network Connectivity Center (GCP) — these are battle-tested, highly available, and eliminate operational overhead of self-managed hubs.

  2. Implement network segmentation from day one: Use separate route tables per environment (production, staging, development) to enforce isolation at the network layer, not just application layer.

  3. Centralize security inspection at the hub: Route all traffic through a firewall or inspection VPC rather than deploying security appliances in every spoke — this reduces cost and ensures consistent policy enforcement.

  4. Plan CIDR blocks carefully: Avoid overlapping IP ranges across spokes. Establish a CIDR allocation strategy before deploying the first spoke — retroactive changes are painful.

  5. Monitor hub throughput and latency: The hub is the bottleneck by design. Set up CloudWatch alarms (or equivalent) for Transit Gateway byte counts, packet counts, and dropped packets.

  6. Deploy hub infrastructure across multiple Availability Zones: Ensure the hub layer survives AZ failures. For AWS Transit Gateway, attach subnets in every AZ where spokes exist.

  7. Use Infrastructure as Code: Define the entire hub and spoke topology in CloudFormation, Terraform, or CDK. Manual configuration of routes and attachments is error-prone at scale.

  8. Consider hybrid topologies for high-bandwidth spoke pairs: If two spokes consistently exchange large volumes of data, add a direct peering connection alongside the hub path to reduce latency and hub load.

  9. Implement transit gateway route table blackholing: Use blackhole routes to explicitly deny traffic between segments that should never communicate, rather than relying on the absence of routes.

  10. Document your routing topology: Maintain a living diagram of all spokes, route tables, and segmentation rules. As spoke count grows, undocumented routing becomes a security and operational risk.

  • Network Handshaking: Understanding how connections are established between hub and spoke nodes at the transport layer.
  • AWS SSO: Often deployed as a shared service in the hub VPC, providing centralized authentication across spoke accounts.
  • REST: APIs hosted in spoke VPCs communicate through the hub, making API gateway placement a key architectural decision.
  • Ansible: Infrastructure automation tool commonly used to configure routing and firewall rules across hub and spoke deployments.
  • Serverless and Container Workloads: Spoke VPCs often host containerized workloads that need hub-mediated access to shared databases and services.