[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-b624e1c5-b85e-4668-bc5b-5edbd0c9028a":3,"$fGc7U9xUntS1bKpEfhkf2iNh449VKHfnFiNwgL9vmbV8":42},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":33},"b624e1c5-b85e-4668-bc5b-5edbd0c9028a","neon-postgres","Neon无服务器Postgres的专家模式、分支、连接","cat_coding_backend","mod_coding","sickn33,coding","---\nname: neon-postgres\ndescription: Expert patterns for Neon serverless Postgres, branching, connection\n  pooling, and Prisma\u002FDrizzle integration\nrisk: safe\nsource: vibeship-spawner-skills (Apache 2.0)\ndate_added: 2026-02-27\n---\n\n# Neon Postgres\n\nExpert patterns for Neon serverless Postgres, branching, connection pooling, and Prisma\u002FDrizzle integration\n\n## Patterns\n\n### Prisma with Neon Connection\n\nConfigure Prisma for Neon with connection pooling.\n\nUse two connection strings:\n- DATABASE_URL: Pooled connection for Prisma Client\n- DIRECT_URL: Direct connection for Prisma Migrate\n\nThe pooled connection uses PgBouncer for up to 10K connections.\nDirect connection required for migrations (DDL operations).\n\n### Code_example\n\n# .env\n# Pooled connection for application queries\nDATABASE_URL=\"postgres:\u002F\u002Fuser:password@ep-xxx-pooler.us-east-2.aws.neon.tech\u002Fneondb?sslmode=require\"\n# Direct connection for migrations\nDIRECT_URL=\"postgres:\u002F\u002Fuser:password@ep-xxx.us-east-2.aws.neon.tech\u002Fneondb?sslmode=require\"\n\n\u002F\u002F prisma\u002Fschema.prisma\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider  = \"postgresql\"\n  url       = env(\"DATABASE_URL\")\n  directUrl = env(\"DIRECT_URL\")\n}\n\nmodel User {\n  id        String   @id @default(cuid())\n  email     String   @unique\n  name      String?\n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n}\n\n\u002F\u002F lib\u002Fprisma.ts\nimport { PrismaClient } from '@prisma\u002Fclient';\n\nconst globalForPrisma = globalThis as unknown as {\n  prisma: PrismaClient | undefined;\n};\n\nexport const prisma = globalForPrisma.prisma ?? new PrismaClient({\n  log: process.env.NODE_ENV === 'development'\n    ? ['query', 'error', 'warn']\n    : ['error'],\n});\n\nif (process.env.NODE_ENV !== 'production') {\n  globalForPrisma.prisma = prisma;\n}\n\n\u002F\u002F Run migrations\n\u002F\u002F Uses DIRECT_URL automatically\nnpx prisma migrate dev\nnpx prisma migrate deploy\n\n### Anti_patterns\n\n- Pattern: Using pooled connection for migrations | Why: DDL operations fail through PgBouncer | Fix: Set directUrl in schema.prisma\n- Pattern: Not using connection pooling | Why: Serverless functions exhaust connection limits | Fix: Use -pooler endpoint in DATABASE_URL\n\n### References\n\n- https:\u002F\u002Fneon.com\u002Fdocs\u002Fguides\u002Fprisma\n- https:\u002F\u002Fwww.prisma.io\u002Fdocs\u002Form\u002Foverview\u002Fdatabases\u002Fneon\n\n### Drizzle with Neon Serverless Driver\n\nUse Drizzle ORM with Neon's serverless HTTP driver for\nedge\u002Fserverless environments.\n\nTwo driver options:\n- neon-http: Single queries over HTTP (fastest for one-off queries)\n- neon-serverless: WebSocket for transactions and sessions\n\n### Code_example\n\n# Install dependencies\nnpm install drizzle-orm @neondatabase\u002Fserverless\nnpm install -D drizzle-kit\n\n\u002F\u002F lib\u002Fdb\u002Fschema.ts\nimport { pgTable, serial, text, timestamp } from 'drizzle-orm\u002Fpg-core';\n\nexport const users = pgTable('users', {\n  id: serial('id').primaryKey(),\n  email: text('email').notNull().unique(),\n  name: text('name'),\n  createdAt: timestamp('created_at').defaultNow().notNull(),\n  updatedAt: timestamp('updated_at').defaultNow().notNull(),\n});\n\n\u002F\u002F lib\u002Fdb\u002Findex.ts (for serverless - HTTP driver)\nimport { neon } from '@neondatabase\u002Fserverless';\nimport { drizzle } from 'drizzle-orm\u002Fneon-http';\nimport * as schema from '.\u002Fschema';\n\nconst sql = neon(process.env.DATABASE_URL!);\nexport const db = drizzle(sql, { schema });\n\n\u002F\u002F Usage in API route\nimport { db } from '@\u002Flib\u002Fdb';\nimport { users } from '@\u002Flib\u002Fdb\u002Fschema';\n\nexport async function GET() {\n  const allUsers = await db.select().from(users);\n  return Response.json(allUsers);\n}\n\n\u002F\u002F lib\u002Fdb\u002Findex.ts (for WebSocket - transactions)\nimport { Pool } from '@neondatabase\u002Fserverless';\nimport { drizzle } from 'drizzle-orm\u002Fneon-serverless';\nimport * as schema from '.\u002Fschema';\n\nconst pool = new Pool({ connectionString: process.env.DATABASE_URL });\nexport const db = drizzle(pool, { schema });\n\n\u002F\u002F With transactions\nawait db.transaction(async (tx) => {\n  await tx.insert(users).values({ email: 'test@example.com' });\n  await tx.update(users).set({ name: 'Updated' });\n});\n\n\u002F\u002F drizzle.config.ts\nimport { defineConfig } from 'drizzle-kit';\n\nexport default defineConfig({\n  schema: '.\u002Flib\u002Fdb\u002Fschema.ts',\n  out: '.\u002Fdrizzle',\n  dialect: 'postgresql',\n  dbCredentials: {\n    url: process.env.DATABASE_URL!,\n  },\n});\n\n\u002F\u002F Run migrations\nnpx drizzle-kit generate\nnpx drizzle-kit migrate\n\n### Anti_patterns\n\n- Pattern: Using pg driver in serverless | Why: TCP connections don't work in all edge environments | Fix: Use @neondatabase\u002Fserverless driver\n- Pattern: HTTP driver for transactions | Why: HTTP driver doesn't support transactions | Fix: Use WebSocket driver (Pool) for transactions\n\n### References\n\n- https:\u002F\u002Fneon.com\u002Fdocs\u002Fguides\u002Fdrizzle\n- https:\u002F\u002Form.drizzle.team\u002Fdocs\u002Fconnect-neon\n\n### Connection Pooling with PgBouncer\n\nNeon provides built-in connection pooling via PgBouncer.\n\nKey limits:\n- Up to 10,000 concurrent connections to pooler\n- Connections still consume underlying Postgres connections\n- 7 connections reserved for Neon superuser\n\nUse pooled endpoint for application, direct for migrations.\n\n### Code_example\n\n# Connection string formats\n\n# Pooled connection (for application)\n# Note: -pooler in hostname\npostgres:\u002F\u002Fuser:pass@ep-cool-name-pooler.us-east-2.aws.neon.tech\u002Fneondb\n\n# Direct connection (for migrations)\n# Note: No -pooler\npostgres:\u002F\u002Fuser:pass@ep-cool-name.us-east-2.aws.neon.tech\u002Fneondb\n\n\u002F\u002F Prisma with pooling\n\u002F\u002F prisma\u002Fschema.prisma\ndatasource db {\n  provider  = \"postgresql\"\n  url       = env(\"DATABASE_URL\")      \u002F\u002F Pooled\n  directUrl = env(\"DIRECT_URL\")        \u002F\u002F Direct\n}\n\n\u002F\u002F Connection pool settings for high-traffic\n\u002F\u002F lib\u002Fprisma.ts\nimport { PrismaClient } from '@prisma\u002Fclient';\n\nexport const prisma = new PrismaClient({\n  datasources: {\n    db: {\n      url: process.env.DATABASE_URL,\n    },\n  },\n  \u002F\u002F Connection pool settings\n  \u002F\u002F Adjust based on compute size\n});\n\n\u002F\u002F For Drizzle with connection pool\nimport { Pool } from '@neondatabase\u002Fserverless';\n\nconst pool = new Pool({\n  connectionString: process.env.DATABASE_URL,\n  max: 10,  \u002F\u002F Max connections in local pool\n  idleTimeoutMillis: 30000,\n  connectionTimeoutMillis: 10000,\n});\n\n\u002F\u002F Compute size connection limits\n\u002F\u002F 0.25 CU: 112 connections (105 available after reserved)\n\u002F\u002F 0.5 CU: 225 connections\n\u002F\u002F 1 CU: 450 connections\n\u002F\u002F 2 CU: 901 connections\n\u002F\u002F 4 CU: 1802 connections\n\u002F\u002F 8 CU: 3604 connections\n\n### Anti_patterns\n\n- Pattern: Opening new connection per request | Why: Exhausts connection limits quickly | Fix: Use connection pooling, reuse connections\n- Pattern: High max pool size in serverless | Why: Many function instances = many pools = many connections | Fix: Keep local pool size low (5-10), rely on PgBouncer\n\n### References\n\n- https:\u002F\u002Fneon.com\u002Fdocs\u002Fconnect\u002Fconnection-pooling\n\n### Database Branching for Development\n\nCreate instant copies of your database for development,\ntesting, and preview environments.\n\nBranches share underlying storage (copy-on-write),\nmaking them instant and cost-effective.\n\n### Code_example\n\n# Create branch via Neon CLI\nneon branches create --name feature\u002Fnew-feature --parent main\n\n# Create branch from specific point in time\nneon branches create --name debug\u002Fyesterday \\\n  --parent main \\\n  --timestamp \"2024-01-15T10:00:00Z\"\n\n# List branches\nneon branches list\n\n# Get connection string for branch\nneon connection-string feature\u002Fnew-feature\n\n# Delete branch when done\nneon branches delete feature\u002Fnew-feature\n\n\u002F\u002F In CI\u002FCD (GitHub Actions)\n\u002F\u002F .github\u002Fworkflows\u002Fpreview.yml\nname: Preview Environment\non:\n  pull_request:\n    types: [opened, synchronize]\n\njobs:\n  create-branch:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: neondatabase\u002Fcreate-branch-action@v5\n        id: create-branch\n        with:\n          project_id: ${{ secrets.NEON_PROJECT_ID }}\n          branch_name: preview\u002Fpr-${{ github.event.pull_request.number }}\n          api_key: ${{ secrets.NEON_API_KEY }}\n          username: ${{ secrets.NEON_ROLE_NAME }}\n\n      - name: Run migrations\n        env:\n          DATABASE_URL: ${{ steps.create-branch.outputs.db_url_with_pooler }}\n        run: npx prisma migrate deploy\n\n      - name: Deploy to Vercel\n        env:\n          DATABASE_URL: ${{ steps.create-branch.outputs.db_url_with_pooler }}\n        run: vercel deploy --prebuilt\n\n\u002F\u002F Cleanup on PR close\non:\n  pull_request:\n    types: [closed]\n\njobs:\n  delete-branch:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: neondatabase\u002Fdelete-branch-action@v3\n        with:\n          project_id: ${{ secrets.NEON_PROJECT_ID }}\n          branch: preview\u002Fpr-${{ github.event.pull_request.number }}\n          api_key: ${{ secrets.NEON_API_KEY }}\n\n### Anti_patterns\n\n- Pattern: Sharing production database for development | Why: Risk of data corruption, no isolation | Fix: Create development branches from production\n- Pattern: Not cleaning up old branches | Why: Accumulates storage and clutter | Fix: Auto-delete branches on PR close\n\n### References\n\n- https:\u002F\u002Fneon.com\u002Fblog\u002Fbranching-with-preview-environments\n- https:\u002F\u002Fgithub.com\u002Fneondatabase\u002Fcreate-branch-action\n\n### Vercel Preview Environment Integration\n\nAutomatically create database branches for Vercel preview\ndeployments. Each PR gets its own isolated database.\n\nTwo integration options:\n- Vercel-Managed: Billing in Vercel, auto-setup\n- Neon-Managed: Billing in Neon, more control\n\n### Code_example\n\n# Vercel-Managed Integration\n# 1. Go to Vercel Dashboard > Storage > Create Database\n# 2. Select Neon Postgres\n# 3. Enable \"Create a branch for each preview deployment\"\n# 4. Environment variables automatically injected\n\n# Neon-Managed Integration\n# 1. Install from Neon Dashboard > Integrations > Vercel\n# 2. Select Vercel project to connect\n# 3. Enable \"Create a branch for each preview deployment\"\n# 4. Optionally enable auto-delete on branch delete\n\n\u002F\u002F vercel.json - Add migration to build\n{\n  \"buildCommand\": \"prisma migrate deploy && next build\",\n  \"framework\": \"nextjs\"\n}\n\n\u002F\u002F Or in package.json\n{\n  \"scripts\": {\n    \"vercel-build\": \"prisma generate && prisma migrate deploy && next build\"\n  }\n}\n\n\u002F\u002F Environment variables injected by integration\n\u002F\u002F DATABASE_URL - Pooled connection for preview branch\n\u002F\u002F DATABASE_URL_UNPOOLED - Direct connection for migrations\n\u002F\u002F PGHOST, PGUSER, PGDATABASE, PGPASSWORD - Individual vars\n\n\u002F\u002F Prisma schema for Vercel integration\ndatasource db {\n  provider  = \"postgresql\"\n  url       = env(\"DATABASE_URL\")\n  directUrl = env(\"DATABASE_URL_UNPOOLED\")  \u002F\u002F Vercel variable\n}\n\n\u002F\u002F For Drizzle in Next.js on Vercel\nimport { neon } from '@neondatabase\u002Fserverless';\nimport { drizzle } from 'drizzle-orm\u002Fneon-http';\n\n\u002F\u002F Use pooled URL for queries\nconst sql = neon(process.env.DATABASE_URL!);\nexport const db = drizzle(sql);\n\n### Anti_patterns\n\n- Pattern: Same database for all previews | Why: Previews interfere with each other | Fix: Enable branch-per-preview in integration\n- Pattern: Not running migrations on preview | Why: Schema mismatch between code and database | Fix: Add migrate command to build step\n\n### References\n\n- https:\u002F\u002Fneon.com\u002Fdocs\u002Fguides\u002Fvercel-managed-integration\n- https:\u002F\u002Fneon.com\u002Fdocs\u002Fguides\u002Fneon-managed-vercel-integration\n\n### Autoscaling and Cold Start Management\n\nNeon autoscales compute resources and scales to zero.\n\nCold start latency: 500ms - few seconds when waking from idle.\nProduction recommendation: Disable scale-to-zero, set minimum compute.\n\n### Code_example\n\n# Neon Console settings for production\n# Project Settings > Compute > Default compute size\n# - Set minimum to 0.5 CU or higher\n# - Disable \"Suspend compute after inactivity\"\n\n\u002F\u002F Handle cold starts in application\n\u002F\u002F lib\u002Fdb-with-retry.ts\nimport { prisma } from '.\u002Fprisma';\n\nconst MAX_RETRIES = 3;\nconst RETRY_DELAY = 1000;\n\nexport async function queryWithRetry\u003CT>(\n  query: () => Promise\u003CT>\n): Promise\u003CT> {\n  let lastError: Error | undefined;\n\n  for (let attempt = 1; attempt \u003C= MAX_RETRIES; attempt++) {\n    try {\n      return await query();\n    } catch (error) {\n      lastError = error as Error;\n\n      \u002F\u002F Retry on connection errors (cold start)\n      if (error.code === 'P1001' || error.code === 'P1002') {\n        console.log(`Retry attempt ${attempt}\u002F${MAX_RETRIES}`);\n        await new Promise(r => setTimeout(r, RETRY_DELAY * attempt));\n        continue;\n      }\n\n      throw error;\n    }\n  }\n\n  throw lastError;\n}\n\n\u002F\u002F Usage\nconst users = await queryWithRetry(() =>\n  prisma.user.findMany()\n);\n\n\u002F\u002F Reduce cold start latency with SSL direct negotiation\n# PostgreSQL 17+ connection string\npostgres:\u002F\u002Fuser:pass@ep-xxx-pooler.aws.neon.tech\u002Fdb?sslmode=require&sslnegotiation=direct\n\n\u002F\u002F Keep-alive for long-running apps\n\u002F\u002F lib\u002Fdb-keepalive.ts\nimport { prisma } from '.\u002Fprisma';\n\n\u002F\u002F Ping database every 4 minutes to prevent suspend\nconst KEEPALIVE_INTERVAL = 4 * 60 * 1000;\n\nif (process.env.NEON_KEEPALIVE === 'true') {\n  setInterval(async () => {\n    try {\n      await prisma.$queryRaw`SELECT 1`;\n    } catch (error) {\n      console.error('Keepalive failed:', error);\n    }\n  }, KEEPALIVE_INTERVAL);\n}\n\n\u002F\u002F Compute sizing recommendations\n\u002F\u002F Development: 0.25 CU, scale-to-zero enabled\n\u002F\u002F Staging: 0.5 CU, scale-to-zero enabled\n\u002F\u002F Production: 1+ CU, scale-to-zero DISABLED\n\u002F\u002F High-traffic: 2-4 CU minimum, autoscaling enabled\n\n### Anti_patterns\n\n- Pattern: Scale-to-zero in production | Why: Cold starts add 500ms+ latency to first request | Fix: Disable scale-to-zero for production branch\n- Pattern: No retry logic for cold starts | Why: First connection after idle may timeout | Fix: Add retry with exponential backoff\n\n### References\n\n- https:\u002F\u002Fneon.com\u002Fblog\u002Fscaling-serverless-postgres\n- https:\u002F\u002Fneon.com\u002Fdocs\u002Fconnect\u002Fconnection-latency\n\n## Sharp Edges\n\n### Cold Start Latency After Scale-to-Zero\n\nSeverity: HIGH\n\n### Using Pooled Connection for Migrations\n\nSeverity: HIGH\n\n### Connection Pool Exhaustion in Serverless\n\nSeverity: HIGH\n\n### PgBouncer Feature Limitations\n\nSeverity: MEDIUM\n\n### Branch Storage Accumulation\n\nSeverity: MEDIUM\n\n### Reserved Connections Reduce Available Pool\n\nSeverity: LOW\n\n### HTTP Driver Doesn't Support Transactions\n\nSeverity: MEDIUM\n\n### Deleting Parent Branch Affects Children\n\nSeverity: HIGH\n\n### Schema Drift Between Branches\n\nSeverity: MEDIUM\n\n## Validation Checks\n\n### Direct Database URL in Client Code\n\nSeverity: ERROR\n\nDirect database URLs should never be exposed to client\n\nMessage: Direct URL exposed to client. Only pooled URLs for server-side use.\n\n### Hardcoded Database Connection String\n\nSeverity: ERROR\n\nConnection strings should use environment variables\n\nMessage: Hardcoded connection string. Use environment variables.\n\n### Missing SSL Mode in Connection String\n\nSeverity: WARNING\n\nNeon requires SSL connections\n\nMessage: Missing sslmode=require. Add to connection string.\n\n### Prisma Missing directUrl for Migrations\n\nSeverity: ERROR\n\nPrisma needs directUrl for migrations through PgBouncer\n\nMessage: Using pooled URL without directUrl. Migrations will fail.\n\n### Prisma directUrl Points to Pooler\n\nSeverity: ERROR\n\ndirectUrl should be non-pooled connection\n\nMessage: directUrl points to pooler. Use non-pooled endpoint for migrations.\n\n### High Pool Size in Serverless Function\n\nSeverity: WARNING\n\nHigh pool sizes exhaust connections with many function instances\n\nMessage: Pool size too high for serverless. Use max: 5-10.\n\n### Creating New Client Per Request\n\nSeverity: WARNING\n\nCreating new clients per request wastes connections\n\nMessage: Creating client per request. Use connection pool or neon() driver.\n\n### Branch Creation Without Cleanup Strategy\n\nSeverity: WARNING\n\nBranches should have cleanup automation\n\nMessage: Creating branch without cleanup. Add delete-branch-action to PR close.\n\n### Scale-to-Zero Enabled on Production\n\nSeverity: WARNING\n\nScale-to-zero adds latency in production\n\nMessage: Scale-to-zero on production. Disable for low-latency.\n\n### HTTP Driver Used for Transactions\n\nSeverity: ERROR\n\nneon() HTTP driver doesn't support transactions\n\nMessage: HTTP driver with transaction. Use Pool from @neondatabase\u002Fserverless.\n\n## Collaboration\n\n### Delegation Triggers\n\n- user needs authentication -> clerk-auth (User table with clerkId column)\n- user needs caching -> redis-specialist (Query caching, session storage)\n- user needs search -> algolia-search (Full-text search beyond Postgres capabilities)\n- user needs analytics -> segment-cdp (Track database events, user actions)\n- user needs deployment -> vercel-deployment (Environment variables, preview databases)\n\n## When to Use\n- User mentions or implies: neon database\n- User mentions or implies: serverless postgres\n- User mentions or implies: database branching\n- User mentions or implies: neon postgres\n- User mentions or implies: postgres serverless\n- User mentions or implies: connection pooling\n- User mentions or implies: preview environments\n- User mentions or implies: database per preview\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.\n","","imported","https:\u002F\u002Fgithub.com\u002Fsickn33\u002Fantigravity-awesome-skills","user_system_seed","SkillOPIC",true,64,331,"2026-05-16 13:30:31",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"编程开发","coding","mdi-code-braces","代码生成、调试、审查，提升开发效率",2,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":25,"skillCount":32,"createdAt":26},"后端开发","backend","mdi-server","API、数据库、服务端架构",296,[34],{"id":35,"skillId":4,"version":36,"fileName":37,"fileSize":38,"filePath":39,"fileHash":40,"manifest":41,"createdAt":19},"1ab252c2-6fb0-4a98-931d-1ae0e3e92608","1.0.0","neon-postgres.zip",5846,"uploads\u002Fskills\u002Fb624e1c5-b85e-4668-bc5b-5edbd0c9028a\u002Fneon-postgres.zip","8d8b17c50f23b5c4004701e815d37e33d0fc3a0d211bc1dfb479d37c4821f04b","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":17082}]",{"code":43,"message":44,"data":45},200,"success",{"items":46,"stats":47,"page":50},[],{"averageRating":48,"totalRatings":48,"ratingCounts":49},0,[48,48,48,48,48],{"limit":51,"offset":48,"hasMore":52,"nextOffset":51,"ratedOnly":16},15,false]