Continuous Benchmark for ORM libraries written in golang.
This repository provides performance benchmarks for popular Go ORM libraries using SQLite as the test database. The benchmarks are designed to compare the performance of different ORM libraries across common database operations.
- ZORM - A simple, ultra-fast ORM library
- BORM - A better ORM library that is simple, fast and self-mockable for Go
- GORM - The most popular ORM library for Go
- SQLX - A library which provides a set of extensions on go's standard
database/sqllibrary - XORM - A simple and powerful ORM for Go
- ENT - An entity framework for Go
- BUN - SQL-first Golang ORM
The following operations are benchmarked:
| Test Case | Description |
|---|---|
InsertSingle |
Single record insertion performance |
InsertBatch |
Batch insertion performance (100 records per batch) |
GetByID |
Single record retrieval by primary key |
GetByIDs |
Multiple records retrieval by primary keys |
Update |
Record update performance |
Delete |
Record deletion performance |
Count |
Count query performance |
GetAll |
Paginated query performance (limit/offset) |
- Go 1.21 or higher
- SQLite3
go test -bench=. -benchmem# ZORM only
go test -bench=ZORM -benchmem
# BORM only
go test -bench=BORM -benchmem
# GORM only
go test -bench=GORM -benchmem
# XORM only
go test -bench=XORM -benchmem
# SQLX only
go test -bench=SQLX -benchmem
# BUN only
go test -bench=BUN -benchmem
# ENT only
go test -bench=ENT -benchmem# Insert single test for all ORMs
go test -bench=InsertSingle -benchmem
# GetByID test for all ORMs
go test -bench=GetByID -benchmem| Test Case | ZORM | BORM | BUN | ENT | GORM | SQLX | XORM |
|---|---|---|---|---|---|---|---|
| InsertSingle | π’ 1x | π’ 1x | π 3.13x | π 3.46x | π΄ 7.09x | π΄ 60.61x | π΄ 61.12x |
| InsertBatch | π’ 1x | π’ 1x | π‘ 1.30x | π 2.50x | π‘ 1.89x | π 3.57x | π 3.33x |
| GetByID | π’ 1x | π’ 1x | π‘ 1.52x | π‘ 1.85x | π‘ 1.90x | π 2x | π 3.12x |
| GetByIDs | π’ 1x | π’ 1x | π‘ 1.17x | π‘ 1.38x | π‘ 1.39x | π‘ 1.36x | π‘ 1.98x |
| Update | π’ 1x | π’ 1x | π 2.67x | π΄ 9.86x | π΄ 7.06x | π΄ 82.52x | π΄ 84x |
| Delete | π’ 1x | π’ 1x | π 2.31x | π 2.62x | π΄ 6.40x | π΄ 105.84x | π΄ 101.85x |
| Count | π’ 1x | π’ 1x | π 2.15x | π΄ 13.40x | π 2.99x | π 4.34x | π΄ 5.95x |
| GetAll | π’ 1x | π’ 1x | π‘ 1.14x | π‘ 1.21x | π‘ 1.43x | π‘ 1.18x | π‘ 1.91x |
Ratio indicates performance multiplier relative to the fastest ORM (lower is better)
β indicates the ORM is both fast and memory-efficient for this test case (Pareto-optimal in ns/op and B/op, lower is better). Stars are placed in the ns/op and B/op columns.
- Go Version: 1.21+
- Database: SQLite (in-memory, DSN uses
cache=shared&mode=memory) - CPU: M4 Pro
- OS: darwin (amd64)
The benchmark results show:
- ns/op: Nanoseconds per operation
- B/op: Bytes allocated per operation
- allocs/op: Number of allocations per operation
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| ZORM | 2,913 β | π’ 1x | 464 β | 16 |
| BORM | 2,916 | π’ 1x | 464 | 16 |
| BUN | 9,123 | π 3.13x | 5,405 | 27 |
| ENT | 10,065 | π 3.46x | 2,642 | 74 |
| GORM | 20,652 | π΄ 7.09x | 6,116 | 96 |
| SQLX | 176,553 | π΄ 60.61x | 632 | 18 |
| XORM | 178,033 | π΄ 61.12x | 2,690 | 54 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| BORM | 104,405 | π’ 1x | 59,503 | 912 |
| ZORM | 104,862 | π’ 1x | 59,502 β | 912 |
| BUN | 136,110 | π‘ 1.30x | 24,455 | 723 |
| GORM | 197,739 | π‘ 1.89x | 74,929 | 1,494 |
| ENT | 261,124 | π 2.50x | 213,805 | 3,360 |
| XORM | 347,846 | π 3.33x | 98,830 | 2,449 |
| SQLX | 373,004 | π 3.57x | 47,349 | 1,622 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| ZORM | 4,729 β | π’ 1x | 939 β | 33 |
| BORM | 4,776 | π’ 1x | 939 | 33 |
| BUN | 7,191 | π‘ 1.52x | 5,700 | 36 |
| ENT | 8,766 | π‘ 1.85x | 3,812 | 103 |
| GORM | 8,975 | π‘ 1.90x | 4,076 | 73 |
| SQLX | 9,471 | π 2x | 1,155 | 37 |
| XORM | 14,750 | π 3.12x | 4,809 | 139 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| BORM | 18,082 β | π’ 1x | 3,511 β | 95 |
| ZORM | 18,257 | π’ 1x | 3,511 | 95 |
| BUN | 21,171 | π’ 1.17x | 7,467 | 107 |
| SQLX | 24,623 | π‘ 1.36x | 4,051 | 116 |
| ENT | 24,997 | π‘ 1.38x | 9,679 | 230 |
| GORM | 25,137 | π‘ 1.39x | 7,369 | 186 |
| XORM | 35,883 | π‘ 1.98x | 12,918 | 400 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| ZORM | 2,103 β | π’ 1x | 454 β | 13 |
| BORM | 2,107 | π’ 1x | 454 | 13 |
| BUN | 5,607 | π 2.67x | 5,044 | 15 |
| GORM | 14,845 | π΄ 7.06x | 7,442 | 99 |
| ENT | 20,745 | π΄ 9.86x | 5,608 | 156 |
| SQLX | 173,533 | π΄ 82.52x | 654 | 16 |
| XORM | 176,658 | π΄ 84x | 4,082 | 103 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| BORM | 1,646 | π’ 1x | 160 | 7 |
| ZORM | 1,667 | π’ 1x | 159 β | 7 |
| BUN | 3,798 | π 2.31x | 4,880 | 14 |
| ENT | 4,318 | π 2.62x | 1,832 | 44 |
| GORM | 10,536 | π΄ 6.40x | 5,571 | 75 |
| XORM | 167,642 | π΄ 101.85x | 3,043 | 80 |
| SQLX | 174,217 | π΄ 105.84x | 255 | 10 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| ZORM | 1,546 β | π’ 1x | 440 β | 14 |
| BORM | 1,555 | π’ 1x | 440 | 14 |
| BUN | 3,327 | π 2.15x | 1,288 | 23 |
| GORM | 4,617 | π 2.99x | 2,720 | 33 |
| SQLX | 6,716 | π 4.34x | 504 | 16 |
| XORM | 9,193 | π΄ 5.95x | 2,394 | 61 |
| ENT | 20,720 | π΄ 13.40x | 2,384 | 54 |
| ORM | ns/op | Ratio | B/op | allocs/op |
|---|---|---|---|---|
| ZORM | 95,365 β | π’ 1x | 14,829 β | 607 |
| BORM | 95,795 | π’ 1x | 14,829 | 607 |
| BUN | 109,081 | π’ 1.14x | 21,955 | 709 |
| SQLX | 112,556 | π’ 1.18x | 17,526 | 712 |
| ENT | 115,475 | π‘ 1.21x | 43,301 | 1,256 |
| GORM | 136,701 | π‘ 1.43x | 25,311 | 1,128 |
| XORM | 182,305 | π‘ 1.91x | 74,869 | 2,771 |
All benchmarks use SQLite as the test database:
- In-memory database for fast performance
- Temporary files are automatically cleaned up after tests
- Each ORM uses its own isolated database instance
goorm/
βββ gorm/ # GORM implementation
βββ xorm/ # XORM implementation
βββ zorm/ # ZORM implementation
βββ sqlx/ # SQLX implementation
βββ borm/ # BORM implementation
βββ bun/ # BUN implementation
βββ ent/ # ENT implementation
β βββ schema/ # ENT schema definitions
βββ internal/
β βββ models/ # Test models (User, Post)
β βββ orm/ # Unified ORM interface
βββ goorm_test.go # Benchmark tests
βββ go.mod # Go module file
βββ README.md # This file
To add a new ORM library:
- Create a new directory (e.g.,
ent/) - Implement the
ORMInterfacein a new file - Add the ORM to the
ormsmap ingoorm_test.go - Add benchmark functions following the naming pattern
Note for ENT: ENT requires code generation. After adding the schema files, run:
go generate ./entThis will generate the ENT client code needed for the implementation.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details.