Receber por email
← Voltar para o catálogo

api-baas-neon

Serverless PostgreSQL with branching, autoscaling, and edge-compatible driver

11estrelas
Atualizado há 7 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add agents-inc/skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/api-baas-neon/svg)](https://www.skillteca.com.br/skills/api-baas-neon)

Skills relacionadas

Ver todas de Dados e Análise →

Alerta por categoria

Receba novas skills de Dados e Análise toda segunda

1 email curto, só com as skills novas de Dados e Análise. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Neon Serverless PostgreSQL Patterns

Quick Guide: Use @neondatabase/serverless for edge/serverless database access. Prefer the neon() HTTP function for single queries (faster, stateless) and Pool/Client for interactive transactions. Use pooled connection strings (-pooler suffix) for serverless workloads, direct connections only for migrations. Branch your database for dev/preview environments using copy-on-write semantics. Always handle cold starts from scale-to-zero (200-500ms wake-up).

<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use the neon() HTTP function for single queries in edge/serverless runtimes -- it is 2-3x faster than WebSocket for one-shot operations)

(You MUST close Pool/Client connections within the same request handler in serverless environments -- WebSocket connections cannot outlive a single request)

(You MUST use pooled connection strings (-pooler suffix) for serverless workloads -- direct connections exhaust the limited connection slots)

(You MUST handle scale-to-zero wake-up latency (200-500ms) with appropriate connection timeouts and retry logic)

(You MUST use sql.unsafe() only for trusted, known-safe strings like table/column names -- never for user input)

</critical_requirements>

Auto-detection: Neon, @neondatabase/serverless, neon(), neonConfig, neon serverless driver, neon database, neon branch, neonctl, neon connection pooling, neon scale-to-zero, neon autoscaling, neon postgres, ep-\*-pooler

When to use:

  • Querying Postgres from edge/serverless functions (edge runtimes, serverless platforms)
  • Setting up connection strings (pooled vs direct) for different workloads
  • Creating database branches for dev, preview, or CI environments
  • Managing scale-to-zero behavior and cold start optimization
  • Running transactions in serverless contexts (HTTP batch or WebSocket)
  • Programmatic branch management via Neon API or neonctl CLI

Key patterns covered:

  • neon() HTTP queries with SQL tagged templates and composable fragments
  • Pool/Client WebSocket connections with proper lifecycle management
  • Pooled (-pooler) vs direct connection strings and when to use each
  • Database branching (dev branches, PR preview branches, schema-only branches)
  • Scale-to-zero behavior, cold start mitigation, and autoscaling
  • sql.transaction() for non-interactive HTTP transactions
  • Neon API and neonctl CLI for programmatic branch management

When NOT to use:

  • Traditional long-lived server connections (use standard pg driver with TCP)
  • Complex ORM-specific patterns (use your ORM's own skill)
  • General PostgreSQL query syntax (use a SQL/Postgres skill)

Detailed Resources:

  • For decision frameworks and quick lookup tables, see [reference.md](reference.md)

Driver & Queries:

  • [examples/core.md](examples/core.md) -- Driver setup, HTTP queries, WebSocket connections, transactions

Branching & Operations:

  • [examples/branching.md](examples/branching.md) -- Dev branches, PR previews, neonctl CLI, Neon API, CI/CD workflows

<philosophy>

Philosophy

Neon separates storage and compute for PostgreSQL, enabling serverless features impossible with traditional Postgres: scale-to-zero, instant branching, and autoscaling. The @neondatabase/serverless driver replaces TCP with HTTP and WebSockets, making Postgres accessible from edge runtimes that lack TCP support.

Core principles:

  1. HTTP for speed, WebSocket for sessions -- The neon() function uses HTTP fetch (~3 round trips) for single queries. Pool/Client use WebSockets (~8 round trips) when you need sessions or interactive transactions. Pick the right transport for the job.
  2. Pooled by default -- Pooled connections route through PgBouncer (transaction mode), handling up to 10,000 concurrent clients. Direct connections are limited by compute size (100-4,000) and should only be used for migrations or features requiring session state.
  3. Branches are cheap -- Copy-on-write means a branch of a 500GB database allocates no extra storage until data diverges. Use branches freely for dev, preview, testing, and CI.
  4. Scale-to-zero is the default -- Computes suspend after 5 minutes of inactivity. Cold starts take 200-500ms. Design for this with timeouts, retries, and connection pooling.
  5. SQL injection safety built in -- The tagged template function parameterizes automatically. Since v1.0, calling neon() as a regular function is a type error, preventing accidental injection.

When to use Neon serverless driver:

  • Edge/serverless functions that cannot open TCP connections
  • Applications benefiting from database branching (preview environments per PR)
  • Cost-sensitive workloads that benefit from scale-to-zero
  • High-concurrency serverless apps needing connection pooling

When NOT to use:

  • Long-running server processes with persistent connections (use standard pg over TCP)
  • Workloads requiring session-level features through PgBouncer (LISTEN/NOTIFY, SET, temporary tables)
  • Databases larger than 16 CU that need always-on compute (scale-to-zero not available above 16 CU)

</philosophy>

<patterns>

Core Patterns

Pattern 1: HTTP Queries with neon()

The neon() function creates an HTTP-based query function using SQL tagged templates. It is the fastest path for single, non-interactive queries.

import { neon } from "@neondatabase/serverless";

const DATABASE_URL = process.env.DATABASE_URL!;
const sql = neon(DATABASE_URL);

// Tagged template -- parameters are auto-parameterized (safe from injection)
const userId = "abc-123";
const posts =
  await sql`SELECT id, title FROM posts WHERE author_id = ${userId}`;

Why good: Tagged template auto-parameterizes values preventing SQL injection, HTTP is ~3 round trips vs ~8 for WebSocket, stateless (no connection to manage)

// BAD: Calling neon() as a regular function (v1.0+ type error)
const sql = neon(DATABASE_URL);
const result = await sql(`SELECT * FROM posts WHERE id = ${id}`); // TYPE ERROR + SQL injection risk

Why bad: Since v1.0, calling the query function as a regular function (not a tagged template) is a runtime and type error -- this was changed specifically to prevent SQL injection from string interpolation

sql.query() for Dynamic SQL

When the query string is in a variable (not a template literal), use the .query() method with numbered placeholders:

const q = "SELECT * FROM posts WHERE id = $1 AND status = $2";
const posts = await sql.query(q, [postId, "published"]);

When to use: Dynamic SQL strings built at runtime, or queries stored in variables. Parameters are still safely parameterized via $1, $2, etc.

Pattern 2: Composable Query Fragments

Template queries support composition with automatic parameter numbering across fragments.

import { neon } from "@neondatabase/serverless";

const sql = neon(DATABASE_URL);

// Build queries from reusable fragments
const whereClause = sql`WHERE status = ${"active"} AND role = ${"admin"}`;
const orderClause = sql`ORDER BY created_at DESC`;
const PAGE_SIZE = 20;
const limitClause = sql`LIMIT ${PAGE_SIZE}`;

const users =
  await sql`SELECT id, name, email FROM users ${whereClause} ${orderClause} ${limitClause}`;

Why good: Parameters are renumbered automatically across composed fragments, named constant for page size, fragments are reusable across queries

Dynamic Table/Column Names with sql.unsafe()

// ONLY for trusted, known-safe values -- never user input
const TABLE_NAME = "posts";
const results =
  await sql`SELECT * FROM ${sql.unsafe(TABLE_NAME)} WHERE id = ${postId}`;

When to use: Only when you need to interpolate trusted identifiers (t

Compartilhar X LinkedIn