Fundamentals 6 min read

Why Accessing a Local Server via 127.0.0.1 Is Not Faster Than Using the Machine’s Own IP

Accessing a service on the same host using 127.0.0.1 offers no performance advantage over using the host’s own IP address because the Linux kernel routes both destinations through the loopback interface, as demonstrated by source‑code analysis and packet‑capture experiments.

Refining Core Development Skills
Refining Core Development Skills
Refining Core Development Skills
Why Accessing a Local Server via 127.0.0.1 Is Not Faster Than Using the Machine’s Own IP

When a client connects to a server running on the same machine, many wonder whether using the loopback address 127.0.0.1 is faster than using the machine’s own IP (e.g., 192.168.x.x ). The author’s conclusion, based on kernel behavior, is that there is no measurable performance difference.

1. Relevant Source‑Code Analysis

First point: All entries in the local routing table are marked with RTN_LOCAL . The kernel decides which device to use during routing in the function __ip_route_output_key .

struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
{
    if (fib_lookup(net, fl4, &res)) {
    }
    if (res.type == RTN_LOCAL) {
        dev_out = net->loopback_dev;
        ...
    }
    rth = __mkroute_output(&res, fl4, orig_oif, dev_out, flags);
    return rth;
}

This function queries the local routing table, which can be listed with:

# ip route list table local
local 10.162.*.* dev eth0  proto kernel  scope host  src 10.162.*.*
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1

Although the table shows an entry for the physical interface (e.g., eth0 ), the kernel sets the type of all local routes to RTN_LOCAL during initialization via the fib_inetaddr_event notifier.

static int fib_inetaddr_event(struct notifier_block *this,
                                 unsigned long event, void *ptr)
{
    switch (event) {
    case NETDEV_UP:
        fib_add_ifaddr(ifa);
        break;
    case NETDEV_DOWN:
        fib_del_ifaddr(ifa, NULL);
    }
}

Both RTN_LOCAL routes are forced to use the loopback virtual device ( lo ).

2. Practical Verification

To confirm the behavior, the author captured packets on two interfaces. First, a tcpdump on eth0 while sending traffic to the host’s IP on port 8888:

# tcpdump -i eth0 port 8888

Then a telnet attempt from another terminal:

# telnet 10.162.*.* 8888
Trying 10.162.*.*...
telnet: connect to address 10.162.*.*: Connection refused

No packets appear on eth0 , indicating the traffic never left the host.

Repeating the capture on the loopback interface shows the packets:

# tcpdump -i lo port 8888
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
08:22:31.956702 IP 10.162.*.*.62705 > 10.162.*.*.ddi-tcp-1: Flags [S], seq 678725385, win 43690, length 0
08:22:31.956720 IP 10.162.*.*.ddi-tcp-1 > 10.162.*.*.62705: Flags [R.], seq 0, ack 678725386, win 0, length 0

Conclusion

Many people intuitively think that using 127.0.0.1 is faster because it avoids the physical NIC. In reality, the kernel knows all local IP addresses and routes traffic destined for any of them through the loopback device, so the performance cost is essentially identical.

GitHub repository for the examples: https://github.com/yanfeizhang/coder-kung-fu

Linux kernelloopbacknetwork performanceIP addresslocal routing
Refining Core Development Skills
Written by

Refining Core Development Skills

Fei has over 10 years of development experience at Tencent and Sogou. Through this account, he shares his deep insights on performance.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.