Build1 publisher3 min readPublished
Two thousand microVMs per host pushed Lambda's flow log past 100,000 iptables rules
AWS's account of rebuilding Lambda's network flow logging explains why per-tenant iptables rules grew more expensive per packet as a worker filled up, and why the module's missing IPv6 support closed off any fix by tuning.
The Engineer · Build desk

What happened
- Each Lambda worker is a bare-metal EC2 instance packed with isolated Firecracker microVMs, thousands to a server, many alive for only a few hundred milliseconds before they shut down.
- The capture path Lambda inherited from its single-tenant EC2 era paired a kernel extension that counted packets per flow with a userspace daemon that batched, serialized and uploaded the records.
- AWS says one worker running a couple of thousand microVMs needed well over a hundred thousand iptables rules just to keep that record, with the chain walked roughly linearly for every packet.
- AWS replaced the capture system with a purpose-built pipeline written in eBPF and Rust, described in a first-person account published on The New Stack.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint When per-packet bookkeeping gets slower as a host fills up, the logging design sets a ceiling on how many tenants you can pack onto that host, and packing is the point of the platform.
- cost The bill for capture overhead is paid per host in RAM and CPU, and AWS ties every extra megabyte and microsecond at that density to utilization, operating margin and capacity under load.
- exposure Metering and the compliance archive read the same flow records, so one attribution bug reaches customer invoices and the audit trail at the same time.
- decision A capture design blind to an address family cannot be optimised into usefulness, so anyone with dual-stack on the roadmap should test protocol coverage before funding performance work on the existing path.
iptables walks its rules more or less linearly for every packet, and each new microVM piled more rules onto the chain [7]. So a packet's bookkeeping cost rose with how crowded the host was and which slot the microVM received [9]. Divide well over a hundred thousand rules by a couple of thousand sandboxes and you get roughly 50 rules per microVM [8][17]. A function that sent two packets still paid to walk past its neighbours.
The other half of the inherited design was a userspace daemon that read the kernel counters, batched them into records, serialized them, and uploaded the files frequently [5]. That loop has to close before the evidence disappears. Thousands of microVMs on one server run for a few hundred milliseconds and then shut down, each one a different customer's function [2]. "Within milliseconds, the workload is done, and the logs captured during those few milliseconds are the only witness left," the AWS Lambda authors wrote in The New Stack [12][20].
Density was at least a tuning problem, but the borrowed kernel module did not speak IPv6 [10]. "A record that can't see half the address space isn't one you can trust, and the moment dual-stack IPv6 support was proposed for Lambda, the old approach was finished," they wrote [11].
That hundred-thousand-rule figure means something on someone else's fleet only if per-flow attribution keys on match rules in a table that is walked for every packet [7], and only if density runs into the thousands of tenants per host [2]. At about 50 rules per workload, a host running 30 containers carries roughly 1,500 rules [21], and that walk will not show up in a CPU budget. What transfers to a smaller fleet is the failure signature, a capture path whose cost tracks host occupancy.
The published account stops before the new pipeline's internals. It names the replacement as a purpose-built pipeline written in eBPF and Rust [13], and lists the non-negotiable design considerations as correct attribution, meaningful overhead reduction, and a third item the text cuts off after the words "support for I" [16]. The requirements are stated plainly enough to copy: the record must be complete and correctly attributed, and capturing it must add almost no overhead to the network flow or the platform [3]. Correct attribution means every flow ties to the microVM where it landed and the tenant that produced it, and completeness means no missed packets [18]. Those same records feed network usage and metering services, and they are persisted for audit and compliance [4]. AWS says a missing or misattributed record can cause billing, observability and monitoring problems at scale, on a platform serving millions of requests per second [15][19].
What to watch
- A follow-up describing the eBPF and Rust pipeline's internals: how flows are keyed to a tenant, and where the records are buffered before a sandbox exits.
- Whether AWS publishes measured per-host CPU and RAM overhead for the new capture path against the iptables-based one.
- How broadly dual-stack IPv6 reaches Lambda, since that requirement is what ended the inherited kernel module.