AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides guidance for working with Lakebase Postgres on Neon. It covers connection management, schema migrations, branching workflows, autoscaling, and performance diagnostics. It is designed to assist with database operations including inspecting schemas, optimizing egress, and implementing search features like vector, full-text, and hybrid search. The skill distinguishes between pooled and direct connection usage, provides diagnostic tools for performance analysis, and outlines procedures for managing compute resources and database branches.
What it does
- Provides best practices for pooled versus direct connection usage
- Guides schema migration and branching workflows including schema-only and branch-per-PR
- Offers diagnostic tools for identifying egress anti-patterns and query performance issues
- Supports configuration of autoscaling, scale-to-zero, and read replicas
- Facilitates implementation of semantic, full-text, and hybrid search features
- Assists with compute management tasks like resizing, suspending, and restarting
When to use it
- When working with an existing DATABASE_URL, SQL, or database schema
- When diagnosing high database bills or network egress issues
- When planning isolated environments for migration testing or preview deployments
- When implementing vector, full-text, or hybrid search capabilities
- When needing to inspect database performance or compute behavior
Advantages
- Provides clear distinctions between pooled and direct connection use cases
- Offers structured workflows for database branching and migration testing
- Includes specific diagnostic queries for identifying egress and performance bottlenecks
- Integrates with Neon CLI and MCP for operational tasks
- Supports modern development patterns like branch-per-PR
Usage examples
- “How do I optimize my database egress costs?”
- The agent will guide you through diagnosing top egress contributors using pg_stat_statements, analyzing your codebase for anti-patterns, and applying fixes like column selection and pagination.
- “Create a new branch for testing my schema migration.”
- The agent will verify your CLI or MCP authentication and execute the branch creation, providing you with the connection string for the new isolated environment.
- “Which connection string should I use for my migration script?”
- The agent will explain that migrations require a direct (unpooled) connection and help you identify the correct string without the -pooler suffix.
- “How can I implement vector search in my Neon database?”
- The agent will provide guidance on using Lakebase Search, including setting up the necessary extensions and managing the search implementation via your ORM.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/neondatabase/neon-postgres/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip neon-postgres.zip -d .agents/skills
Documentation by Neon
FIRST: Use the parent neon skill for a Neon overview, getting started with Neon, Neon development best practices, and more.
If the neon skill is not installed, fetch it from https://neon.com/docs/ai/skills/neon/SKILL.md or install it with:
neon skills -s neon -yLakebase Postgres
Lakebase Postgres is the database at the core of Neon. It runs on the lakebase architecture — OLTP built directly on cloud object storage — which decouples storage from compute to offer autoscaling, branching, instant restore, and scale-to-zero. It's fully compatible with Postgres and works with any language, framework, or ORM that supports Postgres.
It is the same database whether you reach it through Neon or through Databricks; this skill covers the Neon access path.
Login, users, sessions, and @neon/auth belong in neon-auth.
Live queries, reactive UIs, and realtime data belong in neon-realtime.
Setup Flow
1. Select the organization and project
If a DATABASE_URL is already supplied (prompt, environment, or repo) or a .neon file points at a project, use it. Do not list organizations or create a second project for schema work.
Otherwise use the CLI (default) or MCP server to list organizations and projects. Let the user select an existing project or create a new one.
2. Get the connection string
If a DATABASE_URL is already supplied, use it. Do not fetch another through the CLI or MCP.
Otherwise use the CLI (default), neon env pull, or the MCP server to get the connection string. Store it in .env as DATABASE_URL. Read the file first before modifying it, to avoid overwriting existing values.
When to use pooled vs direct connections
| Use case | Connection type |
|---|---|
| Web applications, serverless functions | Pooled (-pooler) |
| Schema migrations | Direct |
| pg_dump / pg_restore | Direct |
| Logical replication | Direct |
| Long-running analytics with temp tables | Direct |
| Admin tasks needing SET or session state | Direct |
| LISTEN / NOTIFY | Direct |
3. Pick the connection method and driver
Preserve the existing ORM and driver. For new TypeScript schema work with no established choice, Drizzle is a suggestion: https://neon.com/docs/guides/drizzle.md. Refer to the connection methods guide to pick the correct driver based on how the runtime treats your code: https://neon.com/docs/connect/choose-connection.md.
Driver notes:
On Vercel, use
node-postgres(npm install pg) with Vercel Fluid compute andimport { attachDatabasePool } from "@vercel/functions";On Cloudflare, use
node-postgreswith Cloudflare HyperdriveOn Neon Functions, use
node-postgres, as the functions are long-running and reuse the pool across requests.Use the
@neondatabase/serverlessdriver for serverless and edge environments (for example, when using Netlify) — HTTP transport for one-shot queries, WebSocket for transaction support. Link: https://neon.com/docs/serverless/serverless-driver.md
4. Set up the schema
Manage schemas and migrations as code. Avoid running ad hoc schema migrations against your database, since they're hard to manage.
If you're using an ORM, follow your ORM's best practices to manage schemas and migrations. For example, if using Drizzle, only use Drizzle for schema and migration management unless instructed otherwise.
Branching
Use this when the user is planning isolated environments, schema migration testing, preview deployments, or branch lifecycle automation.
Key points:
Branches are instant, copy-on-write clones (no full data copy).
Each branch has its own compute endpoint.
Use the neon CLI or MCP server to create, inspect, and compare branches.
Link: https://neon.com/docs/introduction/branching.md
For detailed branch creation workflows (normal vs schema-only branches, reset-from-parent, CLI/MCP selection, and CI/CD patterns), read Branching workflows.
Migrations
Test a migration on a branch of production, against production-like data, before applying it to production.
Use a direct (non-pooled) connection string when you run the migration, not a pooled one. neon connection-string returns the direct string by default; make sure the hostname does not include the -pooler suffix.
Egress Optimization
Use this when a user reports high database bills, unexpected network transfer, egress spikes, query overfetching, or wants a cost-efficiency review of database query patterns.
Before editing code, read Egress optimization. Audit all five patterns: unused columns, missing pagination, repeated static reads, application-side aggregation, and JOIN duplication. Do not stop after fixing SELECT *.
Work in four steps: diagnose which queries transfer the most data, analyze the code behind them, fix the anti-patterns, then verify that behavior is preserved and transfer drops.
Troubleshooting and Neon-Specific Performance
Use Neon's predefined, read-only diagnostics before writing catalog queries by hand. The Neon CLI neon inspect db subcommands and the Neon MCP server's inspect_database tool run the same checks.
This section covers Neon-specific diagnostic tools, compute cache behavior, and platform signals. When the evidence points to generic Postgres work such as rewriting a query, choosing an index, changing a schema, or interpreting plan nodes, load the postgres-best-practices skill and carry the diagnostic evidence into that workflow.
Docs:
Query performance: https://neon.com/docs/postgresql/query-performance.md
pg_stat_statements: https://neon.com/docs/extensions/pg_stat_statements.mdNeon Local File Cache: https://neon.com/docs/extensions/neon.md
Choose CLI or MCP
Prefer the Neon CLI when terminal access and authentication are available:
neon inspect db <check>The CLI resolves the project and branch from the current Neon context. Use --project-id, --branch, and --database-name to override it. Omit --database-name to inspect every database on the branch. Use --db-url only when inspecting a Postgres database directly instead of resolving it through the Neon API.
When using Neon MCP, call inspect_database with projectId and one check. Pass branchId, databaseName, or computeId only when needed. Omit databaseName to inspect all databases on the branch. Increase limit only when the result says it was truncated.
Pick the Diagnostic
| Symptom or question | Checks |
|---|---|
| Which relations consume storage? | table-sizes, index-sizes |
| Is an index unused or a table scanned heavily? | unused-indexes, seq-scans |
| What has run for 5+ minutes or holds locks? | long-running-queries, locks |
| Which queries consume the most total time? | outliers |
| Which queries run most often? | calls |
| Does the active data fit in compute cache? | lfc-hit-rate, working-set |
| Is autovacuum behind or is space wasted? | vacuum-stats, bloat |
| Is logical replication healthy? | replication-slots, subscriptions |
Do not confuse these checks:
long-running-queriesreports statements running right now for more than five minutes.outliersranks the top queries by cumulative execution time since statistics were reset. It does not rank by mean latency.callsranks by execution count over the same statistics history.
outliers and calls require pg_stat_statements. lfc-hit-rate and working-set require the neon extension. If a check reports a missing extension, ask before running the suggested CREATE EXTENSION statement because installing an extension modifies the database.
Interpret Results Safely
Treat
unused-indexesas a candidate list, not permission to drop indexes. Confirm the observation window, constraints, and workload before removal.A sequential scan can be correct for a small table or a query reading much of a table. Check table size, selectivity, and the query plan before adding an index.
bloatis a statistical estimate. Confirm the impact and plan locks or maintenance beforeVACUUM FULL,REINDEX, or similar remediation.Cache and Postgres statistics reset when compute restarts, including scale-to-zero suspension. Run a representative workload before interpreting fresh
lfc-hit-rate,working-set,vacuum-stats, orpg_stat_statementsresults.Compute-wide checks (
lfc-hit-rate,working-set, andreplication-slots) run once even when inspecting every database.One failing database can fail an all-databases inspection; retry the relevant check with an explicit
databaseNameto isolate it.
Inspect Neon Cache Behavior Per Query
Standard EXPLAIN (ANALYZE, BUFFERS) reports Postgres shared-buffer activity, but it does not show Neon's Local File Cache (LFC) or page prefetching. For a safe read-only query, add Neon's FILECACHE and PREFETCH options:
EXPLAIN (ANALYZE, BUFFERS, PREFETCH, FILECACHE)
SELECT ...;File cache: hitscounts pages found in the compute's LFC.File cache: missescounts pages not found in the LFC and fetched from database storage.Prefetch: hits,misses,expired, andduplicatesshow how effectively Neon fetched pages before the executor requested them.
FILECACHE and PREFETCH provide metrics for this query and do not require the neon extension. By contrast, neon inspect db lfc-hit-rate and working-set provide compute-wide statistics and do require the extension.
The MCP explain_sql_statement tool can produce a standard plan but does not expose FILECACHE or PREFETCH options. To collect those Neon-specific metrics through MCP, use run_sql with the explicit, read-only EXPLAIN statement above.
Because ANALYZE executes the statement, use it only when execution is safe; do not run it autonomously for mutating SQL. Compare cold- and warm-cache runs carefully because the first execution can populate the cache and materially change later results.
Performance Workflow
Reproduce the symptom and note its time window.
Run the smallest relevant
inspectchecks from the table above.Identify a specific query before changing schema or compute. Use MCP
explain_sql_statementfor a standard plan, or the Neon-specificEXPLAINabove when LFC or prefetch behavior matters.If the bottleneck is query shape, indexing, schema, locking, or vacuum behavior, load
postgres-best-practicesand carry forward the inspection results and query plan. Keep Neon compute, cache, connection, and platform decisions in this skill.Re-run the same check and workload to verify the change.
Use MCP list_slow_queries instead of inspect_database when the user specifically needs queries ranked by average execution time with a custom threshold and limit. Outside the explicit EXPLAIN case above, use run_sql only for read-only diagnostic SQL when the predefined checks do not answer the question.
Computes
Use this when the user wants to resize a compute, change its scale-to-zero timeout, or start, suspend, restart, or delete it.
Manage computes with neon postgres computes. neon pg and neon lakebase are aliases of neon postgres.
neon postgres computes list # --branch <branch> or the branch .neon pins; --all-branches for the project
neon postgres computes get <compute-id>
neon postgres computes update <compute-id> --cu 0.25-2 --suspend-timeout 300
neon postgres computes restart <compute-id> # also start, suspend, deleteupdate sends only the flags you pass (--cu, --suspend-timeout, --name, --disabled) and fails when you pass none. Each change waits until Neon applies it; update, start, suspend, and restart then print the compute. With --no-wait the command returns once the API accepts the change; find the operation with neon operations list and check it with neon operations get <operation-id>. Add a compute, such as a read replica, with neon branches add-compute <branch>.
Autoscaling
Use this when the user needs compute to scale automatically with workload and wants guidance on CU sizing and runtime behavior.
Set a compute's autoscaling range with neon postgres computes update <compute-id> --cu <min>-<max> (for example --cu 0.25-2), or a fixed size with --cu 2.
Link: https://neon.com/docs/introduction/autoscaling.md
Scale to Zero
Use this when optimizing idle costs and discussing suspend/resume behavior, including cold-start trade-offs.
Key points:
Idle computes suspend automatically after a default of 5 minutes. Change the timeout with
neon postgres computes update <compute-id> --suspend-timeout <seconds>:0uses the plan default and-1disables suspension. Free cannot change it, Launch can only enable or disable suspension, and Scale can set any value from 60 to 604800 (one week).First query after suspend typically has a cold-start penalty (around hundreds of ms)
Storage remains active while compute is suspended.
Link: https://neon.com/docs/introduction/scale-to-zero.md
Keep hot reads off Postgres
Scale to zero only suspends an idle compute. When the same rarely changing rows (config, categories, feature flags) are read on every request, cache them outside Postgres, for example in Upstash Redis with a TTL. Cached reads cut egress and cold-start latency, and let an otherwise idle compute stay suspended.
Instant Restore
Use this when the user needs point-in-time recovery or wants to restore data state without traditional backup restore workflows.
Key points:
History windows for instant restore depend on plan limits.
Users can create branches from historical points-in-time.
Time Travel queries can be used for historical inspection workflows.
Link: https://neon.com/docs/introduction/branch-restore.md
Read Replicas
Use this for read-heavy workloads where the user needs dedicated read-only compute without duplicating storage.
Key points:
Replicas are read-only compute endpoints sharing the same storage.
Creation is fast and scaling is independent from primary compute.
Typical use cases: analytics, reporting, and read-heavy APIs.
Link: https://neon.com/docs/introduction/read-replicas.md
Connection Pooling
Use this when the user is in serverless or high-concurrency environments and needs safe, scalable Postgres connection management.
Key points:
Neon pooling uses PgBouncer.
Add
-poolerto endpoint hostnames to use pooled connections.Pooling is especially important in serverless runtimes with bursty concurrency.
Link: https://neon.com/docs/connect/connection-pooling.md
IP Allow Lists
Use this when the user needs to restrict database access by trusted networks, IPs, or CIDR ranges.
Link: https://neon.com/docs/introduction/ip-allow.md
Logical Replication
Use this when integrating CDC pipelines, external Postgres sync, or replication-based data movement.
Key points:
Neon supports native logical replication workflows.
Useful for replicating to/from external Postgres systems.
Link: https://neon.com/docs/guides/logical-replication-guide.md
Lakebase Search
Use Lakebase Search for semantic, full-text, and hybrid search:
For semantic search, including generating embeddings with the Neon AI Gateway, read Vector search.
For full-text search with BM25 ranking, read Full-text search.
For combining semantic and lexical results with fusion or reranking, read Hybrid search.
For managing any of the above through Drizzle ORM, read Managing Lakebase Search with Drizzle.
Links:
Gotchas
Pooled vs direct connections: use the direct URL for migrations, dumps, and replication
Neon gives you two connection strings for the same database: a pooled one (hostname with the -pooler suffix) and a direct/unpooled one (no -pooler suffix). neon env pull writes them as DATABASE_URL and DATABASE_URL_UNPOOLED. The pooled connection routes through PgBouncer in transaction mode, which doesn't support session-level operations. Choose the right one:
Pooled (
DATABASE_URL) — your application's normal query traffic, especially serverless and connection-per-request workloads.Direct (
DATABASE_URL_UNPOOLED) — schema migrations (Prisma Migrate, Drizzle Kit, Alembic, and others),pg_dump/pg_restore, logical replication,LISTEN/NOTIFY, and anything relying onSETor other session state.
Running migrations, dumps, or replication over the pooled connection can fail, and never in a way that names pooling: prepared statement "s0" already exists from Prisma Migrate, a SET search_path that doesn't persist past its own transaction so the next query reports relation "mytable" does not exist, or a write intermittently hitting a read-only transaction (SQLSTATE 25006) that a pooled backend inherited from an earlier client. Migration tools generally take both strings at once — Prisma's directUrl alongside url — so point that at the direct one rather than swapping DATABASE_URL and losing pooling for the application. See https://neon.com/docs/connect/connection-pooling.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer870 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md18.9 KiB
- references/branching.md12.4 KiB
- references/egress-optimization.md9.3 KiB
- references/full-text-search.md4.2 KiB
- references/hybrid-search.md10.4 KiB
- references/lakebase-search-drizzle.md9.9 KiB
- references/vector-search.md12.2 KiB
references/vector-search.md
Semantic Vector Search
Use lakebase_vector for approximate nearest-neighbor retrieval over embeddings. It retains pgvector's vector types, distance operators, and query syntax; the index access method is lakebase_ann.
Contents
Create the extension — enable
lakebase_vectorand itspgvectordependencyPrepare embeddings — generate vectors with the AI Gateway and match the column dimension
Build the index — match the distance metric, operator class, and query operator
Tune the index — configure index-build options and concurrent index management
Query — rank by vector distance or filter by a similarity radius
Tune search — inspect the index and tune recall against latency
Use prefilter selectively — apply selective filters before ANN scoring
Create the Extension
Lakebase Search requires Postgres 16 or later. Enable the extension before creating vector columns or indexes:
CREATE EXTENSION IF NOT EXISTS lakebase_vector CASCADE;lakebase_vector installs pgvector through CASCADE. It relies on a preloaded library that Neon enables by default; if the project customized its preloaded-library list, confirm the library remains enabled.
Prepare Embeddings
Neon's AI Gateway embeddings endpoint is an OpenAI-compatible way to generate vectors for Lakebase Search. This table uses 1024 dimensions as an example; set the column dimension to the output of the model and any dimensions parameter you choose:
CREATE TABLE documents (
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
title text NOT NULL,
body text NOT NULL,
embedding vector(1024)
);The AI Gateway is available on every Neon plan, including Free, and draws down prepaid AI Gateway credits. If a model shows enabled: false in GET /v1/models, the branch's AI Gateway page in the Neon Console lists the reason and the fix. See the neon-ai-gateway skill.
Enable the AI Gateway on the branch and get NEON_AI_GATEWAY_TOKEN and the bare-host NEON_AI_GATEWAY_BASE_URL:
With
neon.ts, declareaiGateway: true, runneon deploy, then runneon env pull --file .env.Without
neon.ts, runneon env pull --service ai-gateway --file .envfrom a directory linked to the intended project and branch. This requests the gateway variables explicitly and skips other services.Alternatively, get both values from the Neon Console. Neon Functions receive them automatically.
AI SDK (Recommended)
For TypeScript apps, use Neon's @neon/ai-sdk-provider 1.0.0+ with the Vercel AI SDK (ai, 6+) (npm install @neon/ai-sdk-provider ai dotenv). The provider reads NEON_AI_GATEWAY_TOKEN and NEON_AI_GATEWAY_BASE_URL directly and sends embedding requests to /v1/embeddings. Load .env in a standalone app; Neon Functions inject the variables automatically.
import "dotenv/config";
import { neon } from "@neon/ai-sdk-provider";
import { embed, embedMany } from "ai";
const embeddingModel = neon.embeddingModel("qwen3-embedding-0-6b");
const providerOptions = { neon: { dimensions: 1024 } };
// Qwen3 query prompt adapted for Neon documentation search; documents stay unprefixed.
const queryPrompt =
"Instruct: Given a question about Neon, retrieve documentation passages that answer the question\nQuery: ";
const { embeddings: documentEmbeddings } = await embedMany({
model: embeddingModel,
values: documentBodies, // non-empty document batch; store vectors by input index
providerOptions,
maxParallelCalls: 1,
});
const { embedding: queryEmbedding } = await embed({
model: embeddingModel,
value: `${queryPrompt}${queryText}`,
providerOptions,
}); // bind to $1 belowSkip empty imports before calling embedMany. It returns vectors in input order and splits requests according to the provider's item limit. For large imports, also split document text within the endpoint's token limits and keep database writes bounded.
For Neon documentation search, the example adapts the task instruction in Qwen3's stored query prompt from config_sentence_transformers.json. Its document prompt is empty, so document text stays unprefixed. Neither SDK applies SentenceTransformers prompts automatically. Keep the original queryText for BM25, and use the selected model's own prompt conventions if you switch models.
OpenAI SDK Alternative
For an existing OpenAI SDK integration, install openai and dotenv (npm install openai dotenv) and configure the client explicitly:
import "dotenv/config";
import OpenAI from "openai";
const apiKey = process.env.NEON_AI_GATEWAY_TOKEN;
const gatewayBaseUrl = process.env.NEON_AI_GATEWAY_BASE_URL;
if (!apiKey || !gatewayBaseUrl) {
throw new Error("Missing Neon AI Gateway credentials");
}
const client = new OpenAI({
apiKey,
baseURL: `${gatewayBaseUrl}/v1`,
});
async function embedBatch(inputs: string[]): Promise<number[][]> {
if (inputs.length === 0) return [];
const response = await client.embeddings.create({
model: "qwen3-embedding-0-6b",
input: inputs,
dimensions: 1024,
encoding_format: "float",
});
const vectors: number[][] = [];
for (const item of response.data) vectors[item.index] = item.embedding;
return inputs.map((_, index) => {
const embedding = vectors[index];
if (!embedding) throw new Error(`Missing embedding for input ${index}`);
return embedding;
});
}
const documentEmbeddings = await embedBatch(documentBodies);
const [queryEmbedding] = await embedBatch([`${queryPrompt}${queryText}`]);
if (!queryEmbedding) throw new Error("Missing query embedding");Use the same queryPrompt defined above, only for query inputs. Keep each batch within the endpoint's input and rate limits, and pair each vector with its source row using the response index. The OpenAI JavaScript SDK v6 defaults to requesting base64 and decodes the response as base64. If a compatible endpoint returns float arrays instead, that decoder can silently turn them into zeros. Pass encoding_format: "float" explicitly for the AI Gateway; the SDK then returns the float arrays directly. Base64 can reduce response size when an endpoint actually returns base64, but do not assume that format for this gateway.
Use the same model and output dimensions for stored documents and queries. Follow the model's input conventions: some models recommend a query instruction while document text remains unprefixed. If the model supports shorter vectors, compare retrieval quality, storage, and latency before changing dimensions; set the column and both embedding requests to the chosen size. Switching models requires re-embedding the corpus; changing dimensions also requires migrating the vector column and index. Generate embeddings in the application, outside SQL, unless the architecture already provides an in-database embedding function. Other embedding providers are also valid when their output matches the schema and index.
Build the Index
Choose the operator class and query operator as a matched pair:
| Metric | Common use | Operator class | Distance operator |
|---|---|---|---|
| Cosine | Most text embeddings | vector_cosine_ops | <=> |
| L2 / Euclidean | Absolute distance matters; vectors do not need normalization | vector_l2_ops | <-> |
| Inner product | Unit-normalized vectors; matches cosine for unit vectors | vector_ip_ops | <#> |
Choose the metric recommended for the selected model, and keep its index operator class and query operator aligned. The Qwen3 Embedding model card demonstrates cosine similarity and normalized dot product for retrieval. For unit-normalized vectors, cosine, inner product, and L2 have the same exact ranking; approximate indexes can still differ in recall and latency, so benchmark on your corpus.
CREATE INDEX documents_embedding_ann ON documents
USING lakebase_ann (embedding vector_cosine_ops);Tune the Index
The default index options suit most workloads:
build_mode = 'standard'balances recall and index build time. Usequalityfor better recall when a longer build is acceptable.lists = 'auto'chooses the IVF partition layout from the number of indexed vectors. Choose betweenautoand a manual value case by case: test both on the target dataset and use the value that better meets recall and performance targets.
To prioritize recall over index build time:
CREATE INDEX documents_embedding_ann_quality ON documents
USING lakebase_ann (embedding vector_cosine_ops)
WITH (build_mode = 'quality');To override the automatic partition layout instead:
CREATE INDEX documents_embedding_ann_lists ON documents
USING lakebase_ann (embedding vector_cosine_ops)
WITH (lists = '1024');For a large table, use CREATE INDEX CONCURRENTLY to avoid locking out writes while creating the index. For a frequently changing table, periodically use REINDEX INDEX CONCURRENTLY to rebuild the index with minimal write locking.
Query
Generate the query embedding with the same model and dimensions used for stored documents, following the model's query-input conventions (using the Qwen3 query prompt shown above), then bind it as a parameter:
SELECT id, title, embedding <=> $1::vector AS distance
FROM documents
ORDER BY distance
LIMIT $2;Distance sorts ascending: a smaller value is a closer match. Keep the query operator consistent with the index operator class.
To filter by a similarity radius, use the matching boolean range operator in WHERE and the distance operator in ORDER BY:
SELECT id, title
FROM documents
WHERE embedding <<=>> sphere($1::vector, 0.5)
ORDER BY embedding <=> $1::vector
LIMIT $2;The cosine range operator <<=>> returns a boolean; do not use it as the ranking expression.
Tune Search
Inspect the index before overriding defaults:
SELECT lakebase_ann_index_info('documents_embedding_ann');This reports lists, default_probes, and default_epsilon. Small datasets use exact flat search before IVF lists are built. In that state, lists and default_probes are empty. Leave lakebase_ann.probes set to its default of 'auto'; lakebase_ann.epsilon still controls full-precision reranking during flat search.
For an IVF index, lakebase_ann.probes controls how many partitions are searched at each level. Higher values generally improve recall at the cost of speed. Its default is 'auto'. When lists is not empty, the shape of probes must match the shape of lists: use one value for a one-level index or two comma-separated values for a two-level index. At each level, the probes value must be no larger than the corresponding lists value. A mismatched or out-of-range value causes an error.
lakebase_ann.epsilon controls how many candidates are reranked using full-precision distances. Higher values rerank more candidates and take longer. Its default is 'auto', which works well for most workloads.
Use Prefilter Selectively
By default, PostgreSQL applies non-vector filters after the ANN index returns candidate rows. Enable prefilter when a filter is cheap to evaluate and removes most rows. Leave it off for loose or expensive filters.
BEGIN;
SET LOCAL lakebase_ann.prefilter = on;
SELECT id, title
FROM documents
WHERE id % 100 = 0
ORDER BY embedding <=> $1::vector
LIMIT $2;
COMMIT;Start with probes and epsilon set to 'auto'. Benchmark manual probe values against representative query embeddings and choose the smallest values that satisfy recall and tail-latency targets. Keep session settings and the query in the same transaction when using a connection pool or stateless driver.
Source: lakebase_vector documentation.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server, Needs network access, Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Neon
- Publisher
- Neon (Official)
- Source
- neondatabase/agent-skills · skills/neon-postgres · commit 2b0e2b6
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- neondatabase/agent-skills
AutoGineer is not affiliated with or endorsed by Neon.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download neon-postgres.zip