From 9a57b9ca11df666aaab7dc47b96999a812d2a6b9 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Sun, 26 Jul 2026 15:31:51 -0400 Subject: [PATCH 1/4] chore: telemetry stats update --- hasura/metadata/actions.graphql | 1 + src/telemetry/telemetry.service.ts | 42 ++++++++++++++++++++++--- src/telemetry/types/TelemetryPayload.ts | 1 + 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/hasura/metadata/actions.graphql b/hasura/metadata/actions.graphql index 743b83a7..a9df445b 100644 --- a/hasura/metadata/actions.graphql +++ b/hasura/metadata/actions.graphql @@ -1181,6 +1181,7 @@ type TelemetryInstallCounts { type TelemetryFleetTotals { gameServerNodes: Int! + gpuNodes: Int! servers: Int! dedicatedServers: Int! publicServers: Int! diff --git a/src/telemetry/telemetry.service.ts b/src/telemetry/telemetry.service.ts index 5362406c..747398d0 100644 --- a/src/telemetry/telemetry.service.ts +++ b/src/telemetry/telemetry.service.ts @@ -29,6 +29,14 @@ export class TelemetryService { string, { setting: string; defaultEnabled: boolean } > = { + // Not every switch is a `public.` setting — auto highlight generation is + // an unprefixed one, and the GPU workloads below are toggled per node. + highlights: { setting: "auto_generate_match_clips", defaultEnabled: false }, + highlights_imported: { + setting: "auto_generate_match_clips_imported", + defaultEnabled: false, + }, + clip_branding: { setting: "clip_bake_branding", defaultEnabled: false }, leagues: { setting: "public.leagues_enabled", defaultEnabled: false }, seasons: { setting: "public.seasons_enabled", defaultEnabled: false }, events: { setting: "public.events_enabled", defaultEnabled: false }, @@ -164,6 +172,7 @@ export class TelemetryService { enabled: counts.nodes_enabled, online: counts.nodes_online, regions: counts.nodes_regions, + gpu: counts.gpu_nodes, }, servers: { total: counts.servers_total, @@ -302,6 +311,7 @@ export class TelemetryService { const [row] = await this.postgres.query>>( `SELECT coalesce(sum((payload->'nodes'->>'total')::numeric), 0) AS "gameServerNodes", + coalesce(sum((payload->'nodes'->>'gpu')::numeric), 0) AS "gpuNodes", coalesce(sum((payload->'servers'->>'total')::numeric), 0) AS servers, coalesce(sum((payload->'servers'->>'dedicated')::numeric), 0) AS "dedicatedServers", coalesce(sum((payload->'servers'->>'public')::numeric), 0) AS "publicServers", @@ -323,6 +333,7 @@ export class TelemetryService { return TelemetryService.toIntegers(row, [ "gameServerNodes", + "gpuNodes", "servers", "dedicatedServers", "publicServers", @@ -517,6 +528,7 @@ export class TelemetryService { enabled: int(nodes.enabled), online: int(nodes.online), regions: int(nodes.regions), + gpu: int(nodes.gpu), }, servers: { total: int(servers.total), @@ -639,7 +651,7 @@ export class TelemetryService { settings: Map, counts: TelemetryCounts, ): Record { - const usage: Record = { + const usage: Record = { tournaments: counts.tournaments, leagues: counts.league_seasons, seasons: counts.seasons, @@ -659,6 +671,16 @@ export class TelemetryService { sanctions: counts.sanctions, api_keys: counts.api_keys, gamedata_validations: counts.gamedata_validations, + demo_playback: counts.demos, + live_streaming: null, + }; + + // Switched per GPU node instead of by a setting: on means at least one node + // is currently carrying that workload. + const gpuWorkloads: Record = { + demo_playback: counts.gpu_demo_nodes > 0, + clip_renders: counts.gpu_render_nodes > 0, + live_streaming: counts.gpu_stream_nodes > 0, }; const features: Record = {}; @@ -666,6 +688,7 @@ export class TelemetryService { for (const key of new Set([ ...Object.keys(TelemetryService.FeatureFlags), ...Object.keys(usage), + ...Object.keys(gpuWorkloads), ])) { const flag = TelemetryService.FeatureFlags[key]; @@ -675,7 +698,7 @@ export class TelemetryService { settings.get(flag.setting), flag.defaultEnabled, ) - : null, + : (gpuWorkloads[key] ?? null), count: usage[key] ?? null, }; } @@ -801,6 +824,17 @@ export class TelemetryService { (SELECT count(DISTINCT region) FROM public.game_server_nodes WHERE region IS NOT NULL) AS nodes_regions, + -- Demo playback, clip rendering and live streaming are each switched + -- per GPU node rather than by a setting, so "on" means at least one + -- node is carrying that workload. + (SELECT count(*) FROM public.game_server_nodes WHERE gpu) AS gpu_nodes, + (SELECT count(*) FROM public.game_server_nodes + WHERE gpu AND gpu_demos_enabled) AS gpu_demo_nodes, + (SELECT count(*) FROM public.game_server_nodes + WHERE gpu AND gpu_rendering_enabled) AS gpu_render_nodes, + (SELECT count(*) FROM public.game_server_nodes + WHERE gpu AND gpu_streaming_enabled) AS gpu_stream_nodes, + (SELECT count(*) FROM public.servers) AS servers_total, (SELECT count(*) FROM public.servers WHERE enabled) AS servers_enabled, (SELECT count(*) FROM public.servers WHERE is_dedicated) AS servers_dedicated, @@ -854,14 +888,14 @@ export class TelemetryService { JOIN public.matches m ON m.lineup_1_id = p.match_lineup_id OR m.lineup_2_id = p.match_lineup_id WHERE p.steam_id IS NOT NULL - AND m.started_at IS NOT NULL + AND ${TelemetryService.nativeMatch("m")} AND m.effective_at >= now() - interval '7 days') AS players_active_7d, (SELECT count(DISTINCT p.steam_id) FROM public.match_lineup_players p JOIN public.matches m ON m.lineup_1_id = p.match_lineup_id OR m.lineup_2_id = p.match_lineup_id WHERE p.steam_id IS NOT NULL - AND m.started_at IS NOT NULL + AND ${TelemetryService.nativeMatch("m")} AND m.effective_at >= now() - interval '30 days') AS players_active_30d, (SELECT count(*) FROM public.tournaments) AS tournaments, diff --git a/src/telemetry/types/TelemetryPayload.ts b/src/telemetry/types/TelemetryPayload.ts index 0bc91ec7..7e1350f6 100644 --- a/src/telemetry/types/TelemetryPayload.ts +++ b/src/telemetry/types/TelemetryPayload.ts @@ -16,6 +16,7 @@ export type TelemetryPayload = { enabled: number; online: number; regions: number; + gpu: number; }; servers: { total: number; From ead141ae5134696a1fd3140bf7bde59e182d7cde Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Sun, 26 Jul 2026 15:32:20 -0400 Subject: [PATCH 2/4] wip --- test/telemetry.spec.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/telemetry.spec.ts b/test/telemetry.spec.ts index db7d0ff6..2a2e2028 100644 --- a/test/telemetry.spec.ts +++ b/test/telemetry.spec.ts @@ -137,6 +137,11 @@ describe("telemetry (SQL-driven)", () => { expect(payload.features.events.enabled).toBe(false); expect(payload.features.scrims.enabled).toBe(true); expect(payload.features.highlights.count).toBe(0); + // Auto highlights is gated by an unprefixed `auto_generate_match_clips`. + expect(payload.features.highlights.enabled).toBe(false); + // GPU workloads are switched per node, not by a setting. + expect(payload.features.demo_playback.enabled).toBe(false); + expect(payload.features.clip_renders.enabled).toBe(false); }); it("keeps the install id out of the guest-readable settings namespace", async () => { @@ -164,7 +169,7 @@ describe("telemetry (SQL-driven)", () => { installed_at: "2024-01-01T00:00:00.000Z", panel_version: "deadbeef", plugin_runtime: "swiftly", - nodes: { total: 2, enabled: 2, online: 1, regions: 1 }, + nodes: { total: 2, enabled: 2, online: 1, regions: 1, gpu: 1 }, servers: { total: 10, enabled: 9, @@ -304,7 +309,7 @@ describe("telemetry (SQL-driven)", () => { installed_at: "2024-01-01T00:00:00.000Z", panel_version: "cafebabe", plugin_runtime: "css", - nodes: { total: 1, enabled: 1, online: 1, regions: 1 }, + nodes: { total: 1, enabled: 1, online: 1, regions: 1, gpu: 1 }, servers: { total: servers, enabled: servers, From c6f6a2710ad92c20cde3d96e73817ceab74a1eb5 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Sun, 26 Jul 2026 15:33:28 -0400 Subject: [PATCH 3/4] wip --- test/telemetry-perf.spec.ts | 170 ------------------------------------ 1 file changed, 170 deletions(-) delete mode 100644 test/telemetry-perf.spec.ts diff --git a/test/telemetry-perf.spec.ts b/test/telemetry-perf.spec.ts deleted file mode 100644 index f02b5710..00000000 --- a/test/telemetry-perf.spec.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { Logger } from "@nestjs/common"; -import { PostgresService } from "./../src/postgres/postgres.service"; -import { bootMigratedDb, SqlTestDb } from "./utils/sql-test-db"; -import { TelemetryService } from "./../src/telemetry/telemetry.service"; - -// Benchmark, not a guard: it seeds 20k matches and only prints timings, so a -// normal `yarn test:sql` skips it. Run it with PERF=1. -const benchmark = process.env.PERF === "1" ? describe : describe.skip; - -benchmark("telemetry perf", () => { - let db: SqlTestDb; - let postgres: PostgresService; - let service: TelemetryService; - - beforeAll(async () => { - db = await bootMigratedDb("TelemetryPerfTest"); - postgres = db.postgres; - - service = new TelemetryService( - new Logger("Perf"), - { - getConnection: () => ({ - setex: async () => "OK", - scan: async (): Promise<[string, Array]> => ["0", []], - }), - } as never, - null as never, - { get: () => ({ webDomain: "https://panel.test" }) } as never, - postgres, - { getPanelVersion: async () => "abc" } as never, - { - remember: async (_k: string, cb: () => Promise) => await cb(), - } as never, - ); - - await postgres.query( - `INSERT INTO server_regions (value, is_lan) VALUES ('PerfRegion', false) - ON CONFLICT (value) DO NOTHING`, - ); - await postgres.query( - `INSERT INTO servers (host, label, rcon_password, port, enabled, region, type, is_dedicated) - VALUES ('127.0.0.1', 'perf-server', '\\x00'::bytea, 27915, true, 'PerfRegion', 'Ranked', true)`, - ); - - const MATCHES = 20000; - - console.log(`seeding ${MATCHES} matches...`); - const started = Date.now(); - - await postgres.query( - `INSERT INTO match_lineups (id) - SELECT gen_random_uuid() FROM generate_series(1, ${MATCHES * 2})`, - ); - - await postgres.query( - `WITH numbered AS ( - SELECT id, row_number() OVER () AS rn FROM match_lineups - ), - pairs AS ( - SELECT a.id AS l1, b.id AS l2, a.rn - FROM numbered a - JOIN numbered b ON b.rn = a.rn + ${MATCHES} - WHERE a.rn <= ${MATCHES} - ) - INSERT INTO matches (lineup_1_id, lineup_2_id, source, started_at, ended_at, created_at) - SELECT l1, l2, - CASE WHEN rn % 5 = 0 THEN 'faceit' ELSE '5stack' END, - now() - (rn || ' hours')::interval, - now() - (rn || ' hours')::interval, - now() - (rn || ' hours')::interval - FROM pairs`, - ); - - // One player per lineup slot so no match ever gets the same steam id twice - // (a trigger rejects that), which keeps the join row counts realistic. - await postgres.query( - `INSERT INTO players (steam_id, name) - SELECT 76561190000000000 + g, 'p' || g - FROM generate_series(1, ${MATCHES * 10}) g`, - ); - - // check_match_lineup_players re-scans the whole table per row, so inserting - // 10 players a match this way is quadratic — minutes of seeding for a - // benchmark that measures a read. The rows are unique by construction - // (5 consecutive ids per lineup ordinal), so the check has nothing to catch. - await postgres.query( - "ALTER TABLE match_lineup_players DISABLE TRIGGER USER", - ); - await postgres.query( - `INSERT INTO match_lineup_players (match_lineup_id, steam_id) - SELECT l.id, 76561190000000000 + ((l.rn - 1) * 5 + s) - FROM (SELECT id, row_number() OVER (ORDER BY id) AS rn FROM match_lineups) l, - generate_series(1, 5) s`, - ); - await postgres.query( - "ALTER TABLE match_lineup_players ENABLE TRIGGER USER", - ); - - await postgres.query( - `INSERT INTO match_maps (match_id, map_id, "order", status) - SELECT m.id, (SELECT id FROM maps ORDER BY name LIMIT 1), 1, 'Finished' - FROM matches m`, - ); - - console.log(`seeded in ${Date.now() - started}ms`); - - const counts = await postgres.query>>( - `SELECT - (SELECT count(*) FROM matches) AS matches, - (SELECT count(*) FROM match_lineup_players) AS lineup_players, - (SELECT count(*) FROM match_maps) AS maps`, - ); - console.log("row counts:", counts[0]); - - await postgres.query("ANALYZE"); - }, 900_000); - - afterAll(async () => { - await db?.stop(); - }); - - it("times the whole collect()", async () => { - for (let i = 0; i < 3; i++) { - const started = Date.now(); - await service.collect(); - console.log(`collect() run ${i + 1}: ${Date.now() - started}ms`); - } - }, 300_000); - - it("times the active-player join on its own", async () => { - const sql = `SELECT count(DISTINCT p.steam_id) - FROM public.match_lineup_players p - JOIN public.matches m - ON m.lineup_1_id = p.match_lineup_id OR m.lineup_2_id = p.match_lineup_id - WHERE p.steam_id IS NOT NULL - AND m.started_at IS NOT NULL - AND m.effective_at >= now() - interval '30 days'`; - - const started = Date.now(); - await postgres.query(sql); - console.log(`OR-join active players: ${Date.now() - started}ms`); - - const plan = await postgres.query>>( - `EXPLAIN (ANALYZE, BUFFERS) ${sql}`, - ); - console.log(plan.map((r) => r["QUERY PLAN"]).join("\n")); - }, 300_000); - - it("times an IN-rewrite of the same thing", async () => { - const sql = `SELECT count(DISTINCT p.steam_id) - FROM public.match_lineup_players p - WHERE p.steam_id IS NOT NULL - AND p.match_lineup_id IN ( - SELECT lineup_1_id FROM public.matches - WHERE started_at IS NOT NULL AND effective_at >= now() - interval '30 days' - UNION - SELECT lineup_2_id FROM public.matches - WHERE started_at IS NOT NULL AND effective_at >= now() - interval '30 days' - )`; - - const started = Date.now(); - await postgres.query(sql); - console.log(`IN-rewrite active players: ${Date.now() - started}ms`); - - const plan = await postgres.query>>( - `EXPLAIN (ANALYZE, BUFFERS) ${sql}`, - ); - console.log(plan.map((r) => r["QUERY PLAN"]).join("\n")); - }, 300_000); -}); From 4f1c19457407aafac5c7029272a00f8f308daab2 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Sun, 26 Jul 2026 15:33:43 -0400 Subject: [PATCH 4/4] wip --- generated/schema.graphql | 2 + generated/schema.ts | 4 + generated/types.ts | 6 ++ test/telemetry-perf.spec.ts | 170 ++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 test/telemetry-perf.spec.ts diff --git a/generated/schema.graphql b/generated/schema.graphql index 80afcf1a..3c032f3a 100644 --- a/generated/schema.graphql +++ b/generated/schema.graphql @@ -788,6 +788,7 @@ type TelemetryActivityPoint { type TelemetryFeatureAdoption { enabled: Int! + flagged: Int! installsUsing: Int! key: String! reporting: Int! @@ -797,6 +798,7 @@ type TelemetryFeatureAdoption { type TelemetryFleetTotals { dedicatedServers: Int! gameServerNodes: Int! + gpuNodes: Int! mapsPlayed: Int! matches: Int! matchesImported: Int! diff --git a/generated/schema.ts b/generated/schema.ts index f97f3efb..b1db62b8 100644 --- a/generated/schema.ts +++ b/generated/schema.ts @@ -711,6 +711,7 @@ export interface TelemetryActivityPoint { export interface TelemetryFeatureAdoption { enabled: Scalars['Int'] + flagged: Scalars['Int'] installsUsing: Scalars['Int'] key: Scalars['String'] reporting: Scalars['Int'] @@ -721,6 +722,7 @@ export interface TelemetryFeatureAdoption { export interface TelemetryFleetTotals { dedicatedServers: Scalars['Int'] gameServerNodes: Scalars['Int'] + gpuNodes: Scalars['Int'] mapsPlayed: Scalars['Int'] matches: Scalars['Int'] matchesImported: Scalars['Int'] @@ -36349,6 +36351,7 @@ export interface TelemetryActivityPointGenqlSelection{ export interface TelemetryFeatureAdoptionGenqlSelection{ enabled?: boolean | number + flagged?: boolean | number installsUsing?: boolean | number key?: boolean | number reporting?: boolean | number @@ -36360,6 +36363,7 @@ export interface TelemetryFeatureAdoptionGenqlSelection{ export interface TelemetryFleetTotalsGenqlSelection{ dedicatedServers?: boolean | number gameServerNodes?: boolean | number + gpuNodes?: boolean | number mapsPlayed?: boolean | number matches?: boolean | number matchesImported?: boolean | number diff --git a/generated/types.ts b/generated/types.ts index 0c0e5328..eee42056 100644 --- a/generated/types.ts +++ b/generated/types.ts @@ -2511,6 +2511,9 @@ export default { "enabled": [ 40 ], + "flagged": [ + 40 + ], "installsUsing": [ 40 ], @@ -2534,6 +2537,9 @@ export default { "gameServerNodes": [ 40 ], + "gpuNodes": [ + 40 + ], "mapsPlayed": [ 40 ], diff --git a/test/telemetry-perf.spec.ts b/test/telemetry-perf.spec.ts new file mode 100644 index 00000000..f02b5710 --- /dev/null +++ b/test/telemetry-perf.spec.ts @@ -0,0 +1,170 @@ +import { Logger } from "@nestjs/common"; +import { PostgresService } from "./../src/postgres/postgres.service"; +import { bootMigratedDb, SqlTestDb } from "./utils/sql-test-db"; +import { TelemetryService } from "./../src/telemetry/telemetry.service"; + +// Benchmark, not a guard: it seeds 20k matches and only prints timings, so a +// normal `yarn test:sql` skips it. Run it with PERF=1. +const benchmark = process.env.PERF === "1" ? describe : describe.skip; + +benchmark("telemetry perf", () => { + let db: SqlTestDb; + let postgres: PostgresService; + let service: TelemetryService; + + beforeAll(async () => { + db = await bootMigratedDb("TelemetryPerfTest"); + postgres = db.postgres; + + service = new TelemetryService( + new Logger("Perf"), + { + getConnection: () => ({ + setex: async () => "OK", + scan: async (): Promise<[string, Array]> => ["0", []], + }), + } as never, + null as never, + { get: () => ({ webDomain: "https://panel.test" }) } as never, + postgres, + { getPanelVersion: async () => "abc" } as never, + { + remember: async (_k: string, cb: () => Promise) => await cb(), + } as never, + ); + + await postgres.query( + `INSERT INTO server_regions (value, is_lan) VALUES ('PerfRegion', false) + ON CONFLICT (value) DO NOTHING`, + ); + await postgres.query( + `INSERT INTO servers (host, label, rcon_password, port, enabled, region, type, is_dedicated) + VALUES ('127.0.0.1', 'perf-server', '\\x00'::bytea, 27915, true, 'PerfRegion', 'Ranked', true)`, + ); + + const MATCHES = 20000; + + console.log(`seeding ${MATCHES} matches...`); + const started = Date.now(); + + await postgres.query( + `INSERT INTO match_lineups (id) + SELECT gen_random_uuid() FROM generate_series(1, ${MATCHES * 2})`, + ); + + await postgres.query( + `WITH numbered AS ( + SELECT id, row_number() OVER () AS rn FROM match_lineups + ), + pairs AS ( + SELECT a.id AS l1, b.id AS l2, a.rn + FROM numbered a + JOIN numbered b ON b.rn = a.rn + ${MATCHES} + WHERE a.rn <= ${MATCHES} + ) + INSERT INTO matches (lineup_1_id, lineup_2_id, source, started_at, ended_at, created_at) + SELECT l1, l2, + CASE WHEN rn % 5 = 0 THEN 'faceit' ELSE '5stack' END, + now() - (rn || ' hours')::interval, + now() - (rn || ' hours')::interval, + now() - (rn || ' hours')::interval + FROM pairs`, + ); + + // One player per lineup slot so no match ever gets the same steam id twice + // (a trigger rejects that), which keeps the join row counts realistic. + await postgres.query( + `INSERT INTO players (steam_id, name) + SELECT 76561190000000000 + g, 'p' || g + FROM generate_series(1, ${MATCHES * 10}) g`, + ); + + // check_match_lineup_players re-scans the whole table per row, so inserting + // 10 players a match this way is quadratic — minutes of seeding for a + // benchmark that measures a read. The rows are unique by construction + // (5 consecutive ids per lineup ordinal), so the check has nothing to catch. + await postgres.query( + "ALTER TABLE match_lineup_players DISABLE TRIGGER USER", + ); + await postgres.query( + `INSERT INTO match_lineup_players (match_lineup_id, steam_id) + SELECT l.id, 76561190000000000 + ((l.rn - 1) * 5 + s) + FROM (SELECT id, row_number() OVER (ORDER BY id) AS rn FROM match_lineups) l, + generate_series(1, 5) s`, + ); + await postgres.query( + "ALTER TABLE match_lineup_players ENABLE TRIGGER USER", + ); + + await postgres.query( + `INSERT INTO match_maps (match_id, map_id, "order", status) + SELECT m.id, (SELECT id FROM maps ORDER BY name LIMIT 1), 1, 'Finished' + FROM matches m`, + ); + + console.log(`seeded in ${Date.now() - started}ms`); + + const counts = await postgres.query>>( + `SELECT + (SELECT count(*) FROM matches) AS matches, + (SELECT count(*) FROM match_lineup_players) AS lineup_players, + (SELECT count(*) FROM match_maps) AS maps`, + ); + console.log("row counts:", counts[0]); + + await postgres.query("ANALYZE"); + }, 900_000); + + afterAll(async () => { + await db?.stop(); + }); + + it("times the whole collect()", async () => { + for (let i = 0; i < 3; i++) { + const started = Date.now(); + await service.collect(); + console.log(`collect() run ${i + 1}: ${Date.now() - started}ms`); + } + }, 300_000); + + it("times the active-player join on its own", async () => { + const sql = `SELECT count(DISTINCT p.steam_id) + FROM public.match_lineup_players p + JOIN public.matches m + ON m.lineup_1_id = p.match_lineup_id OR m.lineup_2_id = p.match_lineup_id + WHERE p.steam_id IS NOT NULL + AND m.started_at IS NOT NULL + AND m.effective_at >= now() - interval '30 days'`; + + const started = Date.now(); + await postgres.query(sql); + console.log(`OR-join active players: ${Date.now() - started}ms`); + + const plan = await postgres.query>>( + `EXPLAIN (ANALYZE, BUFFERS) ${sql}`, + ); + console.log(plan.map((r) => r["QUERY PLAN"]).join("\n")); + }, 300_000); + + it("times an IN-rewrite of the same thing", async () => { + const sql = `SELECT count(DISTINCT p.steam_id) + FROM public.match_lineup_players p + WHERE p.steam_id IS NOT NULL + AND p.match_lineup_id IN ( + SELECT lineup_1_id FROM public.matches + WHERE started_at IS NOT NULL AND effective_at >= now() - interval '30 days' + UNION + SELECT lineup_2_id FROM public.matches + WHERE started_at IS NOT NULL AND effective_at >= now() - interval '30 days' + )`; + + const started = Date.now(); + await postgres.query(sql); + console.log(`IN-rewrite active players: ${Date.now() - started}ms`); + + const plan = await postgres.query>>( + `EXPLAIN (ANALYZE, BUFFERS) ${sql}`, + ); + console.log(plan.map((r) => r["QUERY PLAN"]).join("\n")); + }, 300_000); +});