Decorative background gradient
Back to Blog
NestJS MicroservicesPrisma MonorepoNestJS PostgreSQL

NestJS & Prisma Monorepo Architecture for Scalable Microservices

Structure a NestJS microservices monorepo with a shared Prisma schema, clean module boundaries, and production-grade PostgreSQL connection pooling.

NestJS & Prisma Monorepo Architecture for Scalable Microservices

Microservices solve real scaling and team-ownership problems, but they also introduce a new failure mode: duplicated database logic, drifting schemas, and connection pool exhaustion. NestJS combined with Prisma gives you a structured way to avoid all three — if you set up the monorepo correctly from day one.

This guide covers the parts that actually matter in production: monorepo layout, module boundaries, transactional writes, and connection pooling.

Step 1: Structure the Monorepo

Use a single monorepo with a shared database package instead of copy-pasting a Prisma schema into every service.

text

packages/database owns the schema and generated Prisma client:

prisma
ts

Every service imports from @myorg/database and gets the exact same generated client — no version drift, no duplicated model definitions.

Step 2: Wrap Prisma in a NestJS Module

Don't instantiate PrismaClient directly inside services — wrap it in an injectable NestJS provider so it's testable and lifecycle-managed.

ts
ts

Marking it @Global() means you only import PrismaModule once in AppModule, and every feature module can inject PrismaService without re-importing it.

Step 3: Keep Domain Logic Inside Its Own Module

Each microservice should expose a narrow, intentional interface — not its entire Prisma client — to the rest of the system.

ts

$transaction guarantees that if orderItem.createMany fails, the order.create is rolled back too — you never end up with an order that has no line items.

Step 4: Communicate Between Services with NestJS Microservices Transport

Instead of services calling each other over raw HTTP, use NestJS's microservices transporters for typed, structured request-response and event patterns.

ts
ts
ts

This decouples orders-service from needing to know anything about how notifications work — it just emits an event and moves on.

Step 5: Get Connection Pooling Right

This is where most teams get burned in production. Every running instance of every service opens its own Prisma connection pool against Postgres. If you have 3 services × 5 instances × a default pool size of 9, that's 135 connections — easily exceeding Postgres' default max_connections of 100.

text

For serverless or high-instance-count deployments, put PgBouncer in front of Postgres in transaction pooling mode, and point Prisma at PgBouncer instead of Postgres directly. This lets you run far more application instances than your database's raw connection limit would otherwise allow.

Key Takeaways

A shared Prisma schema package eliminates model drift across services, wrapping PrismaClient in a NestJS provider makes it testable and lifecycle-safe, $transaction keeps multi-step writes atomic, and disciplined connection pool sizing (with PgBouncer if needed) is what actually keeps a multi-service NestJS architecture stable under real production load.

Frequently Asked Questions

Should each microservice have its own database or share one?

Prefer a database-per-service when services genuinely own independent data. When services are tightly coupled and query overlapping data, a shared PostgreSQL instance with a single Prisma schema (and schema namespacing) is simpler to operate and still lets you split deployment later once boundaries are proven.

How do I avoid Prisma client duplication across services in a monorepo?

Put your schema.prisma and generated client in a shared package (e.g. packages/database) that every service depends on via workspace references. Run prisma generate once at the package level so all services use the same generated client version.

What connection pool size should I use for Prisma in production?

Start with Prisma's default pool size formula (num_physical_cpus * 2 + 1) per service instance, then multiply by your number of running instances to check it against Postgres' max_connections. For serverless or many-instance deployments, put PgBouncer in front of Postgres instead of scaling max_connections directly.

How do NestJS microservices communicate with each other?

NestJS ships built-in microservice transporters (TCP, Redis, NATS, Kafka, gRPC) accessed through ClientProxy, which gives you request-response and event-based patterns without writing raw HTTP clients. For simple setups, Redis or TCP transport is enough; for high-throughput event pipelines, Kafka or NATS scales better.

Working on something similar? Take a look at my services and case studies, or book a free call to talk about your idea.

Related Articles

Silent Tool Failures in AI Agents — Why Your Agent Lies About Success
Ai Agent ReliabilityTool Call FailuresLlm Error Handling+1 more

Silent Tool Failures in AI Agents — Why Your Agent Lies About Success

Most AI agent bugs never throw an error — the tool call "succeeds" with empty, truncated, or stale data and the agent confidently reports the task as done. Here's how to catch failures that don't look like failures.

September 22, 2026Read more →
AI Coding Agents Compared in 2026 — Claude Code vs Cursor vs GitHub Copilot
Claude Code Vs CursorAI Coding AgentsGithub Copilot

AI Coding Agents Compared in 2026 — Claude Code vs Cursor vs GitHub Copilot

Compare Claude Code, Cursor, and GitHub Copilot for real development work — agentic workflows, codebase understanding, pricing, and which fits your team.

September 18, 2026Read more →
Best Authentication Libraries for Next.js in 2026 — Clerk vs Auth.js vs Better Auth
Nextjs AuthenticationClerk Vs NextauthBetter Auth

Best Authentication Libraries for Next.js in 2026 — Clerk vs Auth.js vs Better Auth

Compare Clerk, Auth.js (NextAuth), and Better Auth for Next.js — setup effort, hosted UI, pricing, and which fits your app.

September 18, 2026Read more →
Best Error Monitoring & Analytics Tools for Next.js in 2026 — Sentry vs PostHog vs Vercel Analytics
Nextjs Error MonitoringSentry Vs PosthogWeb Analytics

Best Error Monitoring & Analytics Tools for Next.js in 2026 — Sentry vs PostHog vs Vercel Analytics

Compare Sentry, PostHog, and Vercel Analytics for a Next.js app — error tracking, product analytics, session replay, and pricing.

September 18, 2026Read more →
How to Add AI Features to an Existing Web App (Without a Rebuild)
Add AI To Existing AppAI SaaS FeaturesOpenAI API Integration

How to Add AI Features to an Existing Web App (Without a Rebuild)

A practical guide to adding real AI features, like matching, extraction, and automation, to a web app or SaaS product you already have, without rebuilding it from scratch.

September 16, 2026Read more →
AI Agent Observability and Tracing in Production
Ai Agent ObservabilityLlm TracingAgent Monitoring+2 more

AI Agent Observability and Tracing in Production

Why logging inputs and outputs isn't enough for AI agents in production — and how trace-level observability catches failures evals and logs miss.

September 14, 2026Read more →

Trending Topics