← All Posts

VLANs vs VRFs: When You Need Overlapping Address Space

Most networks start simple. One address range, one set of devices, one routing table. As the network grows, you inevitably reach the point where you need to keep groups of devices separated from each other, and shortly after that, you discover that you've run out of clean address space because two different teams both want to use 10.0.1.0/24. Two technologies solve these problems, and they solve them at different layers. VLANs (Virtual Local Area Networks) separate traffic at layer 2, the switching layer. VRFs (Virtual Routing and Forwarding instances) separate traffic at layer 3, the routing layer. Understanding when you need one versus the other, or both, is one of the more practical things you can learn about network design.

A VLAN is a way to divide a single physical switch into multiple logical switches. Picture an office with one big network switch in the server closet. Without VLANs, every device plugged into that switch can talk to every other device. The engineering team's laptops, the guest Wi-Fi, the security cameras, and the accounting servers all share the same broadcast domain. That means a broadcast packet from any device reaches every other device, which is both a performance problem and a security problem. VLANs fix this by tagging each port on the switch with a numeric ID (typically between 1 and 4094). Devices in VLAN 10 can only communicate directly with other devices in VLAN 10. Devices in VLAN 20 are in their own separate world. Traffic between VLANs has to pass through a router, which gives you a natural enforcement point for firewall rules and access policies.

A switch with three VLANs
Switch (single physical device)
┌──────────────────────────────────────────────────┐
                                                  
  VLAN 10 (Engineering)    10.0.10.0/24          
    ports 1-12                                    
                                                  
  VLAN 20 (Accounting)     10.0.20.0/24          
    ports 13-20                                   
                                                  
  VLAN 99 (Guest Wi-Fi)    192.168.99.0/24       
    ports 21-24                                   
                                                  
└──────────────────────────────────────────────────┘

Each VLAN has its own subnet. Traffic between them
must pass through a router.

Each VLAN typically maps to its own subnet. VLAN 10 might use 10.0.10.0/24, VLAN 20 uses 10.0.20.0/24, and so on. This is clean, it's widely understood, and it works well for most organizations. The key thing to notice is that in a standard VLAN setup, every subnet uses a unique address range. The address spaces don't overlap. VLAN 10's 10.0.10.0/24 and VLAN 20's 10.0.20.0/24 are entirely separate ranges. The VLANs provide the traffic isolation, and the distinct subnets prevent any ambiguity about which device is which.

VRFs enter the picture when you need something VLANs alone can't provide: the ability to reuse the same IP address range in two different places at the same time. In a normal router, there is one routing table. That table says "to reach 10.0.1.0/24, send traffic out interface X." There can only be one entry for a given destination. A VRF creates a completely separate routing table inside the same physical router. You can have a VRF called "production" with a route to 10.0.1.0/24 pointing to one interface, and a VRF called "development" with the exact same 10.0.1.0/24 pointing somewhere else entirely. The two routing tables are invisible to each other. Traffic in the production VRF can never accidentally end up in the development VRF, even though both use identical address ranges.

One router, two VRFs, same CIDR block
Router
┌──────────────────────────────────────────────────┐
                                                  
  VRF "production"                               
    10.0.1.0/24  → interface eth0  (prod switch)  
    10.0.2.0/24  → interface eth1                 
                                                  
  VRF "development"                              
    10.0.1.0/24  → interface eth2  (dev switch)   
    10.0.2.0/24  → interface eth3                 
                                                  
└──────────────────────────────────────────────────┘

Same address ranges, completely isolated routing.
10.0.1.5 in production ≠ 10.0.1.5 in development.

Why would you want overlapping address space? The most common reason is multi-tenancy. If you're a managed service provider hosting infrastructure for multiple clients, each client expects to use their own familiar address ranges. Client A wants 10.0.0.0/16 for their environment. Client B also wants 10.0.0.0/16. Without VRFs, this is impossible because the router can't hold two conflicting routes. With VRFs, each client gets their own routing table, and their address spaces coexist peacefully on the same physical hardware. Cloud providers use this technique extensively, which is why you can spin up a VPC (Virtual Private Cloud) on AWS or GCP using 10.0.0.0/16 without worrying that another customer is using the same range.

Another common scenario is environment isolation. A company might want production, staging, and development to use identical network layouts so that configurations are portable between environments. If production uses 10.0.1.0/24 for web servers, staging should use the exact same range so that firewall rules, load balancer configs, and application settings don't need environment-specific overrides. VRFs make this possible by giving each environment its own routing context.

The relationship between VLANs and VRFs is complementary, not competitive. VLANs operate at the switch level and control which devices can communicate at layer 2. VRFs operate at the router level and control which routes exist in which routing table. In a well-designed network, you often use both together. A production VRF might contain VLANs 10, 20, and 30 (web servers, application servers, and databases). A development VRF might contain VLANs 110, 120, and 130 with the same purpose but completely separate address space. The VLANs handle microsegmentation within each environment, and the VRFs handle macrosegmentation between environments.

VLANs and VRFs working together
VRF "production"
  VLAN 10   10.0.1.0/24   Web servers
  VLAN 20   10.0.2.0/24   App servers
  VLAN 30   10.0.3.0/24   Databases

VRF "development"
  VLAN 110  10.0.1.0/24   Web servers      ← same CIDR, different VRF
  VLAN 120  10.0.2.0/24   App servers
  VLAN 130  10.0.3.0/24   Databases

VRF "guest"
  VLAN 200  192.168.0.0/24  Guest Wi-Fi     ← unique range, no overlap

This is where IP address management tools earn their keep. Tracking subnets is straightforward when every range is unique. You look at 10.0.1.0/24 and you know exactly what it is. Once you introduce VRFs, that same CIDR block can appear multiple times, once per VRF, and each instance represents a completely different set of devices. A spreadsheet struggles with this because it has no concept of routing context. You end up with duplicate rows that look like errors but are actually intentional, and there's no reliable way to filter or query by VRF. Traditional IPAM (IP Address Management) tools often handle VRFs as an afterthought, bolting on a text field that you can sort by but that doesn't actually enforce uniqueness rules correctly.

IPCraft models VLANs and VRFs as first-class objects. You create VRFs (like "production" and "development") and VLANs (like VLAN 10 and VLAN 110), then associate subnets with them. The uniqueness constraint in IPCraft works at the level of network plus VRF: the same CIDR block can exist in multiple VRFs but cannot be duplicated within a single VRF. This matches how real networks behave. When you view your subnet list, you can filter by VRF to see only the address space belonging to a specific routing context, or view everything across all VRFs at once. The API supports the same filtering, so your automation can query "give me the next free IP in 10.0.1.0/24 inside the production VRF" without any ambiguity.

Creating overlapping subnets in different VRFs via the API
# Create the same subnet in two different VRFs
# IPCraft allows this because the VRF context makes each unique

curl -X POST https://api.ipcraft.io/api/v1/subnets \
  -H "Authorization: Bearer ipc_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "10.0.1.0/24",
    "name": "Web servers",
    "vrf_id": "prod-vrf-uuid",
    "section_id": "sec_001"
  }'

curl -X POST https://api.ipcraft.io/api/v1/subnets \
  -H "Authorization: Bearer ipc_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "10.0.1.0/24",
    "name": "Web servers (dev)",
    "vrf_id": "dev-vrf-uuid",
    "section_id": "sec_002"
  }'

# Both succeed. Same CIDR, different VRFs.

A quick rule of thumb for deciding which technology you need. If you want to segment devices on the same physical network so they can't talk to each other directly, use VLANs. If you need two completely separate networks that happen to use the same IP address ranges, use VRFs. If you need both segmentation within an environment and isolation between environments, use both. Most small to mid-size networks get by with VLANs alone. VRFs become relevant when you manage multiple tenants, mirror environments with identical addressing, or interconnect with partners who use the same private address ranges your network uses.

The practical takeaway is that your IP management system needs to understand these concepts natively. An address like 10.0.1.5 is meaningless without knowing which VRF it belongs to, and a subnet like 10.0.1.0/24 might appear in three different VRFs for three different purposes. Any tool that treats IP addresses as globally unique will either reject valid overlapping configurations or create confusing duplicates with no way to tell them apart. Building VRF-awareness into the data model from the start, rather than patching it in later, is what makes the difference between a system that models your network accurately and one that forces you to work around its limitations.