question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Question regarding performance of writes to db using prisma client.

See original GitHub issue

Hi, I have a question regarding performance of writes to db using prisma client.

So I created very simple app in nodejs to test performance of writing less than 10 elements to db - postgres, and I noticed that it takes around 70ms to write 11 rows into database. I added some logging to see what is taking so long and it seems that queries are very fast so what is impacting the overall time it takes to finish the transaction?

Here is the sample code:

Schema

datasource db {
  url      = ""
  provider = "postgresql"
}

generator client {
  provider = "prisma-client-js"
}

model Task {
  id        String    @id @default(uuid())
  createdAt DateTime  @default(now())
  name      String?   @default("")
  startDate DateTime?
  endDate   DateTime?
  Account   Account?   @relation(fields: [accountId], references: [id])
  accountId String?
}

model Account {
  id        String   @id @default(uuid())
  createdAt DateTime @default(now())
  name      String?  @default("")
  email     String
  Task      Task[]
}

And simple ts snippet:

import { Prisma, PrismaClient } from "@prisma/client";
import { v4 as uuid } from "uuid";
import perfy from "perfy";

const prisma = new PrismaClient({
  errorFormat: "minimal",
  log: [
    {
      emit: 'event',
      level: 'query',
    }
  ]
});

prisma.$on('query', (e) => {
  console.log('Query: ' + e.query)
  console.log('Duration: ' + e.duration + 'ms')
})

const account: Prisma.AccountCreateInput = {
  email: "test@test.com",
  createdAt: new Date(),
  name: "test",
  id: uuid(),
};

const createManyTasks = (count: number): Prisma.TaskCreateInput[] => {
  const tasks: Prisma.TaskCreateInput[] = [];
  for (let i = 0; i < count; i++) {
    tasks.push({
      createdAt: new Date(),
      name: "task" + i,
      startDate: new Date(),
      endDate: new Date(),
      id: uuid(),
    });
  }
  return tasks;
}

const tasks = createManyTasks(10);

perfy.start("transaction");
prisma.account.create({
  data: {
    id: account.id,
    email: account.email,
    name: account.name,
    createdAt: account.createdAt,
    Task: {
      createMany: {
        data: tasks
      }
    }
  },
})
.then(() => {
  let res = perfy.end("transaction");
  console.log(`ended in ${res.fullMilliseconds} ms`)
})

It prints something like:

Query: BEGIN
Duration: 1ms
Query: INSERT INTO "public"."Account" ("id","createdAt","name","email") VALUES ($1,$2,$3,$4) RETURNING "public"."Account"."id"
Duration: 2ms
Query: INSERT INTO "public"."Task" ("endDate","id","name","accountId","startDate","createdAt") VALUES ($1,$2,$3,$4,$5,$6), ($7,$8,$9,$10,$11,$12), ($13,$14,$15,$16,$17,$18), ($19,$20,$21,$22,$23,$24), ($25,$26,$27,$28,$29,$30), ($31,$32,$33,$34,$35,$36), ($37,$38,$39,$40,$41,$42), ($43,$44,$45,$46,$47,$48), ($49,$50,$51,$52,$53,$54), ($55,$56,$57,$58,$59,$60)
Duration: 2ms
Query: SELECT "public"."Account"."id", "public"."Account"."createdAt", "public"."Account"."name", "public"."Account"."email" FROM "public"."Account" WHERE "public"."Account"."id" = $1 LIMIT $2 OFFSET $3
Duration: 1ms
Query: COMMIT
Duration: 1ms
ended in 75.115 ms

I’m not a nodejs expert but might it be because of nodejs and it being single-threaded? Any help here would be appreciated.

_Originally posted by @mdrgeniebelt in https://github.com/prisma/prisma/discussions/8729_

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
janpiocommented, Aug 13, 2021

If you have some time on your hands, you could try this preview feature that we have behind a feature flag right now. It might have a bit of impact on that overhead you are seeing there right now: https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine#enable-the-node-api-n-api-preview If you do try it, please report back how it influences your numbers.

0reactions
ricofeghcommented, Aug 14, 2021

The same test on node-postgres:

const { Pool, Client } = require('pg')


async function run() {
	const pool = new Pool()

	console.time("Node-postgres execution");

    for (let i = 0; i < 5000; i++) {
  		await pool.query('SELECT * FROM "User" LIMIT 1');
  	}	   

    console.timeEnd("Node-postgres execution");		    

    await pool.end()
}

run();

gives:

Node-postgres execution: 2.341s

But unlike Prisma case, the execution time dramatically decrease if run in parallel:

const { Pool, Client } = require('pg')


async function run() {
	const pool = new Pool()

	console.time("Node-postgres execution");

	const promises = [];

    for (let i = 0; i < 5000; i++) {
  		promises.push(pool.query('SELECT * FROM "User" LIMIT 1'));
  	}	 

  	await Promise.all(promises);  

    console.timeEnd("Node-postgres execution");		    

    await pool.end()
}

run();

Result:

Node-postgres execution: 470.144ms
Read more comments on GitHub >

github_iconTop Results From Across the Web

Query optimization - Prisma
This guide describes ways to optimize query performance, debug performance issues, and how to tackle common performance issues such as the ...
Read more >
Performance and optimization - Prisma
Guides on performance, query optimization, and transactions when using Prisma.
Read more >
Improving Query Performance with Indexes using Prisma
One strategy for improving the performance of your database queries is using indexes. This article covers the fundamentals of database ...
Read more >
Transactions - Prisma
To implement atomic writes in a low-level database clients, you must wrap your inserts ... Why can't I use the $transaction API to...
Read more >
Why Prisma? Comparison with SQL query builders & ORMs
On this page, you'll learn about the motivation for Prisma and how it compares to other database tools like ORMs and SQL query...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found