Development Task
All of these are TiProxy code changes. Percents are of total CPU in that short-conn profile (~6.2 cores over 10s); they overlap, so they do not add.
-
Always cache DNS (use lookupNetIP even when ns-servers is empty) — ~6–7%; this is the main DNS win, because the cache/singleflight path is skipped today.
-
Raise DNS TTL from 5s to 30s+ (singleflight already exists) — <1% extra after (1); only cuts rare cache misses, not the per-connection resolver storm.
-
Dial backends by cached IP (ServerName still the hostname) — ~6–7% if (1) is not done; ~0.5–1% extra if (1) is done, by skipping DNS on the dial path entirely.
-
Do not start processSignals until redirect/graceful-close is needed — ~2–4% (one less goroutine, ticker, and stack per short connection).
-
Skip TCP keepalive on new connections (or until the conn lives for a few seconds) — ~1%.
-
Stop cloning zap loggers per connection (With / Named in onConn / Connect) — ~1–1.5%.
-
Make addCmdMetrics / addTraffic lock-free after the first lookup — ~1–2% (Prometheus Observe itself stays).
-
Replace crypto/rand salt with a buffered CSPRNG — ~0.7–1%.
-
Use smaller conn buffers (or a short-conn pool) instead of 32KB × 4 — ~1–2% via less alloc/GC; already pooled, so this is burst/GC only.
-
sync.Pool BackendConnManager / ClientConnection / packetIO — ~1–3% GC; does not cut syscalls.
-
Shard or atomic-ize SQLServer.mu.clients so Accept does not take a global lock per conn — <1%.
-
Backend connection reuse (COM_RESET_CONNECTION / COM_CHANGE_USER pool, not pre-dial) — ~15–25% on TCP/DNS/close; large feature, handshake reset still costs. Pre-dial without
reuse saves ~0% CPU.
Practical order: (1) first, then (4)+(5), then (6)–(8). (2) is optional. (12) is the only large remaining win and is a different project.
Development Task
All of these are TiProxy code changes. Percents are of total CPU in that short-conn profile (~6.2 cores over 10s); they overlap, so they do not add.
Always cache DNS (use lookupNetIP even when ns-servers is empty) — ~6–7%; this is the main DNS win, because the cache/singleflight path is skipped today.
Raise DNS TTL from 5s to 30s+ (singleflight already exists) — <1% extra after (1); only cuts rare cache misses, not the per-connection resolver storm.
Dial backends by cached IP (ServerName still the hostname) — ~6–7% if (1) is not done; ~0.5–1% extra if (1) is done, by skipping DNS on the dial path entirely.
Do not start processSignals until redirect/graceful-close is needed — ~2–4% (one less goroutine, ticker, and stack per short connection).
Skip TCP keepalive on new connections (or until the conn lives for a few seconds) — ~1%.
Stop cloning zap loggers per connection (With / Named in onConn / Connect) — ~1–1.5%.
Make addCmdMetrics / addTraffic lock-free after the first lookup — ~1–2% (Prometheus Observe itself stays).
Replace crypto/rand salt with a buffered CSPRNG — ~0.7–1%.
Use smaller conn buffers (or a short-conn pool) instead of 32KB × 4 — ~1–2% via less alloc/GC; already pooled, so this is burst/GC only.
sync.Pool BackendConnManager / ClientConnection / packetIO — ~1–3% GC; does not cut syscalls.
Shard or atomic-ize SQLServer.mu.clients so Accept does not take a global lock per conn — <1%.
Backend connection reuse (COM_RESET_CONNECTION / COM_CHANGE_USER pool, not pre-dial) — ~15–25% on TCP/DNS/close; large feature, handshake reset still costs. Pre-dial without
reuse saves ~0% CPU.
Practical order: (1) first, then (4)+(5), then (6)–(8). (2) is optional. (12) is the only large remaining win and is a different project.