SIGN IN SIGN UP

feature/conn25: don't pre-size flow table maps

NewFlowTable pre-sized its two per-direction lookup maps to maxEntries.
The datapath handler creates a client table (10k flows) and a connector
table (100k flows) unconditionally at extension init, so every client
paid ~15.8 MiB of empty map buckets up front (measured on device, and
reproducible with a benchmark: 2x100k + 2x10k maps keyed by the 38-byte
flowtrack.Tuple).

On iOS the Network Extension has a hard 50 MiB jetsam limit. On large
tailnets the netmap and derived engine state need ~18 MiB of live heap
on top of the baseline, and this pre-allocation pushed the process over
the limit: the extension was killed (per-process-limit) seconds after
connecting, in a relaunch loop, making such tailnets unusable on iOS.

maxEntries is still enforced as a bound at insertion time; the maps now
grow on demand instead. On an iPhone 14 Pro Max joining a ~600 node
tailnet this took peak live heap during netmap ingest from 36.8 MiB to
24.3 MiB and the extension now connects and stays up with ~18 MiB of
headroom instead of being killed at 50 MiB.

Fixes tailscale/corp#46408
Updates tailscale/corp#18514

Signed-off-by: James Tucker <james@tailscale.com>
J
James Tucker committed
d200b3f18f0ee4cff1f6819a78a9fe8e6a7367f2
Parent: 69efc99
Committed by Brad Fitzpatrick <brad@danga.com> on 8/11/2026, 1:52:08 PM