From fb0db371bfe55e4d2f0160ebe87155534453582f Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 30 Mar 2026 13:21:24 +0200 Subject: [PATCH 1/5] disable background workers with params --- docs/components/Repl.vue | 5 +++++ docs/docs/api.md | 15 +++++++++++++++ docs/repl/ReplPlayground.vue | 9 +++++++-- packages/pglite/src/pglite.ts | 6 ++++++ packages/pglite/tests/basic.test.ts | 22 ++++++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/components/Repl.vue b/docs/components/Repl.vue index 03ac6c8da..badc03f3d 100644 --- a/docs/components/Repl.vue +++ b/docs/components/Repl.vue @@ -6,6 +6,11 @@ import { PGlite } from '@electric-sql/pglite' import { vector } from '@electric-sql/pglite/vector' const pg = new PGlite({ + startParams: [ + ...PGlite.defaultStartParams, + '-c', + 'application_name=PGlite REPL' + ], extensions: { vector, }, diff --git a/docs/docs/api.md b/docs/docs/api.md index a77163b9c..76fd450e7 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -90,6 +90,21 @@ Path to the directory for storing the Postgres database. You can provide a URI s }) ``` +- `startParams?: string[]`
+ An array of strings that will be passed to the Postgres process. This is the set of parameters one would pass to a native PostgreSQL instance. + + ```ts + import { PGlite } from '@electric-sql/pglite' + + const pg = await PGlite.create({ + startParams: [ + ...PGlite.defaultStartParams, + "-c", + "application_name=My awesome backend" + ] + }) + ``` + #### `options.extensions` PGlite and Postgres extensions are loaded into a PGLite instance on start, and can include both a WASM build of a Postgres extension and/or a PGlite client plugin. diff --git a/docs/repl/ReplPlayground.vue b/docs/repl/ReplPlayground.vue index 5934b3293..2789626da 100644 --- a/docs/repl/ReplPlayground.vue +++ b/docs/repl/ReplPlayground.vue @@ -53,6 +53,11 @@ async function loadPg() { try { console.log(`Creating PGlite instance with idb://${dbName}`) return await PGlite.create({ + startParams: [ + ...PGlite.defaultStartParams, + '-c', + 'application_name=PGlite REPL Playground' + ], dataDir: `idb://${dbName}`, extensions, }) @@ -93,7 +98,7 @@ async function loadPg() { } onMounted(async () => { - pg.value = await loadPg() + doLoadPg() }) const rootStyle = window.getComputedStyle(document.body) @@ -179,7 +184,7 @@ async function clearDb() { if (closed) break await new Promise((resolve) => setTimeout(resolve, 10)) } - pg.value = await loadPg() + doLoadPg() } diff --git a/packages/pglite/src/pglite.ts b/packages/pglite/src/pglite.ts index 02620dcfd..cf569e7f1 100644 --- a/packages/pglite/src/pglite.ts +++ b/packages/pglite/src/pglite.ts @@ -123,6 +123,12 @@ export class PGlite 'exit_on_error=false', '-c', 'log_checkpoints=false', + '-c', + 'max_worker_processes=0', + '-c', + 'max_parallel_workers=0', + '-c', + 'max_parallel_workers_per_gather=0', ] /** diff --git a/packages/pglite/tests/basic.test.ts b/packages/pglite/tests/basic.test.ts index e229e3d33..cb82486b6 100644 --- a/packages/pglite/tests/basic.test.ts +++ b/packages/pglite/tests/basic.test.ts @@ -650,5 +650,27 @@ await testEsmCjsAndDTC(async (importType) => { current_role: 'postgres', }) }) + + // this tests the parameter 'max_parallel_workers_per_gather=0', + it('it shouldnt use parallel workers on gather', async () => { + const db = await PGlite.create() + + const ROWS = 400_000; + + await db.exec(` + CREATE TABLE t (id SERIAL PRIMARY KEY, val TEXT); + INSERT INTO t (val) + SELECT md5(i::text) FROM generate_series(1, ${ROWS}) AS i; + `); + + // when using workers for GATHER, the query plans contains Gather + const plan = await db.query("EXPLAIN SELECT COUNT(*) FROM t"); + + const hasGather = plan.rows.some((r: any) => r["QUERY PLAN"].includes("Gather")); + expect(hasGather).toBeFalsy() + + const result = await db.query("SELECT COUNT(*) FROM t"); + expect(result.rows[0].count).toEqual(ROWS) + }) }) }) From a8012bd04b8424e1251f863cd6e59ca939d4f174 Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 30 Mar 2026 13:21:53 +0200 Subject: [PATCH 2/5] leftovers --- docs/components/Repl.vue | 6 +++--- docs/docs/api.md | 6 +++--- docs/repl/ReplPlayground.vue | 6 +++--- packages/pglite/tests/basic.test.ts | 16 +++++++++------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/components/Repl.vue b/docs/components/Repl.vue index badc03f3d..3de2e7cb9 100644 --- a/docs/components/Repl.vue +++ b/docs/components/Repl.vue @@ -7,9 +7,9 @@ import { vector } from '@electric-sql/pglite/vector' const pg = new PGlite({ startParams: [ - ...PGlite.defaultStartParams, - '-c', - 'application_name=PGlite REPL' + ...PGlite.defaultStartParams, + '-c', + 'application_name=PGlite REPL', ], extensions: { vector, diff --git a/docs/docs/api.md b/docs/docs/api.md index 76fd450e7..c4420d71a 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -99,9 +99,9 @@ Path to the directory for storing the Postgres database. You can provide a URI s const pg = await PGlite.create({ startParams: [ ...PGlite.defaultStartParams, - "-c", - "application_name=My awesome backend" - ] + '-c', + 'application_name=My awesome backend', + ], }) ``` diff --git a/docs/repl/ReplPlayground.vue b/docs/repl/ReplPlayground.vue index 2789626da..195b3f58b 100644 --- a/docs/repl/ReplPlayground.vue +++ b/docs/repl/ReplPlayground.vue @@ -54,9 +54,9 @@ async function loadPg() { console.log(`Creating PGlite instance with idb://${dbName}`) return await PGlite.create({ startParams: [ - ...PGlite.defaultStartParams, - '-c', - 'application_name=PGlite REPL Playground' + ...PGlite.defaultStartParams, + '-c', + 'application_name=PGlite REPL Playground', ], dataDir: `idb://${dbName}`, extensions, diff --git a/packages/pglite/tests/basic.test.ts b/packages/pglite/tests/basic.test.ts index cb82486b6..0bc98d2e6 100644 --- a/packages/pglite/tests/basic.test.ts +++ b/packages/pglite/tests/basic.test.ts @@ -655,22 +655,24 @@ await testEsmCjsAndDTC(async (importType) => { it('it shouldnt use parallel workers on gather', async () => { const db = await PGlite.create() - const ROWS = 400_000; - + const ROWS = 400_000 + await db.exec(` CREATE TABLE t (id SERIAL PRIMARY KEY, val TEXT); INSERT INTO t (val) SELECT md5(i::text) FROM generate_series(1, ${ROWS}) AS i; - `); + `) // when using workers for GATHER, the query plans contains Gather - const plan = await db.query("EXPLAIN SELECT COUNT(*) FROM t"); + const plan = await db.query('EXPLAIN SELECT COUNT(*) FROM t') - const hasGather = plan.rows.some((r: any) => r["QUERY PLAN"].includes("Gather")); + const hasGather = plan.rows.some((r: any) => + r['QUERY PLAN'].includes('Gather'), + ) expect(hasGather).toBeFalsy() - const result = await db.query("SELECT COUNT(*) FROM t"); + const result = await db.query('SELECT COUNT(*) FROM t') expect(result.rows[0].count).toEqual(ROWS) - }) + }) }) }) From 44e6b4de0a548c393239721d500e39c98e1207e9 Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 30 Mar 2026 13:24:18 +0200 Subject: [PATCH 3/5] changeset --- .changeset/soft-carpets-kneel.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/soft-carpets-kneel.md diff --git a/.changeset/soft-carpets-kneel.md b/.changeset/soft-carpets-kneel.md new file mode 100644 index 000000000..6fa9b0004 --- /dev/null +++ b/.changeset/soft-carpets-kneel.md @@ -0,0 +1,5 @@ +--- +'@electric-sql/pglite': patch +--- + +Disable background workers. From a98b6952dcead26f1c992e748ade77ce909a4c80 Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 30 Mar 2026 13:32:06 +0200 Subject: [PATCH 4/5] test for startParams --- packages/pglite/tests/basic.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/pglite/tests/basic.test.ts b/packages/pglite/tests/basic.test.ts index 0bc98d2e6..dd92e6ca6 100644 --- a/packages/pglite/tests/basic.test.ts +++ b/packages/pglite/tests/basic.test.ts @@ -674,5 +674,21 @@ await testEsmCjsAndDTC(async (importType) => { const result = await db.query('SELECT COUNT(*) FROM t') expect(result.rows[0].count).toEqual(ROWS) }) + + it('altering startParams should work"', async () => { + const dateTime = Date.now().toString() + const db = await PGlite.create({ + startParams: [ + ...PGlite.defaultStartParams, + '-c', + `application_name=${dateTime}` + ] + }) + + const databaseAndRole = await db.exec( + `SELECT setting FROM pg_settings WHERE name='application_name'`, + ) + expect(databaseAndRole[0].rows[0].setting).toEqual(dateTime) + }) }) }) From e4f5192ad3d5bef4570081fe7ac45b0137fb9a08 Mon Sep 17 00:00:00 2001 From: tudor Date: Mon, 30 Mar 2026 13:32:24 +0200 Subject: [PATCH 5/5] test for startParams --- packages/pglite/tests/basic.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pglite/tests/basic.test.ts b/packages/pglite/tests/basic.test.ts index dd92e6ca6..9a058762f 100644 --- a/packages/pglite/tests/basic.test.ts +++ b/packages/pglite/tests/basic.test.ts @@ -681,14 +681,14 @@ await testEsmCjsAndDTC(async (importType) => { startParams: [ ...PGlite.defaultStartParams, '-c', - `application_name=${dateTime}` - ] + `application_name=${dateTime}`, + ], }) const databaseAndRole = await db.exec( `SELECT setting FROM pg_settings WHERE name='application_name'`, ) expect(databaseAndRole[0].rows[0].setting).toEqual(dateTime) - }) + }) }) })