Skip to content

prisma/orm-benchmarks

Repository files navigation

ORM Benchmarks

This repo contains the app that was used to collect the data for ORM benchmarks.

You can learn more about the benchmark methodology and results in this blog post: Performance Benchmarks: Comparing Query Latency across TypeScript ORMs & Databases.

Setup

1. Set up the repo

Clone the repo, navigate into it and install dependencies:

git clone git@github.com:prisma/orm-benchmarks.git
cd orm-benchmarks
npm install

2. Configure database connection

Set the DATABASE_URL environment variable to your database connection string in a .env file.

First, create a .env file:

touch .env

Then open the .env file and add the following line:

DATABASE_URL="your-database-url"

For example:

DATABASE_URL="postgresql://user:password@host:port/db"
Alternative: Set the DATABASE_URL in the terminal

Alternatively, you can set the DATABASE_URL in the terminal:

export DATABASE_URL="postgresql://user:password@host:port/db"

3. Run database migration

To create the database and the schema, run the prisma db push command by pointing it to the schema of your database.

PostgreSQL

If you use PostgreSQL, run:

npx prisma db push --schema ./prisma-pg/schema.prisma

PostgreSQL native dependencies (pg-native)

This project uses pg-native for high-performance native bindings to PostgreSQL via libpq. This requires additional setup:

Requirements:

  • Your local PostgreSQL version must match your target PostgreSQL server version (for pg_dump/pg_restore compatibility)
  • PostgreSQL client libraries and tools must be installed locally

macOS setup:

# Install libpq (required for pg-native)
brew install libpq

# Install full PostgreSQL (includes pg_dump/pg_restore)
brew install postgresql

# Verify pg_config is in your PATH
pg_config --version

Alternative: Simpler Setup (No native dependencies)

If you prefer to avoid native dependencies or encounter build issues, you can use the Prisma-based seeder instead:

  1. Remove pg-native dependency:

    npm uninstall pg-native
  2. Update package.json start script - remove NODE_PG_FORCE_NATIVE=true from the start command

  3. Switch to Prisma seeder in src/run-benchmarks-pg.ts:

    // Comment out the native seeder
    // import { preparePg } from "./lib/prepare-pg-native"; // seed via `pg_restore`
    
    // Uncomment the Prisma seeder
    import { preparePg } from "./lib/prepare-pg-prisma"; // seed via `createMany`

Note: The native approach (pg-native + pg_restore) is faster for large datasets, while the Prisma approach is simpler to set up but slower for seeding.

Note: We may add more databases in the future.

4. Run the benchmarks

Note for PostgreSQL: Since the data preparation/seeding relies on pg_dump and pg_restore, the PostgreSQL versions of the machine that's executing the script must match the version of the target PostgreSQL server.

sh ./benchmark.sh -i 500 -s 1000

This executes the benchmark scripts with 500 iterations and a sample size of 1000 records per table. See below for the different options you can provide to any benchmark runs.

The results of the benchmark run will be stored in a folder called results/DB-SIZE-ITERATIONS-TIMESTAMP, e.g. results/postgresql-1000-500-1721027353940. This folder will have one .csv file per ORM, e.g.:

results/postgresql-1000-500-1721027353940
├── drizzle.csv
├── prisma.csv
└── typeorm.csv

5. Generate website output (optional)

To generate JSON output for website visualization from your benchmark results, run:

npm run website:output results/postgresql-1000-500-1721027353940

Replace results/postgresql-1000-500-1721027353940 with your actual results directory path. This will output a JSON structure that can be used for result visualization.

Usage

Executing the benchmarks

You can execute the benchmarks by running the benchmark.sh:

sh ./benchmark.sh [options]

Options

You can provide the following options to the script:

Name Short Default Description Required
--iterations -i 2 Number of times to execute the benchmarks No
--size -s 50 Size of the data set (number of records per table) No
--database-url -d n/a Database connection string No

For example:

sh ./benchmark.sh -i 500 -s 1000 --database-url postgresql://user:password@host:port/db

Debugging

You can turn on two debug setting via the DEBUG environment variable:

  • benchmarks:compare-results: Compare the results at the end of each benchmark run. Note that this approach will consume more memory because the results of all executed queries are collected.

Notes

About

Benchmark application to compare query latency of TypeScript ORMs.

Resources

Code of conduct

Security policy

Stars

Watchers

Forks