Every “Cilium vs Calico” article you have read was probably written around one idea: Cilium is the modern eBPF one, Calico is the older iptables one. Today that idea is simply wrong. Cilium 1.20 was announced in September, Calico Open Source 3.33 shipped on October 1, and the two projects now overlap more than they differ. Calico has an eBPF dataplane and now supports netkit pod devices too. Both enforce the new Kubernetes ClusterNetworkPolicy. Both ship a Gateway API implementation.
So the honest question is no longer “which one is faster”. It is which policy model, which operating constraints and which ecosystem you are signing up for — and how hard it will be to change your mind later, because the CNI is the one cluster component you almost never get to swap cheaply. This is the comparison I wish I had before choosing one for a production platform: what each project actually does today, what GKE, EKS and AKS have already decided for you, and the traps that only show up during a migration.

The Short Answer
If you only read one section, read this one.
- Choose Cilium when your nodes are all Linux on a modern kernel and you want application-aware security in open source: L7 rules for HTTP, gRPC and Kafka, DNS-aware egress (
toFQDNs), flow observability through Hubble, a built-in Gateway API and multi-cluster networking through Cluster Mesh. It is also what you already run on GKE Dataplane V2 and on Azure CNI Powered by Cilium. - Choose Calico when the cluster is heterogeneous or bolted to physical infrastructure: Windows nodes, BGP peering with top-of-rack switches, older kernels that need an iptables or nftables dataplane, VMs and bare-metal hosts you want under the same policy, or many teams who need policy tiers with a clear precedence order.
- Choose neither consciously on EKS unless you have a reason: the Amazon VPC CNI is the only CNI Amazon supports on EC2 nodes, and it now enforces network policy natively.
The rest of this article explains why — and where each recommendation breaks.
What Cilium and Calico Actually Are
Cilium is an eBPF-based networking, security and observability project for Kubernetes, started by the founders of Isovalent. It joined the CNCF in 2021 and graduated in October 2023. Around the CNI itself sit Hubble for flow observability, a built-in Gateway API implementation and Cluster Mesh for multi-cluster networking.
Calico is created and maintained by Tigera. Calico Open Source is the free core that runs across clouds and distributions; Calico Cloud and Calico Enterprise are the commercial editions that add features such as DNS policy, egress gateways and multi-cluster management. Calico also reaches beyond Kubernetes pods to VMs, bare-metal hosts and OpenStack.
Both are open source, both are production-proven at very large scale, and both have a commercial company behind them. That matters less for features than for support: know which edition a feature belongs to before you plan around it.
What a CNI Actually Decides (and Why the Choice Is Sticky)
A Container Network Interface plugin is not just “the thing that gives pods an IP”. In a production cluster it owns four jobs:
- IP address management — which range a pod’s address comes from, and whether that range is routable outside the cluster.
- Connectivity — overlay (VXLAN, Geneve, IP-in-IP) or native routing, and whether nodes speak BGP to the network.
- Network policy — turning Kubernetes
NetworkPolicy(and often a richer CRD of its own) into packet filtering rules on every node. - Service load balancing — optionally replacing kube-proxy, so that traffic to a ClusterIP is translated in the CNI’s dataplane instead of in iptables chains.
Because the CNI owns the address plan and the dataplane, replacing it means re-addressing every pod. Platforms know this and lock it in. GKE states that Dataplane V2 “can only be enabled when creating a new cluster”. RKE2 does not support changing the primary CNI after first start. Treat this decision like choosing a database engine: you can migrate later, but you will pay for it.
Architecture: Identities in eBPF Maps vs a Policy Engine With Pluggable Dataplanes
The deepest difference between the two projects is not eBPF. It is how they represent “who is allowed to talk to whom”.
Cilium derives a numeric security identity from each pod’s labels and stores identities, endpoints, services and policy in eBPF maps in the kernel. When a packet arrives, an eBPF program looks up the source identity rather than evaluating a list of IP addresses. That makes policy independent of pod churn, and it is why Cilium can attach rich metadata to every flow for Hubble. The cost is that identities are a finite resource: Microsoft’s AKS documentation warns that high-churn workloads such as Spark jobs can push a cluster toward the 65,535 identity limit, and recommends excluding volatile labels from identity calculation.
Calico is built around Felix, an agent on every node that computes policy from labels and selectors and programs it into whichever dataplane you choose: iptables, nftables, eBPF, Windows or VPP. BGP routing has historically been handled by BIRD, which is why Calico is the natural fit for networks that already speak BGP. In 3.33 Felix, rather than BIRD, programs the cluster routes for IP-in-IP pools by default; BIRD programming of those routes is deprecated, with removal planned for 3.35.
Cilium is an eBPF dataplane with a policy model on top. Calico is a policy model with several dataplanes underneath. Most of the practical differences in this article follow from that one sentence.
Dataplanes Today: eBPF Everywhere, With Different Exits

Here is where the two stand after the autumn releases:
| Cilium 1.20 | Calico Open Source 3.33 | |
|---|---|---|
| Dataplanes | eBPF only | iptables, nftables, eBPF, Windows, VPP |
| kube-proxy replacement | Yes (eBPF) | Yes, in eBPF mode |
| Pod device | veth by default; bpf.datapathMode=auto selects netkit when the kernel supports it |
veth by default; netkit is an opt-in CNI device_type (kernel 6.7+), and eBPF programs attach through the netkit API when it is used |
| Kernel floor for eBPF | A modern kernel; check the system requirements for your release | 5.10+ with BTF/CO-RE — and a known 3.33 regression on 5.15 |
| Encryption | WireGuard, IPsec, plus sidecarless mTLS via ztunnel (beta) | WireGuard |
| BGP | Yes, via GoBGP | Yes, mature fabric peering; ARP-based L2 reachability without BGP or overlays is new in 3.33 |
| Windows nodes | No | Yes |
A few of these rows deserve a closer look.
netkit. netkit is a newer Linux network device designed to replace veth pairs for containers: the BPF program becomes part of the device itself instead of being attached to a veth pair from the outside, which removes overhead from the pod’s path. It originally required kernel 6.8. The Cilium 1.20 announcement points to netkit running at Meta and ByteDance scale, with ByteDance reporting around a 10% gain. Cilium’s new auto mode picks netkit when the kernel supports it and falls back to veth otherwise; the default stays veth. Calico 3.33 takes a smaller step: its CNI can create netkit pod devices through the opt-in device_type setting (kernel 6.7+, default veth), and the eBPF dataplane now attaches through the netkit API on those devices by default, using TCX elsewhere.
The iptables exit. Cilium has no non-eBPF fallback. If your fleet includes kernels or hardened images where eBPF is constrained, Calico’s ability to run the same policy on iptables or nftables is a real operational advantage, not a legacy feature. 3.33 also adds optional nftables flowtable offload, which lets established flows skip most of the ruleset.
Footprint. Both projects trimmed this year: the cilium-cni binary dropped from 76 MB to 16 MB in 1.20, and Calico 3.33 consolidates calico-node services, which Tigera puts at roughly 200 MB of memory saved per node, and ships a single quay.io/calico/calico image.
On a managed platform the operational limits come from the provider, not the project. Google documents, for example, that GKE Dataplane V2’s agent (anetd) can consume two to three vCPUs on nodes with a high rate of short-lived TCP connections, recommends keep-alives and connection pooling, and reserves 0.25% of node memory for the largest eBPF maps. None of this is a reason to avoid eBPF, but it is a reason to load-test your own traffic pattern instead of trusting anyone’s benchmark — including the vendors’.
Network Policy: The Difference You Will Actually Feel
Both projects enforce standard Kubernetes NetworkPolicy. If that is all you write, either will do. The differences start the moment you need more than L3/L4 rules inside one namespace.
Cilium network policy: L7 and DNS-aware rules in open source
Cilium adds CiliumNetworkPolicy and CiliumClusterwideNetworkPolicy. The headline capabilities are L7 rules — HTTP methods and paths, gRPC, Kafka — and DNS-aware egress. Here is a policy that lets only the checkout service call one endpoint of the payments API, and lets payments reach exactly one external hostname:
apiVersion: cilium.io/v2kind: CiliumNetworkPolicymetadata: name: payments-api namespace: shopspec: endpointSelector: matchLabels: app: payments ingress: - fromEndpoints: - matchLabels: app: checkout toPorts: - ports: - port: "8080" protocol: TCP rules: http: - method: POST path: "/v1/charges" egress: # Allow DNS so the FQDN rule below can learn IPs - toEndpoints: - matchLabels: "k8s:io.kubernetes.pod.namespace": kube-system "k8s:k8s-app": kube-dns toPorts: - ports: - port: "53" protocol: ANY rules: dns: - matchPattern: "*" - toFQDNs: - matchName: "api.stripe.com" toPorts: - ports: - port: "443" protocol: TCPA plain NetworkPolicy cannot express either rule. That is the core of Cilium’s appeal for zero-trust inside the cluster, and it is why both GKE (FQDN network policies) and AKS (FQDN filtering and L7 policies through Advanced Container Networking Services) built their premium networking features on top of it.
Calico network policy: tiers and governance in open source
Calico’s open-source edition answers a different question: who is allowed to override whom. Policies live in ordered tiers. A security team can own a high-precedence tier that application teams cannot circumvent, and a Pass action hands the decision down to the next tier:
apiVersion: projectcalico.org/v3kind: Tiermetadata: name: securityspec: order: 300---apiVersion: projectcalico.org/v3kind: GlobalNetworkPolicymetadata: name: security.isolate-prodspec: tier: security order: 100 namespaceSelector: env == "prod" types: - Ingress ingress: - action: Deny source: namespaceSelector: env == "dev" - action: PassDev can never reach prod, whatever an application team writes in its own namespace; everything else is passed down to the default tier, where ordinary Kubernetes policies live. Add staged policies — preview what a policy would allow or deny before enforcing it — and host endpoints, which put nodes, VMs and bare-metal servers under the same label-based policy, and you have a strong platform-team toolkit.
What Calico Open Source does not include is DNS-based policy: Tigera’s own feature matrix lists DNS/FQDN policy, egress gateways and Cluster Mesh as Calico Cloud and Calico Enterprise features. If FQDN egress is a hard requirement and you want to stay on open source, that alone can decide the comparison.
The common ground: ClusterNetworkPolicy
The good news is that the Kubernetes community is closing the gap for cluster-wide rules. ClusterNetworkPolicy (policy.networking.k8s.io/v1alpha2) gives platform teams an Admin tier that overrides namespace policies and a Baseline tier that namespace policies can override:
apiVersion: policy.networking.k8s.io/v1alpha2kind: ClusterNetworkPolicymetadata: name: deny-dev-to-prodspec: tier: Admin priority: 10 subject: namespaces: matchLabels: env: prod ingress: - name: deny-from-dev action: Deny from: - namespaces: matchLabels: env: devCilium 1.20 added support for it. Calico maps it straight into tiers: Admin policies land in a built-in kube-admin tier and Baseline policies in kube-baseline, and 3.33 supports named ports in them. One caution: EKS implements the same idea natively in the VPC CNI, but under its own API group, networking.k8s.aws/v1alpha1. Copying YAML between clouds is not as portable as the name suggests.
Observability: Hubble vs Whisker
Debugging network policy without flow visibility is guesswork, so this matters more than it looks on a feature list.
Cilium’s Hubble is the most mature open-source answer: per-flow visibility with source and destination identities, L7 metadata where an L7 policy applies, and policy verdicts. In 1.20 Hubble can also correlate audit-mode verdicts with the policy that produced them, which makes “what would break if I enforced this” a question you can answer from data. On managed platforms the same idea surfaces as GKE Dataplane V2 observability and network policy logging, and as Container Network Observability in AKS.
Calico’s Whisker is a web console for flow logs, fed by a flow aggregator and backed by a flow logs API — both still a technology preview in 3.33. Retention in the open-source edition is in-memory; longer retention, dashboards and the service graph are part of the commercial editions. Calico’s real observability strength is its staged policies: you can see the effect of a policy change on live flows before it enforces anything.
If observability is your main driver, Cilium has the lead in open source today. If your main fear is breaking production with a policy change, Calico’s staged workflow is the more direct tool.
Encryption and mTLS
Both projects encrypt pod-to-pod traffic between nodes with WireGuard, which is the simple default for “encrypt everything in transit” requirements. Cilium also supports IPsec.
The most interesting recent development is on the Cilium side: sidecarless mutual TLS using ztunnel, built with Microsoft and Isovalent. It is beta since 1.19, runs TLS 1.3 over HBONE, is switched on per namespace with the label io.cilium/mtls-enabled=true, and can use an internal CA or SPIRE. Unlike node-to-node WireGuard or IPsec, it also encrypts traffic between pods on the same node. Cilium’s older Mutual Authentication feature is deprecated in its favour. Calico’s equivalent path is integration with Istio ambient mode, which is still a technology preview in 3.33.
One compliance note for regulated environments: Calico 3.33 removed FIPS mode. If your current deployment depends on it, do not upgrade on autopilot — check with your auditors and with Tigera before you plan the next release.
Gateway API: Both Ship One, Built Differently
With Ingress NGINX reaching end-of-life in March 2026, the north-south story matters more than usual.
- Cilium implements Gateway API natively through its built-in Envoy proxy. 1.20 moves to Gateway API v1.6: TCPRoute and UDPRoute (now in the Standard channel), ListenerSets, a CORS filter, 303/307/308 redirects and an ExternalAuth filter that forwards a request to an auth service and acts on its 200, 302, 401 or 403 answer.
- Calico ships the Calico Ingress Gateway, a bundled Envoy Gateway — v1.9.1 in 3.33 with Gateway API CRDs v1.6.1, which requires Kubernetes 1.33 or newer.
Either is a reasonable replacement for Ingress NGINX. The architectural difference is that Cilium’s gateway is built into the CNI you already run, while Calico’s is a separate Envoy Gateway deployment that it packages and manages. On GKE you will usually use Google’s own Gateway controller instead — see GKE Gateway API vs Ingress for that decision.
What GKE, EKS and AKS Have Already Decided for You

On a managed service, “Cilium vs Calico” is usually a smaller question than it looks.
GKE. Dataplane V2 is implemented with Cilium, runs as the anetd DaemonSet, is the default for new Autopilot clusters and is Google’s recommended network plugin for all clusters. Network policy is always on, network policy logging is built in, and GKE does not use kube-proxy for Services on it. The legacy dataplane is Calico-based and is available only on Standard clusters; enabling it recreates nodes and costs roughly 128 MB of memory and 300 millicores of CPU in kube-system. Two limits worth knowing: Dataplane V2 cannot be enabled on existing clusters, and clusters that use the CiliumNetworkPolicy CRD are capped at 1,000 nodes, while CiliumClusterwideNetworkPolicy supports up to 5,000. GKE also does not support installing your own eBPF programs on Dataplane V2 nodes — a real constraint if you planned to add eBPF-based tooling. For the wider hardening picture, see the secure-by-default GKE reference architecture.
EKS. The Amazon VPC CNI is the only CNI Amazon EKS supports on EC2 nodes; Fargate runs only the VPC CNI, and EKS Auto Mode does not support alternate CNI or network policy plugins. From VPC CNI 1.21 it enforces both standard network policies and an Admin ClusterNetworkPolicy natively. You can still install Cilium or Calico — AWS lists Isovalent and Tigera as partners — but AWS recommends commercial support or in-house expertise if you do. On EKS Hybrid Nodes, by contrast, Amazon supports the core capabilities of both Cilium and Calico. One sharp edge: traffic to and from pods with security groups for pods is not subject to Calico policy enforcement, only to the security groups.
AKS. Microsoft recommends Azure CNI Powered by Cilium for network policy, and it is the default network configuration in AKS Automatic. It runs without kube-proxy, is Linux-only, and supports CiliumNetworkPolicy and CiliumClusterwideNetworkPolicy out of the box; FQDN filtering, L7 policy, WireGuard and flow observability come through Advanced Container Networking Services. Calico is supported for standard Kubernetes network policies only — AKS does not test or support its other features — but it is the engine that covers Windows node pools. With Azure Network Policy Manager no longer supported on Windows nodes since September 30, 2026 and scheduled for retirement on Linux in 2028, that makes the AKS picture simple: Cilium for Linux, Calico where you have Windows.
Self-managed distributions. k3s defaults to Flannel with kube-router for network policy; to run Cilium or Calico instead, start the server with --flannel-backend=none and --disable-network-policy, then install the CNI. RKE2 bundles Canal (the default — Flannel between nodes, Calico for policy), Cilium, Calico and Flannel. Only Calico and Flannel support Windows nodes there, and Canal is not supported on clusters with Windows nodes. If you are still choosing a distribution, the k3s vs k0s vs MicroK8s vs RKE2 comparison covers those defaults in more detail.
On GKE and AKS, choosing Cilium mostly means accepting the platform default. The real Cilium-vs-Calico decision lives on self-managed clusters, on-prem, at the edge, and anywhere Windows nodes or a BGP fabric are involved.
Scale and Multi-Cluster
Both projects run very large clusters; the differences are in how they connect clusters to each other.
Cilium Cluster Mesh is part of open source: it connects up to 255 clusters by default, provides cross-cluster service discovery and policy, and 1.20 marks its implementation of the Kubernetes Multi-Cluster Services API as stable. A new cluster-mesh policy entity lets you write rules about “any workload in the mesh” without enumerating clusters.
Calico takes a network-first approach: with BGP you can peer clusters and the physical fabric so pod IPs are routable across them. Calico’s managed multi-cluster product, Cluster Mesh, and multi-cluster policy management belong to Calico Cloud and Calico Enterprise rather than the open-source edition.
If “many clusters, one service and policy model” is the requirement and you want to stay on open source, Cilium is ahead. If “pods as first-class citizens of my routed datacenter network” is the requirement, Calico’s BGP heritage is the reason it exists.
Migrating From Calico to Cilium: Read This Before You Plan It
Most teams that compare the two are already running Calico and wondering whether to move. Cilium has a documented live-migration path, and it is genuinely clever: install Cilium in a secondary mode with a separate pod CIDR, cluster-pool IPAM and a distinct encapsulation port (the example uses VXLAN on port 8473), so both overlays coexist and the Linux routing table separates their traffic. Then, node by node: cordon and drain, label the node so a CiliumNodeConfig makes Cilium write its CNI config, restart the Cilium agent, reboot, verify, uncordon.
Then read the limitations section of the same guide. Migration has not been tested with BGP-based routing, nor with an existing NetworkPolicy provider — and Cilium’s own policy enforcement has to run with policyEnforcementMode: never during the migration, because otherwise traffic from not-yet-migrated pods could be dropped. A production Calico cluster almost always has policies, and many on-prem ones use BGP. In other words, the clusters most likely to want this migration are exactly the ones it was not tested on.
A pragmatic order of operations:
- Inventory your policies and translate them, paying special attention to
ipBlockrules and Calico tiers, which have no one-to-one Cilium equivalent. - Rehearse on a clone of the cluster, with a connectivity monitor running, as the guide itself strongly recommends.
- Decide whether a policy-free window is acceptable. If it is not, build a new Cilium cluster and move workloads with a blue/green or GitOps-driven cutover instead.
- On AKS, use the supported in-place dataplane upgrade from Azure CNI to Cilium (kubenet clusters move to Azure CNI Overlay first). On GKE, there is no in-place path to Dataplane V2: it is a new cluster.
Gotchas Worth Knowing Before You Upgrade
Calico 3.33
- eBPF on kernel 5.15 is broken in 3.33 — a known regression: the host endpoint program grew past the verifier limit. The workaround is kernel 6.8 or newer, or staying on 3.32. This matters for anyone on Ubuntu 22.04 images, including the default AKS node image for Kubernetes 1.25 through 1.34.
- FIPS mode is gone. Regulated deployments need a plan before upgrading.
- Native v3 CRDs are GA and the aggregated API server is deprecated, which simplifies installs but changes how tooling talks to Calico resources.
- BIRD programming of IP-in-IP cluster routes is deprecated, with removal planned for 3.35; Felix now owns those routes by default.
Cilium 1.20
- Legacy Mutual Authentication is deprecated in favour of ztunnel-based mTLS.
cilium-dbg bgpcommands are deprecated in favour of new shell commands for the GoBGP-based control plane.- Identity churn remains the classic scaling trap: exclude high-cardinality labels before they exhaust the identity space.
- On GKE, other eBPF-based tools can interfere with Dataplane V2; Google documents a case where Microsoft Retina prevented pods from reaching Services.
How to Decide in Five Questions

- Do you run Windows nodes? Then Calico, at least for those nodes. Cilium does not support Windows.
- Are you on GKE or AKS? Use the platform’s Cilium-based dataplane unless you have a specific reason not to. On EKS, start from the VPC CNI’s native network policy.
- Do you need L7 policy, FQDN egress or multi-cluster networking in open source? That points to Cilium.
- Do pods need to be routable on a BGP fabric, or do VMs and bare-metal hosts need the same policy as pods? That points to Calico.
- Do several teams write policy, with a security team that must always win? Calico’s tiers are the most direct model; on Cilium, the new
ClusterNetworkPolicyAdmin and Baseline tiers now cover the common cases.
The Bottom Line
Today Cilium and Calico are both excellent, both run eBPF, and both are converging on the same upstream APIs: Gateway API for traffic in, ClusterNetworkPolicy for platform guardrails. Choosing between them by benchmark is choosing by the least important difference.
Cilium is the better default for a Linux-only, cloud-native cluster that wants to understand its traffic at L7 — and on GKE and AKS it is the default already. Calico is the better choice for a heterogeneous or infrastructure-bound cluster: Windows nodes, BGP fabrics, older kernels, VMs under the same policy, and organisations where policy governance matters more than packet-level magic.
Whichever you pick, pick it as if you will keep it for the life of the cluster, because the migration is where the real cost lives. And before you trust any policy — including the ones you wrote for the other CNI — check your ipBlock rules.
Related reading: for the platform built on top of the network, see platform engineering on Kubernetes; for what the managed services actually run for you, see what EKS, AKS and GKE actually manage.




From the community
Discussion on the Fediverse
Replies from Mastodon and Bluesky — straight from the open web, no tracking.
Loading replies …
No replies yet. Start the conversation:
Replies could not be loaded right now.