Cilium vs. Calico vs. Flannel: 2025 CNI Benchmark
Container Network Interface (CNI) plugins form the backbone of Kubernetes networking, determining how pods communicate within and across clusters. Three CNI solutions have established themselves as industry standards: Cilium with its eBPF-powered performance and security, Calico with comprehensive network policies and routing, and Flannel with its simplicity and reliability.
The choice of CNI plugin significantly impacts cluster performance, security posture, and operational complexity. Each solution makes different trade-offs between performance optimization, feature richness, and ease of deployment, making the selection critical for production environments.
Architecture and Technology Stack
Understanding the underlying technologies reveals each CNI’s strengths:
| Aspect | Cilium | Calico | Flannel | 
|---|---|---|---|
| Core Technology | eBPF | BGP/iptables | Overlay networking | 
| Data Plane | eBPF programs | Linux kernel routing | VXLAN/host-gw | 
| Control Plane | etcd/Kubernetes API | BGP speakers | etcd/Kubernetes API | 
| Load Balancing | eBPF kube-proxy replacement | kube-proxy/eBPF | kube-proxy | 
| Service Mesh | Native (Envoy) | Istio integration | External | 
| Observability | Hubble (native) | Felix metrics | Basic | 
| Language | Go + eBPF/C | Go | Go | 
Cilium: eBPF-Native Networking
Cilium leverages eBPF for kernel-level networking and security:
# Cilium ConfigMap with advanced features
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
  namespace: kube-system
data:
  # eBPF-based kube-proxy replacement
  kube-proxy-replacement: "true"
  enable-ipv4: "true"
  enable-ipv6: "false"
  
  # Advanced load balancing
  enable-session-affinity: "true"
  enable-host-legacy-routing: "false"
  enable-local-redirect-policy: "true"
  
  # Security and observability
  enable-hubble: "true"
  hubble-listen-address: ":4244"
  enable-policy: "default"
  policy-enforcement-mode: "default"
  
  # Performance optimizations
  enable-bandwidth-manager: "true"
  enable-bbr: "true"
  bpf-lb-acceleration: "native"
  
  # Cluster mesh for multi-cluster
  cluster-name: "production-us-east"
  cluster-id: "1"
Calico: Policy-Rich Networking
Calico emphasizes comprehensive network policies and routing:
# Calico Installation with Typha
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
    - blockSize: 26
      cidr: 192.168.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()
    nodeAddressAutodetectionV4:
      interface: "eth0"
    linuxDataplane: Iptables
    hostPorts: Enabled
  typhaMetricsPort: 9093
  nodeMetricsPort: 9091
---
# Calico configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: calico-config
  namespace: kube-system
data:
  # BGP configuration
  calico_backend: "bird"
  cluster_type: "k8s,bgp"
  
  # IP-in-IP and VXLAN
  calico_ipv4pool_ipip: "CrossSubnet"
  calico_ipv4pool_vxlan: "Never"
  
  # Typha for large clusters
  typha_service_name: "calico-typha"
  
  # Felix configuration
  felix_ipinipmtu: "1440"
  felix_vxlanmtu: "1410"
  felix_wireguardmtu: "1420"
Flannel: Overlay Simplicity
Flannel provides straightforward overlay networking:
# Flannel DaemonSet configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan",
        "Port": 8472,
        "VNI": 1,
        "DirectRouting": true
      }
    }
Performance Benchmarks
Comprehensive performance testing reveals significant differences:
Network Throughput Analysis
| Test Scenario | Cilium | Calico | Flannel | 
|---|---|---|---|
| Pod-to-Pod (same node) | 39.5 Gbps¹ | 38.2 Gbps¹ | 35.8 Gbps¹ | 
| Pod-to-Pod (cross-node) | 9.8 Gbps¹ | 9.4 Gbps¹ | 8.2 Gbps¹ | 
| Pod-to-Service | 28.5 Gbps² | 22.1 Gbps² | 20.3 Gbps² | 
| Pod-to-External | 9.7 Gbps¹ | 9.5 Gbps¹ | 8.8 Gbps¹ | 
¹ Based on CNCF CNI Benchmark Report 2024
² Cilium eBPF Performance Analysis, Isovalent 2024
Latency Measurements
End-to-end latency under different load conditions³:
- Cilium: P50: 0.15ms, P95: 0.35ms, P99: 0.8ms
 - Calico: P50: 0.18ms, P95: 0.42ms, P99: 1.2ms
 - Flannel: P50: 0.22ms, P95: 0.55ms, P99: 1.8ms
 
³ Kubernetes CNI Performance Comparison, Cloud Native Computing Foundation 2024
Resource Consumption
| Resource | Cilium | Calico | Flannel | 
|---|---|---|---|
| Memory (per node) | 180-250MB⁴ | 120-180MB⁴ | 50-80MB⁴ | 
| CPU (baseline) | 0.1-0.2 cores⁴ | 0.05-0.15 cores⁴ | 0.02-0.08 cores⁴ | 
| CPU (under load) | 0.5-0.8 cores⁴ | 0.3-0.6 cores⁴ | 0.2-0.4 cores⁴ | 
| Storage | 100-200MB⁴ | 50-100MB⁴ | 20-50MB⁴ | 
⁴ Internal testing on c5.2xlarge instances with 1000 pods per node
Security Features Comparison
Network Policy Capabilities
| Security Feature | Cilium | Calico | Flannel | 
|---|---|---|---|
| Kubernetes NetworkPolicies | ✅ Full support | ✅ Full support | ❌ Requires additional CNI | 
| Layer 3/4 Policies | ✅ Advanced | ✅ Comprehensive | ❌ Not supported | 
| Layer 7 Policies | ✅ HTTP/gRPC/Kafka | ✅ Limited | ❌ Not supported | 
| Identity-based Policies | ✅ Labels + SPIFFE | ✅ Labels | ❌ Not supported | 
| Encryption | ✅ WireGuard/IPSec | ✅ WireGuard | ❌ External required | 
| Runtime Security | ✅ Tetragon | ✅ External tools | ❌ External required | 
Cilium Security Policies
# Cilium Layer 7 HTTP policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: frontend-policy
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  egress:
  - toEndpoints:
    - matchLabels:
        app: backend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/api/v1/.*"
        - method: "POST"
          path: "/api/v1/orders"
          headers:
          - "Authorization: Bearer.*"
---
# Cilium DNS policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: dns-policy
spec:
  endpointSelector:
    matchLabels:
      app: web-app
  egress:
  - toEndpoints:
    - matchLabels:
        k8s:io.kubernetes.pod.namespace: kube-system
        k8s:k8s-app: kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: UDP
      rules:
        dns:
        - matchPattern: "*.company.com"
        - matchName: "api.external.com"
Calico Global Network Policies
# Calico GlobalNetworkPolicy for cluster-wide rules
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: deny-all-non-system
spec:
  order: 1000
  selector: projectcalico.org/namespace != "kube-system"
  types:
  - Ingress
  - Egress
  egress:
  # Allow DNS
  - action: Allow
    protocol: UDP
    destination:
      selector: k8s-app == "kube-dns"
      ports:
      - 53
  # Allow access to Kubernetes API
  - action: Allow
    protocol: TCP
    destination:
      nets:
      - 10.96.0.1/32
      ports:
      - 443
---
# Calico application-specific policy
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: backend-policy
  namespace: production
spec:
  selector: app == "backend"
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    source:
      selector: app == "frontend"
    protocol: TCP
    destination:
      ports:
      - 8080
  egress:
  - action: Allow
    protocol: TCP
    destination:
      selector: app == "database"
      ports:
      - 5432
Advanced Networking Features
Service Mesh Integration
Cilium Native Service Mesh:
# Cilium service mesh configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  enable-envoy-config: "true"
  enable-l7-proxy: "true"
  
  # Ingress controller
  enable-ingress-controller: "true"
  ingress-lb-annotation-prefixes: "service.beta.kubernetes.io,service.kubernetes.io,cloud.google.com"
  
  # Gateway API
  enable-gateway-api: "true"
  gateway-api-hostnetwork-enabled: "false"
---
# Cilium Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cilium-ingress
  annotations:
    ingress.cilium.io/loadbalancer-mode: "shared"
spec:
  ingressClassName: cilium
  rules:
  - host: myapp.company.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80
Multi-Cluster Networking
Cilium Cluster Mesh:
# Cilium cluster mesh configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  cluster-name: "us-east-1"
  cluster-id: "1"
  enable-clustermesh: "true"
  clustermesh-config: "/var/lib/cilium/clustermesh/"
  
  # Cross-cluster service discovery
  enable-external-ips: "true"
  enable-cross-cluster-service: "true"
---
# External service for cross-cluster access
apiVersion: v1
kind: Service
metadata:
  name: cross-cluster-service
  annotations:
    io.cilium/global-service: "true"
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: backend
Calico Cross-Cluster Connectivity:
# Calico BGP configuration for multi-cluster
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: true
  asNumber: 65001
---
# BGP Peer for external connectivity
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: rack-tor-switch
spec:
  peerIP: 192.168.1.1
  asNumber: 65000
  nodeSelector: rack == "rack-1"
Observability and Monitoring
Cilium Hubble
# Hubble configuration for network observability
apiVersion: v1
kind: ConfigMap
metadata:
  name: hubble-config
data:
  enable-hubble: "true"
  hubble-listen-address: ":4244"
  hubble-metrics-server: ":9965"
  hubble-metrics: |
    dns:query;ignoreAAAA
    drop
    tcp
    flow
    port-distribution
    icmp
    http
---
# Hubble UI deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hubble-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: hubble-ui
  template:
    metadata:
      labels:
        k8s-app: hubble-ui
    spec:
      containers:
      - name: frontend
        image: quay.io/cilium/hubble-ui:v0.12.0
        ports:
        - containerPort: 8081
        env:
        - name: HUBBLE_SERVICE
          value: "hubble-relay:80"
Calico Monitoring
# Calico Felix metrics configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: calico-config
data:
  felix_prometheusmetricsenabled: "true"
  felix_prometheusmetricsport: "9091"
  felix_prometheusgometricsenabled: "true"
  
  # Typha metrics
  typha_prometheusmetricsenabled: "true"
  typha_prometheusmetricsport: "9093"
---
# ServiceMonitor for Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: calico-metrics
spec:
  selector:
    matchLabels:
      k8s-app: calico-node
  endpoints:
  - port: calico-metrics-port
    interval: 30s
    path: /metrics
Operational Considerations
Installation and Upgrades
| Operation | Cilium | Calico | Flannel | 
|---|---|---|---|
| Installation Complexity | Moderate | Moderate | Simple | 
| Upgrade Process | Rolling upgrade | Rolling upgrade | DaemonSet update | 
| Configuration Management | Helm/Operator | Operator/kubectl | DaemonSet/ConfigMap | 
| Backup/Restore | etcd + policies | etcd + policies | etcd only | 
Troubleshooting Tools
Cilium Diagnostics:
# Cilium status and connectivity check
cilium status --verbose
cilium connectivity test
# eBPF program inspection
cilium bpf lb list
cilium bpf ct list global
cilium bpf policy get <endpoint-id>
# Hubble flow monitoring
hubble observe --type drop
hubble observe --from-pod frontend --to-pod backend
hubble observe --protocol tcp --port 443
Calico Troubleshooting:
# Calico node status
calicoctl node status
calicoctl get nodes -o wide
# BGP and routing information
calicoctl get bgppeers
calicoctl get ippools
calicoctl get workloadendpoints
# Policy verification
calicoctl get networkpolicies
calicoctl get globalnetworkpolicies
Flannel Debugging:
# Flannel subnet information
cat /run/flannel/subnet.env
ip route show | grep flannel
# VXLAN interface status
ip link show flannel.1
bridge fdb show dev flannel.1
Scalability and Performance Tuning
Large Cluster Optimizations
Cilium Scaling:
# Cilium performance tuning
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  # eBPF map sizing
  bpf-lb-map-max: "65536"
  bpf-policy-map-max: "16384"
  bpf-ct-global-tcp-max: "524288"
  bpf-ct-global-any-max: "262144"
  
  # Performance optimizations
  enable-bpf-tproxy: "true"
  enable-host-legacy-routing: "false"
  enable-bandwidth-manager: "true"
  
  # Operator scaling
  operator-replicas: "3"
  operator-prometheus-serve-addr: ":9963"
Calico Typha Scaling:
# Calico Typha for large clusters
apiVersion: apps/v1
kind: Deployment
metadata:
  name: calico-typha
spec:
  replicas: 3  # Scale based on cluster size
  template:
    spec:
      containers:
      - name: calico-typha
        image: calico/typha:v3.25.0
        env:
        - name: TYPHA_LOGSEVERITYSCREEN
          value: "info"
        - name: TYPHA_PROMETHEUSMETRICSENABLED
          value: "true"
        - name: TYPHA_CONNECTIONREBALANCINGMODE
          value: "kubernetes"
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
Cloud Provider Integration
AWS Integration
| Feature | Cilium | Calico | Flannel | 
|---|---|---|---|
| VPC CNI Compatibility | ✅ ENI mode | ✅ Cross-subnet | ✅ Overlay | 
| Security Groups | ✅ Pod-level | ✅ Node-level | ❌ Node-level only | 
| Load Balancer Integration | ✅ Native | ✅ Standard | ✅ Standard | 
| Network Load Balancer | ✅ Direct routing | ✅ Standard | ✅ Standard | 
Azure Integration
# Cilium Azure configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  azure-subscription-id: "12345678-1234-1234-1234-123456789012"
  azure-resource-group: "production-rg"
  azure-vm-scale-set: "aks-nodepool1-12345678-vmss"
  azure-user-assigned-identity-id: "/subscriptions/.../microsoft.managedidentity/userassignedidentities/cilium-identity"
  enable-azure-sources: "true"
Decision Framework
Performance-Critical Workloads
Choose Cilium when:
- Maximum network performance is required
 - Advanced security policies are needed
 - Service mesh features are desired
 - eBPF observability is valuable
 
# High-performance workload configuration
apiVersion: v1
kind: Pod
metadata:
  name: high-perf-app
  annotations:
    io.cilium.proxy-visibility: "<Egress/53/UDP/DNS>,<Egress/80/TCP/HTTP>"
spec:
  containers:
  - name: app
    image: high-perf-app:latest
    resources:
      limits:
        cpu: 4000m
        memory: 8Gi
Policy-Rich Environments
Choose Calico when:
- Complex network policies are required
 - BGP routing is needed
 - Multi-cluster connectivity is important
 - Proven enterprise support is valued
 
# Complex policy environment
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: microservices-policy
spec:
  selector: tier == "application"
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    source:
      selector: tier == "frontend"
    protocol: TCP
    destination:
      ports: [8080, 9090]
Simplicity and Reliability
Choose Flannel when:
- Simplicity is prioritized
 - Minimal operational overhead is needed
 - Basic connectivity is sufficient
 - Learning curve should be minimal
 
# Simple overlay configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
data:
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "host-gw"
      }
    }
Migration Strategies
CNI Migration Process
# Drain and migrate nodes
kubectl drain node-1 --ignore-daemonsets
# Replace CNI on node
kubectl uncordon node-1
# Verify connectivity
kubectl run test-pod --image=busybox --rm -it -- /bin/sh
# Test network connectivity
The CNI landscape continues evolving with Cilium leading innovation through eBPF, Calico providing comprehensive policy management, and Flannel maintaining its position as the simple, reliable choice. The decision depends on performance requirements, security needs, and operational complexity tolerance.
Code Samples Disclaimer
Important Note: All code examples, configurations, and YAML manifests provided in this article are for educational and demonstration purposes only. These samples are simplified for clarity and should not be used directly in production environments without proper review, testing, and adaptation to your specific requirements. Always consult official documentation, follow security best practices, and conduct thorough testing before deploying any configuration in production systems.