tailscale/cmd
Brad Fitzpatrick b75921a7cb derp/derpserver: cache local peer lookups per client
Avoid taking Server.mu for repeated sends from a client to the same small set
of local peers. Each sclient now keeps a bounded, goroutine-local LRU of
destination public key to clientSet.

To cap memory for idle clients, cache entries track a coarsely updated
last-used time. The hot path refreshes that timestamp only when it is older
than 30 seconds, and incoming ping frames trim entries idle for more than 10
minutes. This keeps cleanup on the client run goroutine without adding
another mutex or background goroutine.

cmd/derper gets new --peer-cache-max-entries and --peer-cache-max-idle flags.
Their zero values use the automatic defaults, and --peer-cache-max-entries=-1
disables the cache.

The peer_lookup_cache_misses counter tracks how often lookupDest falls back
to the authoritative Server.mu lookup. We do not count hits on the hot path;
when the cache is enabled, hits can be derived from packets_received minus
peer_lookup_cache_misses.

This optimization is pulled out of the larger #13510 DERP flow-tracking work
from 2024, which did a bunch more. We can rebase that bigger PR later and
discuss its stats and memory impact on its own merits without losing this
standalone optimization.

The benchmark compares the same code with TS_DEBUG_DERP_DISABLE_PEER_CACHE
set true for the before run and the default cached path for the after run:

    TS_DEBUG_DERP_DISABLE_PEER_CACHE=true go test ./derp/derpserver -run '^$' -bench '^BenchmarkLookupDestPeerCache$' -benchtime=2s -count=10 > before

    go test ./derp/derpserver -run '^$' -bench '^BenchmarkLookupDestPeerCache$' -benchtime=2s -count=10 > after

    go run golang.org/x/perf/cmd/benchstat@latest before after

    goos: linux
    goarch: amd64
    pkg: tailscale.com/derp/derpserver
    cpu: Intel(R) Xeon(R) 6975P-C
                           │    before     │                after                │
                           │    sec/op     │   sec/op     vs base                │
    LookupDestPeerCache-16   180.400n ± 0%   5.720n ± 1%  -96.83% (p=0.000 n=10)

                           │   before   │             after              │
                           │    B/op    │    B/op     vs base            │
    LookupDestPeerCache-16   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
    ¹ all samples are equal

                           │   before   │             after              │
                           │ allocs/op  │ allocs/op   vs base            │
    LookupDestPeerCache-16   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
    ¹ all samples are equal

Updates #3560

Change-Id: Ie31b540447211fd9415eea6cc235b83a87930093
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-05-12 13:04:07 -07:00
..
addlicense all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
build-webclient all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
checkmetrics all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
cigocacher cmd/cigocacher: make --stats flag best-effort (#18761) 2026-02-19 16:06:12 +00:00
cloner cmd/cloner: deep-clone pointer elements in map-of-slice values 2026-04-17 11:36:05 -04:00
connector-gen all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
containerboot all: migrate code off Notify.NetMap to Notify.SelfChange 2026-05-01 06:51:40 -07:00
derper derp/derpserver: cache local peer lookups per client 2026-05-12 13:04:07 -07:00
derpprobe all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
dist all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
distsign all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
featuretags all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
get-authkey all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
gitops-pusher tsnet: make workload identity federation opt-in 2026-05-06 18:43:45 -07:00
hello cmd/hello: split server into helloserver package 2026-04-30 08:40:55 -07:00
jsonimports all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
k8s-nameserver cmd/vet: add subtestnames analyzer; fix all existing violations 2026-04-05 15:52:51 -07:00
k8s-operator tsnet: make workload identity federation opt-in 2026-05-06 18:43:45 -07:00
k8s-proxy cmd/containerboot,cmd/k8s-proxy,kube: add authkey renewal to k8s-proxy (#19221) 2026-04-15 16:13:46 +01:00
mkmanifest all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
mkpkg all: use Go 1.26 things, run most gofix modernizers 2026-03-06 13:32:03 -08:00
mkversion all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
nardump tool/updateflakes, cmd/nardump: replace update-flake.sh with Go tool 2026-04-28 10:18:32 -07:00
natc all: use bart.Lite instead of bart.Table where appropriate 2026-03-24 14:45:23 +00:00
netlogfmt all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
nginx-auth all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
omitsize all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
pgproxy cmd/pgproxy: fix client TLS handshake timeout 2026-05-11 11:12:11 -07:00
printdep cmd/printdep: add --next flag to use rc Go build hash instead 2026-01-27 14:49:56 -08:00
proxy-test-server all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
proxy-to-grafana all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
sniproxy all: migrate code off Notify.NetMap to Notify.SelfChange 2026-05-01 06:51:40 -07:00
speedtest all: use Go 1.26 things, run most gofix modernizers 2026-03-06 13:32:03 -08:00
ssh-auth-none-demo ssh: replace tempfork with tailscale/gliderssh 2026-04-07 11:59:38 +01:00
stunc all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
stund derp,types,util: use bufio Peek+Discard for allocation-free fast reads (#19067) 2026-03-24 10:52:20 -04:00
stunstamp all: use Go 1.26 things, run most gofix modernizers 2026-03-06 13:32:03 -08:00
sync-containers all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
systray client/systray: support several different color themes 2026-04-27 18:54:14 -07:00
tailscale cmd/tailscale/cli: add RunWithContext 2026-05-12 12:27:55 -07:00
tailscaled wgengine/netstack, net/ping: stop using pro-bing and use our net/ping instead 2026-05-04 14:05:24 -07:00
testcontrol all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
testwrapper cmd/testwrapper: print unit for package duration (#19663) 2026-05-06 22:31:48 +01:00
tl-longchain all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
tsconnect all: migrate code off Notify.NetMap to Notify.SelfChange 2026-05-01 06:51:40 -07:00
tsidp tsnet: make workload identity federation opt-in 2026-05-06 18:43:45 -07:00
tsnet-proxy cmd/tsnet-proxy: add tsnet-based port proxy tool (#19468) 2026-04-22 13:34:18 -04:00
tsp control/tsp, cmd/tsp: add low-level Tailscale protocol client and tool 2026-04-16 20:00:25 -07:00
tsshd all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
tta tstest/natlab/vmtest: add TestDiscoKeyChange 2026-04-29 12:58:00 -07:00
vet cmd/vet/lowerell, drive/driveimpl: forbid variables named "l" or "I" 2026-05-04 14:03:28 -07:00
viewer cmd/cloner: deep-clone pointer elements in map-of-slice values 2026-04-17 11:36:05 -04:00
vnet all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
xdpderper all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00