layout: doc lang: en translation_key: go title: Batch row lookups with Go and pgx seo_title: “Batch PostgreSQL Row Lookups with Go and pgx” description: Use pg_local_cache from Go with pgx, parameterized keys, and decoded JSON rows. section: Go permalink: /docs/go.html

last_modified_at: “2026-09-16”

Batch row lookups with Go and pgx {#batch-row-lookups-with-go-and-pgx}

Start the disposable database first, then run:

go -C examples/go-pgx run ./demo

It uses 127.0.0.1:55432, database pglc_demo, and the demo / demo-only credentials. Set PGLC_DEMO_PORT when the quickstart uses another port.

The demo shows an ordinary prepared SQL fallback query:

SELECT id::text AS key, row_to_json(items)::text AS row
FROM public.items
WHERE id = ANY($1::bigint[]);

The example requests 42, 7, 42, NULL, 999999, restores input order in Go, and prints nulls for the null input and missing key. For cached reads, use RESP MGET; the endpoint uses the configured worker role and is not part of an application’s SQL transaction.

Compare rows, not just round trips {#compare-rows-not-just-round-trips}

An ordinary WHERE id = ANY($1::bigint[]) query does not preserve requested positions. Restore input order, duplicates and missing rows for ordinary SQL results. For cached complete-row reads, use RESP MGET; the batch lookup guide compares the contracts.

The benchmark uses persistent connections and prepared statements. Preparing SQL does not cache its result rows: see the PostgreSQL caching guide. The common benchmark tests Go and Node.js with the same keys, batch sizes, connection counts and duration through prepared SQL and RESP MGET. RESP does not share a caller’s SQL transaction.

See the quickstart for setup and transaction checks before adapting the read path.