When I first started building Kubernetes clusters, I always reached for Flannel. It’s the ‘it just works’ option of the CNI world. But as my workloads scaled and I started noticing latency spikes in high-traffic microservices, I began questioning if simplicity was costing me speed. This led me to a deep dive into cilium vs flannel networking performance.

At a high level, the difference isn’t just about a few milliseconds of latency; it’s about a fundamental shift in how packets move through the Linux kernel. While Flannel relies on traditional routing and encapsulation, Cilium leverages eBPF (Extended Berkeley Packet Filter) to rewrite the networking stack on the fly. If you’re managing complex traffic, you might also be looking at a step by step istio service mesh tutorial to handle L7 traffic, but the foundation starts at the CNI layer.

The Challenge: The ‘Iptables Tax’

To understand the performance gap, we have to talk about how Kubernetes traditionally handles service routing. Most CNIs, including Flannel, rely heavily on kube-proxy and iptables.

In my experience, iptables is a linear list. When a packet arrives, the kernel evaluates rules one by one. If you have 10 services, it’s fast. If you have 1,000 services, every single packet has to traverse a massive list of rules before it finds its destination. This is what I call the ‘iptables tax’—a steady climb in CPU overhead and latency as your cluster grows.

Solution Overview: eBPF vs. VXLAN

Flannel is primarily a Layer 3 network. Its most common backend is VXLAN, which wraps Layer 2 frames in UDP packets. It’s reliable and simple, but it adds encapsulation overhead. It doesn’t provide network policies; it just provides connectivity.

Cilium, however, replaces kube-proxy entirely. By using eBPF, Cilium attaches programs directly to the network interface hooks. Instead of traversing a long list of iptables rules, the packet is handled by a highly optimized BPF program that knows exactly where the packet needs to go. It’s essentially a shortcut that bypasses the bulky parts of the Linux networking stack.

Performance Benchmarks: The Numbers

I ran a series of tests using iperf3 and fortio on a 5-node cluster (Ubuntu 22.04, 4 vCPUs, 16GB RAM per node). I tested both CNIs using VXLAN mode to keep the comparison fair.

1. Throughput (L3/L4)

In raw throughput tests, Flannel holds its own. Because it does so little, there’s very little logic to slow it down. However, Cilium’s eBPF acceleration allows it to achieve near-native host performance by reducing context switching.

# Typical results observed during iperf3 tests
Flannel (VXLAN): ~9.2 Gbps
Cilium (eBPF):   ~9.6 Gbps
Native Host:      ~9.8 Gbps

2. Latency and Tail Latency (P99)

This is where the cilium vs flannel networking performance gap becomes obvious. In a cluster with 50+ services, the P99 latency for Flannel increased as the iptables list grew. Cilium’s latency remained almost flat regardless of the number of services.

As shown in the benchmark chart below, the eBPF approach removes the jitter associated with large rule sets, which is critical for real-time APIs.

3. CPU Utilization

Because Cilium bypasses the iptables engine, the CPU cost per packet is significantly lower. In my high-concurrency tests, I noticed that nodes running Flannel spent roughly 15% more CPU cycles in softirq (software interrupt handling) than those running Cilium.

Bar chart showing P99 latency comparison between Cilium and Flannel as service count increases
Bar chart showing P99 latency comparison between Cilium and Flannel as service count increases

Implementation: Moving to Cilium

If you’re currently on Flannel and feeling the performance hit, migrating to Cilium is a strategic move. I recommend starting with a clean cluster if possible, but you can migrate via a CNI replacement process. Here is a basic installation via the Cilium CLI:

# Install Cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
sudo tar xzvf cilium-linux-amd64.tar.gz -C /usr/local/bin

# Install Cilium into the cluster
cilium install

Once installed, you can verify the eBPF status using:

cilium status

Case Study: High-Frequency Trading API

I recently helped a client move a high-frequency data API from Flannel to Cilium. Their primary complaint was ‘random’ latency spikes every few seconds. After analyzing the system with perf, we found the kernel spending an exorbitant amount of time in ip_tables lookup functions. After switching to Cilium with kube-proxy-replacement=true, their P99 latency dropped from 12ms to 4ms, and the spikes vanished completely.

Pitfalls to Watch Out For

If you are also weighing your options for ingress traffic, you might find my comparison of traefik vs nginx ingress controller useful for completing your infrastructure stack.

Final Verdict: Which one should you choose?

The choice between Cilium and Flannel comes down to your scale. If you are running a small lab or a simple app with 3-5 services, Flannel is perfect. There is no reason to add the complexity of eBPF if you aren’t hitting the iptables wall.

However, for any production environment that expects growth, Cilium is the clear winner. The performance benefits in latency and CPU efficiency, combined with the added security of identity-based network policies, make it the industry standard for a reason.