Prisma@7 はなぜ遅くなってしまったのか
※ アクセス数が増えた関係でCloudflareの無料プランが限界を迎えたので、課金設定を入れました
Prisma@7 の現状🔗
2025/11/17 に Prisma の公式 Blog で 7.0.0 が発表されました。
https://www.prisma.io/blog/announcing-prisma-orm-7-0-0
- Moving away from Rust
- 90% smaller bundle output
- 3x faster query execution
- Significantly lower CPU and memory utilization
- Simpler deployments for Vercel Edge and Cloudflare Workers
Rust から脱却し、バンドルサイズが 90%縮小、クエリの実行が 3 倍速、CPU 私用率やメモリ消費の低減、Edge 環境や Cloudflare への導入が簡単になったという内容です。
現実はこの issue に集約されています。
https://github.com/prisma/prisma/issues/28845
ベンチマークの結果、三倍速どころか逆に遅くなっている状況です。さらに Prisma@7 以降で発生した大量のバグによって、issues が埋め尽くされています。
また、基本的な使い方を示す Examples のリポジトリが、完全に体をなしていません。全然テストが通らないのです。
https://github.com/prisma/prisma-examples/actions
Prisma の動作種別🔗
現状使われている Prisma の動作の流れは図に示すとおりです。Prisma@7 の基本構成が 4 です。では順番に解説します。
1 PrismaEngine - RustNative
PrismaClient に渡したパラメータを PrismaEngine 処理して DB とやり取りします。PrismaEngine は Rust でコンパイルされたネイティブバイナリで動作し、DB とのやり取りも Rust 製のドライバーで完結するため、各 DB ごとの Adapter を必要としません。
ここでボトルネックになるのは、PrismaClient のパラメータを JSON に変換し、PrismaEngine に渡す部分と、DB から戻ってきたデータをやっぱり JSON に変換してやり取りする部分です。データ量が多い場合はパフォーマンスが低下します。
ちなみに PrismaClient と PrismaEngine の間の経路は、ネットワーク経由で行うことも可能であり、それを利用したのがPrisma Accelerateというサービスになります。
2 PrismaEngine - RustWasm
Edge 環境や Cloudflare に対応するため、PrismaEngine を WebAssembly 化しました。この時点でバイナリサイズが 90%近く縮小しています。ここで追加仕様が発生しました。Rust 製の DB ドライバの移植までは不可能だったので、JavaScript 製の Adapter を挟むようになり、ひと手間増えました。欠点は Native 版と変わりません。
3 QueryCompiler - RustWasm
DB から返ってきたデータの取得を高速化するため、動作の方法を根本から見直したのがこの形式です。DB からデータを受け取る機能を PrismaClient 側に持たせました。QueryCompiler はその名の通り、PrismaClient から送られて来たパラメータを SQL に変換する部分を担当しています。変換された SQL は PrismaClient に戻されるので、そこから Adapter を経由して DB とやり取りします。DB データの戻り値の変換ロスが発生しないため、大きなデータのやり取りの速度が向上します。クエリの実行が 3 倍速といっているのはこの部分です。しかし今度はパラメータを SQL に変換する作業がボトルネックになり、細かいクエリでは速度が落ちます。今後のバージョンではこの部分をキャッシュすることによって問題を解決する予定のようです。ただ、プログラムが都度起動するような環境では、キャッシュによる速度向上は見込み薄なので、用途によっては速度問題が解決しない可能性があります。
4 QueryCompiler - RustWasm -TypeScript
PrismaClient の部分を TypeScript 化したものです。ただし QueryCompiler とのやりとりは 3 と変わらないので、速度的な優位性は発生しません。3 はprisma generateで node_modules に実コードを.js、型情報をd.ts、パッケージ情報を package.json として出力します。4 ではこれを TypeScript で出力し、ユーザーコードとして、ユーザー側のビルド対象に含めています。3 は PrismaClient が外部パッケージ扱い、4 はユーザーコード扱いになるという差が生じます。これになんの利点があるのかというと、良くわかりません。
ちなみに 3 の外部パッケージ扱いにした場合、package.json 内の exports に、Node.js、Deno、Edge、Workerd など、環境によって実行するコードの情報が入った状態になります。4 ではそれが不可能なので、schema.prismaの中で実行環境を指定する必要があります。3 は環境の自動切り替えが行われ、4 では手動設定が必要となり、利便性で退化してます。
この部分を Prisma は Rust を TypesScript 化したという話につなげているようです。しかし JavaScript で node_modules に出力していた部分を TypeScript にしただけなので、そういった関連性はありません。Rust でコンパイルされたコードは.wasmもしくは.js中の BASE64 として残っています。
まとめ🔗
Prisma@7 に関しては速度云々の話をする以前の問題として、バグが山のように積み上がっています。まずは取り急ぎ Example のエラーを解決することに集中して欲しいです。もしその状況で正式リリースすれば、ここまで混沌とした状況にはなっていなかったでしょう。今はスタートラインにすら立っていません。
こうなってくるとPrismaに対する信頼が無きに等しい状態なので、この記事を書いている Blog システムは Prisma から Drizzle に置き換えました。その過程で作ったものがこれです。
https://www.npmjs.com/package/pothos-drizzle-generator
Drizzle のスキーマ情報から自動で GraphQL のオペレーションを自動生成します。これに関しては、また別の記事を書く予定です。