From f358a6db1126b76d07442786038a5e7a4d3f32c3 Mon Sep 17 00:00:00 2001 From: Spike Curtis Date: Wed, 28 Jan 2026 07:12:32 +0400 Subject: [PATCH] chore: convert tailnet tables to UNLOGGED for improved write performance (#21607) This migration converts all tailnet coordination tables to UNLOGGED: - `tailnet_coordinators` - `tailnet_peers` - `tailnet_tunnels` UNLOGGED tables skip Write-Ahead Log (WAL) writes, significantly improving performance for high-frequency updates like coordinator heartbeats and peer state changes. The trade-off is that UNLOGGED tables are truncated on crash recovery and are not replicated to standby servers. This is acceptable for these tables because the data is ephemeral: 1. Coordinators re-register on startup 2. Peers re-establish connections on reconnect 3. Tunnels are re-created based on current peer state **Migration notes:** - Child tables must be converted before the parent table because LOGGED child tables cannot reference UNLOGGED parent tables (but the reverse is allowed) - The down migration reverses the order: parent first, then children Fixes https://github.com/coder/coder/issues/21333 --- coderd/database/dump.sql | 6 +++--- .../000411_tailnet_tables_unlogged.down.sql | 10 ++++++++++ .../000411_tailnet_tables_unlogged.up.sql | 20 +++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 coderd/database/migrations/000411_tailnet_tables_unlogged.down.sql create mode 100644 coderd/database/migrations/000411_tailnet_tables_unlogged.up.sql diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 6bfcc24dfa..ab9c78970e 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1762,14 +1762,14 @@ CREATE TABLE site_configs ( value text NOT NULL ); -CREATE TABLE tailnet_coordinators ( +CREATE UNLOGGED TABLE tailnet_coordinators ( id uuid NOT NULL, heartbeat_at timestamp with time zone NOT NULL ); COMMENT ON TABLE tailnet_coordinators IS 'We keep this separate from replicas in case we need to break the coordinator out into its own service'; -CREATE TABLE tailnet_peers ( +CREATE UNLOGGED TABLE tailnet_peers ( id uuid NOT NULL, coordinator_id uuid NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -1777,7 +1777,7 @@ CREATE TABLE tailnet_peers ( status tailnet_status DEFAULT 'ok'::tailnet_status NOT NULL ); -CREATE TABLE tailnet_tunnels ( +CREATE UNLOGGED TABLE tailnet_tunnels ( coordinator_id uuid NOT NULL, src_id uuid NOT NULL, dst_id uuid NOT NULL, diff --git a/coderd/database/migrations/000411_tailnet_tables_unlogged.down.sql b/coderd/database/migrations/000411_tailnet_tables_unlogged.down.sql new file mode 100644 index 0000000000..6b9fd14518 --- /dev/null +++ b/coderd/database/migrations/000411_tailnet_tables_unlogged.down.sql @@ -0,0 +1,10 @@ +-- Revert tailnet tables to LOGGED (standard WAL-enabled tables). +-- WARNING: This requires a full table rewrite with WAL generation, +-- which can be slow for large tables. + +-- Convert parent table first (before children, reverse of up migration). +ALTER TABLE tailnet_coordinators SET LOGGED; + +-- Convert child tables after parent. +ALTER TABLE tailnet_peers SET LOGGED; +ALTER TABLE tailnet_tunnels SET LOGGED; diff --git a/coderd/database/migrations/000411_tailnet_tables_unlogged.up.sql b/coderd/database/migrations/000411_tailnet_tables_unlogged.up.sql new file mode 100644 index 0000000000..c555b9a0c4 --- /dev/null +++ b/coderd/database/migrations/000411_tailnet_tables_unlogged.up.sql @@ -0,0 +1,20 @@ +-- Convert all tailnet coordination tables to UNLOGGED for improved write performance. +-- These tables contain ephemeral coordination data that can be safely reconstructed +-- after a crash. UNLOGGED tables skip WAL writes, significantly improving performance +-- for high-frequency updates like coordinator heartbeats and peer state changes. +-- +-- IMPORTANT: UNLOGGED tables are truncated on crash recovery and are not replicated +-- to standby servers. This is acceptable because: +-- 1. Coordinators re-register on startup +-- 2. Peers re-establish connections on reconnect +-- 3. Tunnels are re-created based on current peer state + +-- Convert child tables first (they have FK references to tailnet_coordinators). +-- UNLOGGED child tables can reference LOGGED parent tables, but LOGGED child +-- tables cannot reference UNLOGGED parent tables. So we must convert children +-- before converting the parent. +ALTER TABLE tailnet_tunnels SET UNLOGGED; +ALTER TABLE tailnet_peers SET UNLOGGED; + +-- Convert parent table last (after all children are unlogged). +ALTER TABLE tailnet_coordinators SET UNLOGGED;