Skip to content
Back to skills

Configuring Serverless Clients

ASecurity

Configure PrismaClient for serverless (Next.js, Lambda, Vercel) with connection_limit=1 and global singleton pattern.

  • 666 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 8, 2026
databasestypescriptbashsqlnextjsnodeawstestingapidatabase

Works with

  • cli
  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill configuring-serverless-clients --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Configuring Serverless Clients?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Configuring Serverless Clients
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-configuring-serverless-clients/badge)](https://www.skillsdirectory.com/skills/majiayu000-configuring-serverless-clients)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: configuring-serverless-clients
description: Configure PrismaClient for serverless (Next.js, Lambda, Vercel) with connection_limit=1 and global singleton pattern.
allowed-tools: Read, Write, Edit, Glob, Grep
---

# Serverless PrismaClient Configuration

Configure PrismaClient for serverless platforms to prevent connection pool exhaustion using connection limits and global singleton patterns.

## Activation Triggers

Deploy to Next.js (App/Pages Router), AWS Lambda, Vercel, or similar serverless platforms; encountering P1017 errors; files in app/, pages/api/, lambda/ directories.

## Problem & Solution

**Problem:** Each Lambda instance creates its own connection pool. Default unlimited pool × instances exhausts database (e.g., 10 instances × 10 connections = 100 connections).

**Solution:** Set `connection_limit=1` in DATABASE_URL; use global singleton to reuse client across invocations; consider PgBouncer for high concurrency.

## Configuration Workflow

**Phase 1—Environment:** Add `connection_limit=1` and `pool_timeout=20` to DATABASE_URL in .env; configure in Vercel dashboard if applicable.

**Phase 2—Client Singleton:** Create single global PrismaClient in `lib/prisma.ts`; use `globalThis` pattern (Next.js 13+ App Router), `global.prisma` pattern (Pages Router/Lambda), or initialize outside handler (Lambda standalone).

**Phase 3—Validation:** Verify DATABASE_URL contains connection parameters; confirm `new PrismaClient()` appears only in `lib/prisma.ts`; test with 10+ concurrent requests; monitor connection count.

## Implementation Patterns

### Next.js App Router (`lib/prisma.ts`)

```typescript
import { PrismaClient } from '@prisma/client';

const prismaClientSingleton = () => new PrismaClient();

declare const globalThis: {
  prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;

const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();

export default prisma;

if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma;
```

**Environment:** `DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=1&pool_timeout=20"`

**Usage in Server Action:**

```typescript
import prisma from '@/lib/prisma';

export async function createUser(formData: FormData) {
  'use server';
  return await prisma.user.create({
    data: {
      email: formData.get('email') as string,
      name: formData.get('name') as string,
    },
  });
}
```

### Next.js Pages Router / AWS Lambda (`lib/prisma.ts`)

```typescript
import { PrismaClient } from '@prisma/client';

declare global {
  var prisma: PrismaClient | undefined;
}

const prisma = global.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') global.prisma = prisma;

export default prisma;
```

**Lambda Handler:**

```typescript
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();

export const handler = async (event: any) => {
  const users = await prisma.user.findMany();
  return { statusCode: 200, body: JSON.stringify(users) };
  // Never call prisma.$disconnect() – reuse Lambda container connections
};
```

### With PgBouncer (High Concurrency)

Use when >50

concurrent requests or connection limits still cause issues.

```bash
DATABASE_URL="postgresql://user:pass@pgbouncer-host:6543/db?connection_limit=10&pool_timeout=20"
DIRECT_URL="postgresql://user:pass@direct-host:5432/db"
```

```prisma
datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}
```

DATABASE_URL → PgBouncer (queries); DIRECT_URL → database (migrations).

## Requirements

**MUST:** Set `connection_limit=1` in DATABASE_URL; use global singleton (never `new PrismaClient()` in functions); create single `lib/prisma.ts` imported throughout; add `pool_timeout`.

**SHOULD:** Use PgBouncer for high concurrency (>50); monitor production connection count; set limit via URL parameter; reuse Lambda connections.

**NEVER:** Create `new PrismaClient()` in routes/handlers; use default pool size in serverless; call `$disconnect()` in handlers; deploy without limits; split instances across files.

## Common Mistakes

| Issue                          | Wrong                                                     | Right                                      |
| ------------------------------ | --------------------------------------------------------- | ------------------------------------------ |
| Connection in Constructor      | `new PrismaClient({ datasources: { db: { url: ... } } })` | Set `connection_limit=1` in DATABASE_URL   |
| Multiple Instances             | `const prisma = new PrismaClient()` inside functions      | Import singleton from `lib/prisma`         |
| Handler Disconnect             | `await prisma.$disconnect()` after query                  | Remove disconnect – reuse containers       |
| Missing TypeScript Declaration | `const prisma = global.prisma \|\| ...`                   | `declare global { var prisma: ... }` first |

## Validation Checklist

1. **Environment:** DATABASE_URL contains `connection_limit=1` and `pool_timeout`; verified in Vercel dashboard.
2. **Code:** `new PrismaClient()` appears exactly once in `lib/prisma.ts`; all other files import from it.
3. **Testing:** 10+ concurrent requests to staging; connection count stays ≤10-15; no P1017 errors.
4. **Monitoring:** Production alerts for connection exhaustion and timeout errors.

## Platform-Specific Notes

**Vercel:** Set environment variables in dashboard (

auto-encrypted); connection pooling shared across invocations; consider Vercel Postgres for built-in pooling.

**AWS Lambda:** Container reuse varies by traffic; cold starts create new instances; use provisioned concurrency for consistency; Lambda layers optimize Prisma binary size.

**Cloudflare Workers:** Standard PrismaClient unsupported (V8 isolates, not Node.js); use Data Proxy or D1.

**Railway/Render:** Apply `connection_limit=1` pattern; check platform docs for built-in pooling.

## Related Skills

**Next.js Integration:**

- If implementing authenticated data access layers in Next.js, use the securing-data-access-layer skill from nextjs-16 for verifySession() DAL patterns
- If securing server actions with database operations, use the securing-server-actions skill from nextjs-16 for authentication patterns

## References

- Next.js patterns: `references/nextjs-patterns.md`
- Lambda optimization: `references/lambda-patterns.md`
- PgBouncer setup: `references/pgbouncer-guide.md`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.