What Prisma 8 actually changes
First, the facts, because they are the reason you are reading this. Prisma 8 (in release candidate as of late September 2026) adds the features people have asked for over several major versions:
- Postgres full-text search, native to the query API rather than raw SQL.
- Multi-file schemas, so a large
schema.prismacan be split by domain instead of becoming a 2,000-line monolith. - Prepared ORM reads and aggregates, which trim per-query overhead.
- Conflict-skipping bulk creation (skip-duplicates), and Prisma 7 schema compatibility as a migration source.
- A new schema contract: files require
// use prisma-8on the first line, and unmapped models now use their names verbatim as table names.
These are genuinely good. Full-text search alone removes a common reason teams reach for a raw query or bolt on a separate search service too early. If you are on Prisma 7, the upgrade is worth planning. But notice what is on that list and what is not.
The finding: the ORM is rarely the slow part
We look at a lot of databases that someone else built, through our software rescue work and our research audits. Two of those studies are directly relevant here: our review of 25 AI-generated Supabase databases and our teardown of 23 funded Series A codebases. When a “the database is slow” ticket comes in, the cause almost never turns out to be the ORM's per-call overhead. It is one of these, in roughly this order:
- Missing or wrong indexes. The single most common finding. A query filters or joins on a column with no supporting index, so Postgres does a sequential scan that gets linearly worse as the table grows. In the Supabase audit, missing indexes were near-universal on tables that had grown past a few thousand rows.
- N+1 query patterns. Code loops over a list and lazily loads a relation once per row. A page that should run 2 queries runs 200. The ORM allowed it; the developer wrote it.
- Over-fetching. Selecting every column (and every relation) when the screen needs four fields. Cheap on a dev seed, brutal on a real row count with wide JSON columns.
- No pagination. An endpoint that returns the entire table because it was fine with 50 rows in testing and is now returning 50,000.
- No connection pooling (or a serverless function opening a fresh connection per invocation) — which shows up as timeouts under load, not slow single queries.
Every one of those is invisible in a benchmark that runs one query against an empty table, which is exactly what most “Prisma is 10× slower than Drizzle” posts measure. Swap the ORM and a missing index is still missing. Fix the index and the ORM difference vanishes into noise.
What Prisma 8 fixes, and what it can't
Mapping the new features against the real causes above:
- Full-text search genuinely helps if you were doing
LIKE '%term%'scans, that pattern cannot use a normal index and is a real slow-query source. This is a legitimate performance win. - Prepared reads/aggregates trim ORM overhead, which matters at very high query volume, but overhead is milliseconds. It will not rescue a sequential scan measured in seconds.
- Multi-file schemas are a developer-experience win, not a performance one.
- Nothing in Prisma 8 writes your indexes, removes your N+1s, or paginates your endpoints. Those stay your job, in any ORM.
How to actually find your bottleneck
Before you migrate anything, spend an hour on the boring diagnosis. It out-performs an ORM swap almost every time.
-- Slowest queries by total time, the ones worth fixing first
SELECT
substring(query, 1, 90) AS query,
calls,
round(mean_exec_time::numeric, 2) AS avg_ms,
round(total_exec_time::numeric, 2) AS total_ms
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = $1 AND status = 'open';
-- "Seq Scan on orders ... rows=... " with a high cost is your answer.
-- The fix is an index, not a different ORM:
CREATE INDEX CONCURRENTLY orders_customer_status_idx
ON orders (customer_id, status);For N+1, the tell is a burst of near-identical queries per request in your logs or APM. In Prisma the fix is to load the relation in one go rather than per row:
// N+1: one query for the list, then one per row for its author
const posts = await prisma.post.findMany({ where: { published: true } });
for (const p of posts) {
p.author = await prisma.user.findUnique({ where: { id: p.authorId } }); // 🔴
}
// One query. The ORM was never the problem, the access pattern was.
const posts = await prisma.post.findMany({
where: { published: true },
select: { id: true, title: true, author: { select: { id: true, name: true } } },
});Note the select: ask for the columns the screen uses, not the whole row. That one habit fixes over-fetching, the third-most-common cause on our list, for free.
So, Prisma or Drizzle?
The honest answer is that it matters far less than the discourse implies, and it matters on axes that have nothing to do with raw speed:
- Choose Drizzle when your runtime target is the edge (Cloudflare Workers, Vercel Edge) or cold-start latency is critical, its zero-dependency design shines there.
- Choose Prisma when you value migrations, tooling, a mature type-safe client, and now full-text search and multi-file schemas, and you are on a standard Node runtime.
- Either way, budget the time you would have spent agonising over the choice on an index and query audit instead. That is the change that moves p95.
We make this call on every build through our product engineering work, and we un-make bad versions of it through software rescue — where “the app got slow” is, nine times in ten, a schema and index problem wearing an ORM costume.
Three companion audits that quantify the patterns above:
Research
We Audited 25 AI-Generated Supabase Databases: RLS Holes, Missing Indexes, Billing Bombs
Only 5 of 25 had correct RLS, and missing indexes were near-universal. The exact patterns behind slow AI-built databases.
Research
Series A Code Audit: Inside 23 Funded SaaS Codebases
Patterns from 23 SaaS codebase audits, including the query and schema debt that shows up as 'the database is slow'.
Research
The Multi-Tenant SaaS Architecture Decision: Cost & Engineering Hours Across 4 Patterns
Where schema shape and isolation choices decide performance and cost long before the ORM does.
The engagements that build the data layer right, and fix it when it went wrong:
Service
Product Engineering
The build that ships a schema, indexes and query patterns designed for real row counts, in any ORM.
Service
Software Rescue & Security
Where we diagnose 'the database got slow' — usually indexes and N+1, not the ORM.
Service
SaaS Web App Development
The full build the data layer slots into, from schema to caching.
Frequently asked questions
- Is Prisma 8 faster than Prisma 7?
- Prisma 8 shaves real overhead with prepared ORM reads and aggregates, and adds Postgres full-text search and multi-file schemas. But ORM overhead is usually single-digit milliseconds; if a query is slow because it does a sequential scan on a million rows or fires N+1 sub-queries, upgrading Prisma will not fix it. Measure with EXPLAIN ANALYZE before assuming the ORM is the cost.
- Should I migrate to Prisma 8?
- If you are on Prisma 7 and want full-text search, multi-file schemas or the prepared-read performance, yes, and the schema is largely compatible (Prisma 8 files require `// use prisma-8` on the first line, and unmapped models use their names verbatim as table names). But do not migrate expecting it to fix a slow database. Audit your indexes and query patterns first; that is where the wins are.
- Prisma vs Drizzle in 2026, which is faster?
- For most applications the difference is noise next to your schema and indexes. Drizzle's zero-dependency design wins on edge runtimes (Cloudflare Workers, Vercel Edge) and cold starts; Prisma wins on developer experience, migrations and now full-text search and multi-file schemas. Pick on runtime target and team ergonomics, not on a benchmark that disappears the moment you add a missing index.
- Does an ORM cause N+1 queries?
- The ORM makes N+1 easy to write, it does not force it. An N+1 happens when you loop over records and lazily load a relation per row instead of fetching them together. Both Prisma and Drizzle let you avoid it (Prisma with `include`/`select` and relation loading, Drizzle with joins). In our audits N+1 was one of the top slow-query causes, and it was a code pattern, not the ORM's fault.
- What does `// use prisma-8` do?
- It is the first-line directive Prisma 8 schema files require to opt into the Prisma 8 schema contract. Prisma 8 also treats unmapped models' names verbatim as table names, so if you relied on prior implicit mapping, check your `@@map` annotations during the upgrade.














































