litedbmodel 2.0.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +7 -0
  2. package/dist/DBConditions.d.ts.map +1 -1
  3. package/dist/DBConditions.js +16 -1
  4. package/dist/DBConditions.js.map +1 -1
  5. package/dist/DBHandler.d.ts.map +1 -1
  6. package/dist/DBHandler.js +6 -0
  7. package/dist/DBHandler.js.map +1 -1
  8. package/dist/DBModel.d.ts +84 -2
  9. package/dist/DBModel.d.ts.map +1 -1
  10. package/dist/DBModel.js +312 -29
  11. package/dist/DBModel.js.map +1 -1
  12. package/dist/decorators.d.ts +52 -0
  13. package/dist/decorators.d.ts.map +1 -1
  14. package/dist/decorators.js +127 -24
  15. package/dist/decorators.js.map +1 -1
  16. package/dist/drivers/mysql.d.ts.map +1 -1
  17. package/dist/drivers/mysql.js +12 -2
  18. package/dist/drivers/mysql.js.map +1 -1
  19. package/dist/drivers/postgres.d.ts.map +1 -1
  20. package/dist/drivers/postgres.js +13 -2
  21. package/dist/drivers/postgres.js.map +1 -1
  22. package/dist/drivers/sqlite.d.ts +2 -0
  23. package/dist/drivers/sqlite.d.ts.map +1 -1
  24. package/dist/drivers/sqlite.js +49 -4
  25. package/dist/drivers/sqlite.js.map +1 -1
  26. package/dist/index.cjs +10741 -0
  27. package/dist/index.d.cts +1 -0
  28. package/dist/scp/coltype.d.ts +108 -0
  29. package/dist/scp/coltype.d.ts.map +1 -1
  30. package/dist/scp/coltype.js +293 -6
  31. package/dist/scp/coltype.js.map +1 -1
  32. package/dist/scp/connection-routing.d.ts +312 -0
  33. package/dist/scp/connection-routing.d.ts.map +1 -0
  34. package/dist/scp/connection-routing.js +394 -0
  35. package/dist/scp/connection-routing.js.map +1 -0
  36. package/dist/scp/dbmodel-runtime.d.ts +101 -0
  37. package/dist/scp/dbmodel-runtime.d.ts.map +1 -0
  38. package/dist/scp/dbmodel-runtime.js +174 -0
  39. package/dist/scp/dbmodel-runtime.js.map +1 -0
  40. package/dist/scp/decorator-adapter.d.ts +196 -0
  41. package/dist/scp/decorator-adapter.d.ts.map +1 -0
  42. package/dist/scp/decorator-adapter.js +286 -0
  43. package/dist/scp/decorator-adapter.js.map +1 -0
  44. package/dist/scp/emit/emitter.d.ts +108 -0
  45. package/dist/scp/emit/emitter.d.ts.map +1 -0
  46. package/dist/scp/emit/emitter.js +782 -0
  47. package/dist/scp/emit/emitter.js.map +1 -0
  48. package/dist/scp/emit/endpoint.d.ts +248 -0
  49. package/dist/scp/emit/endpoint.d.ts.map +1 -0
  50. package/dist/scp/emit/endpoint.js +20 -0
  51. package/dist/scp/emit/endpoint.js.map +1 -0
  52. package/dist/scp/emit/index.d.ts +11 -0
  53. package/dist/scp/emit/index.d.ts.map +1 -0
  54. package/dist/scp/emit/index.js +13 -0
  55. package/dist/scp/emit/index.js.map +1 -0
  56. package/dist/scp/errors.d.ts +45 -1
  57. package/dist/scp/errors.d.ts.map +1 -1
  58. package/dist/scp/errors.js +47 -1
  59. package/dist/scp/errors.js.map +1 -1
  60. package/dist/scp/exec-context.d.ts +390 -0
  61. package/dist/scp/exec-context.d.ts.map +1 -0
  62. package/dist/scp/exec-context.js +540 -0
  63. package/dist/scp/exec-context.js.map +1 -0
  64. package/dist/scp/grouping.d.ts +32 -0
  65. package/dist/scp/grouping.d.ts.map +1 -0
  66. package/dist/scp/grouping.js +0 -0
  67. package/dist/scp/grouping.js.map +1 -0
  68. package/dist/scp/index.cjs +6432 -17579
  69. package/dist/scp/index.d.cts +1 -0
  70. package/dist/scp/index.d.mts +1 -0
  71. package/dist/scp/index.d.ts +51 -52
  72. package/dist/scp/index.d.ts.map +1 -1
  73. package/dist/scp/index.js +189 -152
  74. package/dist/scp/index.js.map +1 -1
  75. package/dist/scp/index.mjs +6067 -3659
  76. package/dist/scp/leaf-transport.d.ts +50 -0
  77. package/dist/scp/leaf-transport.d.ts.map +1 -0
  78. package/dist/scp/leaf-transport.js +92 -0
  79. package/dist/scp/leaf-transport.js.map +1 -0
  80. package/dist/scp/leaves.d.ts +174 -0
  81. package/dist/scp/leaves.d.ts.map +1 -0
  82. package/dist/scp/leaves.js +287 -0
  83. package/dist/scp/leaves.js.map +1 -0
  84. package/dist/scp/limit-config.d.ts +118 -0
  85. package/dist/scp/limit-config.d.ts.map +1 -0
  86. package/dist/scp/limit-config.js +126 -0
  87. package/dist/scp/limit-config.js.map +1 -0
  88. package/dist/scp/makesql/compile-relation.d.ts +49 -23
  89. package/dist/scp/makesql/compile-relation.d.ts.map +1 -1
  90. package/dist/scp/makesql/compile-relation.js +101 -76
  91. package/dist/scp/makesql/compile-relation.js.map +1 -1
  92. package/dist/scp/makesql/compile-select.d.ts +45 -10
  93. package/dist/scp/makesql/compile-select.d.ts.map +1 -1
  94. package/dist/scp/makesql/compile-select.js +50 -10
  95. package/dist/scp/makesql/compile-select.js.map +1 -1
  96. package/dist/scp/makesql/handler.d.ts +1 -1
  97. package/dist/scp/makesql/handler.d.ts.map +1 -1
  98. package/dist/scp/makesql/index.d.ts +7 -10
  99. package/dist/scp/makesql/index.d.ts.map +1 -1
  100. package/dist/scp/makesql/index.js +19 -30
  101. package/dist/scp/makesql/index.js.map +1 -1
  102. package/dist/scp/makesql/json-array.d.ts +65 -0
  103. package/dist/scp/makesql/json-array.d.ts.map +1 -1
  104. package/dist/scp/makesql/json-array.js +99 -10
  105. package/dist/scp/makesql/json-array.js.map +1 -1
  106. package/dist/scp/makesql/json-batch.d.ts.map +1 -1
  107. package/dist/scp/makesql/json-batch.js +21 -19
  108. package/dist/scp/makesql/json-batch.js.map +1 -1
  109. package/dist/scp/makesql/makesql.d.ts +1 -1
  110. package/dist/scp/makesql/makesql.d.ts.map +1 -1
  111. package/dist/scp/makesql/mysql-returning.d.ts +93 -0
  112. package/dist/scp/makesql/mysql-returning.d.ts.map +1 -0
  113. package/dist/scp/makesql/mysql-returning.js +215 -0
  114. package/dist/scp/makesql/mysql-returning.js.map +1 -0
  115. package/dist/scp/makesql/outtype.d.ts +75 -34
  116. package/dist/scp/makesql/outtype.d.ts.map +1 -1
  117. package/dist/scp/makesql/outtype.js +91 -118
  118. package/dist/scp/makesql/outtype.js.map +1 -1
  119. package/dist/scp/makesql/pool-executor.d.ts +135 -13
  120. package/dist/scp/makesql/pool-executor.d.ts.map +1 -1
  121. package/dist/scp/makesql/pool-executor.js +229 -21
  122. package/dist/scp/makesql/pool-executor.js.map +1 -1
  123. package/dist/scp/makesql/tx.d.ts +107 -22
  124. package/dist/scp/makesql/tx.d.ts.map +1 -1
  125. package/dist/scp/makesql/tx.js +451 -97
  126. package/dist/scp/makesql/tx.js.map +1 -1
  127. package/dist/scp/makesql/writeouttype.d.ts +7 -8
  128. package/dist/scp/makesql/writeouttype.d.ts.map +1 -1
  129. package/dist/scp/makesql/writeouttype.js +8 -7
  130. package/dist/scp/makesql/writeouttype.js.map +1 -1
  131. package/dist/scp/middleware.d.ts +287 -0
  132. package/dist/scp/middleware.d.ts.map +1 -0
  133. package/dist/scp/middleware.js +358 -0
  134. package/dist/scp/middleware.js.map +1 -0
  135. package/dist/scp/relation.d.ts +80 -9
  136. package/dist/scp/relation.d.ts.map +1 -1
  137. package/dist/scp/relation.js +198 -78
  138. package/dist/scp/relation.js.map +1 -1
  139. package/dist/scp/tx-options.d.ts +136 -0
  140. package/dist/scp/tx-options.d.ts.map +1 -0
  141. package/dist/scp/tx-options.js +184 -0
  142. package/dist/scp/tx-options.js.map +1 -0
  143. package/dist/scp/write-bundle.d.ts +131 -0
  144. package/dist/scp/write-bundle.d.ts.map +1 -0
  145. package/dist/scp/write-bundle.js +160 -0
  146. package/dist/scp/write-bundle.js.map +1 -0
  147. package/dist/types.d.ts +7 -0
  148. package/dist/types.d.ts.map +1 -1
  149. package/dist/types.js.map +1 -1
  150. package/docs/BENCHMARK.md +58 -56
  151. package/docs/benchmark-chart.svg +166 -166
  152. package/docs/design/phase-a-execution-context.md +139 -0
  153. package/package.json +16 -9
  154. package/dist/scp/authoring-sql.d.ts +0 -134
  155. package/dist/scp/authoring-sql.d.ts.map +0 -1
  156. package/dist/scp/authoring-sql.js +0 -191
  157. package/dist/scp/authoring-sql.js.map +0 -1
  158. package/dist/scp/authoring.d.ts +0 -155
  159. package/dist/scp/authoring.d.ts.map +0 -1
  160. package/dist/scp/authoring.js +0 -162
  161. package/dist/scp/authoring.js.map +0 -1
  162. package/dist/scp/catalog.d.ts +0 -94
  163. package/dist/scp/catalog.d.ts.map +0 -1
  164. package/dist/scp/catalog.js +0 -234
  165. package/dist/scp/catalog.js.map +0 -1
  166. package/dist/scp/codegen.d.ts +0 -189
  167. package/dist/scp/codegen.d.ts.map +0 -1
  168. package/dist/scp/codegen.js +0 -421
  169. package/dist/scp/codegen.js.map +0 -1
  170. package/dist/scp/find-filter-guard.d.ts +0 -68
  171. package/dist/scp/find-filter-guard.d.ts.map +0 -1
  172. package/dist/scp/find-filter-guard.js +0 -88
  173. package/dist/scp/find-filter-guard.js.map +0 -1
  174. package/dist/scp/guard.d.ts +0 -43
  175. package/dist/scp/guard.d.ts.map +0 -1
  176. package/dist/scp/guard.js +0 -134
  177. package/dist/scp/guard.js.map +0 -1
  178. package/dist/scp/makesql/authoring-compile.d.ts +0 -90
  179. package/dist/scp/makesql/authoring-compile.d.ts.map +0 -1
  180. package/dist/scp/makesql/authoring-compile.js +0 -494
  181. package/dist/scp/makesql/authoring-compile.js.map +0 -1
  182. package/dist/scp/makesql/ir.d.ts +0 -42
  183. package/dist/scp/makesql/ir.d.ts.map +0 -1
  184. package/dist/scp/makesql/ir.js +0 -66
  185. package/dist/scp/makesql/ir.js.map +0 -1
  186. package/dist/scp/makesql/static-bundle.d.ts +0 -187
  187. package/dist/scp/makesql/static-bundle.d.ts.map +0 -1
  188. package/dist/scp/makesql/static-bundle.js +0 -1113
  189. package/dist/scp/makesql/static-bundle.js.map +0 -1
  190. package/dist/scp/runtime.d.ts +0 -242
  191. package/dist/scp/runtime.d.ts.map +0 -1
  192. package/dist/scp/runtime.js +0 -400
  193. package/dist/scp/runtime.js.map +0 -1
package/docs/BENCHMARK.md CHANGED
@@ -11,7 +11,7 @@ Reference: [Kysely performance comparison article](https://izanami.dev/post/1e3f
11
11
 
12
12
  **Test Environment:**
13
13
  - PostgreSQL 16 (Docker, local - no network latency)
14
- - Node.js v24
14
+ - Node.js v24 — **native arm64 (Apple Silicon)**, not x86_64/Rosetta
15
15
  - **5 rounds × 50 iterations = 250 total per ORM**
16
16
  - Interleaved execution to reduce environmental variance
17
17
  - **All write operations use transactions for fair comparison**
@@ -27,25 +27,25 @@ Reference: [Kysely performance comparison article](https://izanami.dev/post/1e3f
27
27
  <!--@embedoc:benchmark_table-->
28
28
  | Operation | litedbmodel | Kysely | Drizzle | TypeORM | Prisma |
29
29
  | --- | --- | --- | --- | --- | --- |
30
- | Find all (limit 100) | 0.70ms | 0.65ms | **0.64ms** 🏆 | 0.72ms | 1.35ms |
31
- | Filter, paginate & sort | **0.58ms** 🏆 | 0.64ms | 0.59ms | 0.66ms | 1.10ms |
32
- | Nested find all (include posts) | **3.64ms** 🏆 | 4.60ms | 4.66ms | 8.34ms | 12.06ms |
33
- | Find first | 0.37ms | **0.32ms** 🏆 | 0.36ms | 0.40ms | 0.59ms |
34
- | Nested find first (include posts) | 0.65ms | 0.61ms | 0.71ms | **0.52ms** 🏆 | 1.06ms |
35
- | Find unique (by email) | **0.29ms** 🏆 | 0.31ms | 0.30ms | 0.32ms | 0.53ms |
36
- | Nested find unique (include posts) | **0.57ms** 🏆 | 0.58ms | 0.59ms | 1.05ms | 0.94ms |
37
- | Create | 0.69ms | **0.68ms** 🏆 | 0.76ms | 0.79ms | 1.01ms |
38
- | Nested create (with post) | **0.90ms** 🏆 | 0.96ms | 1.03ms | 1.22ms | 1.81ms |
39
- | Update | 0.63ms | **0.61ms** 🏆 | 0.66ms | 0.67ms | 1.12ms |
40
- | Nested update (update user + post) | 0.94ms | 1.00ms | **0.92ms** 🏆 | 1.02ms | 2.28ms |
41
- | Upsert | 0.71ms | 0.74ms | **0.66ms** 🏆 | 0.75ms | 2.07ms |
42
- | Nested upsert (user + post) | **1.00ms** 🏆 | **1.00ms** 🏆 | **1.00ms** 🏆 | 1.14ms | 2.27ms |
43
- | Delete | **0.97ms** 🏆 | 1.00ms | 0.98ms | 1.10ms | 1.72ms |
44
- | Create Many (10 records) | 0.77ms | **0.72ms** 🏆 | 0.89ms | 1.00ms | 1.20ms |
45
- | Upsert Many (10 records) | **0.88ms** 🏆 | 0.90ms | 1.03ms | 1.06ms | 11.89ms |
46
- | Update Many (10 different values) | **0.70ms** 🏆 | 2.83ms | 2.75ms | 3.02ms | 5.31ms |
47
- | Nested relations (100→1000→10000) | 25.82ms | 24.65ms | **24.25ms** 🏆 | 80.56ms | 84.10ms |
48
- | Nested relations (composite key, 5 tenants) | 22.41ms | N/A | **16.26ms** 🏆 | 39.25ms | 219.00ms |
30
+ | Find all (limit 100) | **0.48ms** 🏆 | 0.55ms | 0.58ms | 0.64ms | 0.97ms |
31
+ | Filter, paginate & sort | **0.52ms** 🏆 | 0.57ms | 0.60ms | 0.64ms | 0.80ms |
32
+ | Nested find all (include posts) | **2.16ms** 🏆 | 3.07ms | 4.37ms | 5.90ms | 7.37ms |
33
+ | Find first | 0.31ms | 0.32ms | **0.29ms** 🏆 | 0.33ms | 0.49ms |
34
+ | Nested find first (include posts) | 0.51ms | 0.51ms | 0.56ms | **0.47ms** 🏆 | 0.74ms |
35
+ | Find unique (by email) | **0.27ms** 🏆 | **0.27ms** 🏆 | 0.29ms | 0.32ms | 0.44ms |
36
+ | Nested find unique (include posts) | 0.54ms | **0.49ms** 🏆 | 0.54ms | 0.97ms | 0.72ms |
37
+ | Create | 0.70ms | **0.68ms** 🏆 | 0.71ms | 0.76ms | 0.93ms |
38
+ | Nested create (with post) | **0.82ms** 🏆 | 0.89ms | 0.91ms | 1.09ms | 1.43ms |
39
+ | Update | **0.61ms** 🏆 | 0.65ms | 0.66ms | 0.74ms | 1.04ms |
40
+ | Nested update (update user + post) | **0.89ms** 🏆 | 0.95ms | 0.93ms | 1.01ms | 2.07ms |
41
+ | Upsert | 0.65ms | **0.64ms** 🏆 | 0.70ms | 0.73ms | 1.53ms |
42
+ | Nested upsert (user + post) | **0.85ms** 🏆 | 1.09ms | 1.09ms | 1.10ms | 1.89ms |
43
+ | Delete | **0.83ms** 🏆 | 0.95ms | 0.97ms | 1.08ms | 1.20ms |
44
+ | Create Many (10 records) | **0.72ms** 🏆 | 0.75ms | 0.87ms | 0.93ms | 1.05ms |
45
+ | Upsert Many (10 records) | **0.76ms** 🏆 | 0.86ms | 1.08ms | 1.09ms | 9.94ms |
46
+ | Update Many (10 different values) | **0.67ms** 🏆 | 2.73ms | 2.58ms | 2.78ms | 4.39ms |
47
+ | Nested relations (100→1000→10000) | **12.18ms** 🏆 | 16.22ms | 19.34ms | 54.93ms | 60.07ms |
48
+ | Nested relations (composite key, 5 tenants) | 14.62ms | N/A | **14.24ms** 🏆 | 29.21ms | 195.74ms |
49
49
  <!--@embedoc:end-->
50
50
 
51
51
  *All write operations wrapped in transactions for fair comparison across all ORMs.*
@@ -53,26 +53,27 @@ Reference: [Kysely performance comparison article](https://izanami.dev/post/1e3f
53
53
  ### Analysis
54
54
 
55
55
  1. **litedbmodel** - **Fastest in read/write operations** 🏆
56
- - **#1 in Filter/paginate, Nested find all, Find unique, Nested find unique, Nested create, Nested upsert (tie), Delete, Upsert Many, Update Many**
57
- - Update Many with different values: **3.9x - 7.6x faster** than other ORMs
56
+ - **#1 in 13 of 19 ops: Find all, Filter/paginate, Nested find all, Find unique (tie), Nested create, Update, Nested update, Nested upsert, Delete, Create Many, Upsert Many, Update Many, Nested relations single key**
57
+ - Update Many with different values: **3.9x - 6.6x faster** than other ORMs
58
+ - **Nested relations single key: fastest at 12.18ms** (batch-loaded, beats Drizzle's LATERAL JOIN)
58
59
  - Excellent balance of read and write performance
59
60
 
60
61
  2. **Kysely** - **Strong simple query performance**
61
- - **#1 in Find first, Create, Update, Create Many**
62
+ - **#1 in Create, Upsert, Nested find unique**
62
63
  - Minimal abstraction overhead
63
64
  - **Limitation:** Cannot batch load composite FK
64
65
 
65
- 3. **Drizzle** - **Fastest in nested relations** 🏆
66
- - **#1 in Find all, Nested update, Upsert, Nested upsert (tie), Nested relations single key (24ms), Nested composite key (16ms)** using LATERAL JOIN
66
+ 3. **Drizzle** - **Fastest in composite-key nested relations** 🏆
67
+ - **#1 in Find first, Nested composite key (14.24ms)** using LATERAL JOIN
67
68
  - Query API with relations provides excellent performance
68
69
 
69
70
  4. **TypeORM** - Variable performance
70
71
  - **#1 in Nested find first** (JOIN-based approach)
71
- - Decent composite key support (39ms)
72
+ - Composite key support at 29.21ms
72
73
 
73
74
  5. **Prisma** - Convenience over speed
74
- - **Slowest in most operations** (1.5x - 14x slower)
75
- - Composite key nested: 219ms (**13x slower** than Drizzle)
75
+ - **Slowest in most operations** (1.4x - 14x slower)
76
+ - Composite key nested: 195.74ms (**13.7x slower** than Drizzle)
76
77
  - Trade-off: Rich DX features (Prisma Studio, migrations, etc.)
77
78
 
78
79
  ---
@@ -89,36 +90,36 @@ Reference: [Kysely performance comparison article](https://izanami.dev/post/1e3f
89
90
 
90
91
  | ORM | Median | Ratio | Queries | Notes |
91
92
  |-----|--------|-------|---------|-------|
92
- | **Drizzle** 🏆 | **24.25ms** | **1.00x** | 1 | **LATERAL JOIN** |
93
- | Kysely | 24.65ms | 1.02x | 3 | Separate queries |
94
- | litedbmodel | 25.82ms | 1.06x | 3 | Separate queries + sync cache |
95
- | TypeORM | 80.56ms | 3.32x | 2 | JOIN-based |
96
- | Prisma | 84.10ms | 3.47x | 3 | Parameter explosion |
93
+ | **litedbmodel** 🏆 | **12.18ms** | **1.00x** | 3 | Separate queries + sync cache |
94
+ | Kysely | 16.22ms | 1.33x | 3 | Separate queries |
95
+ | Drizzle | 19.34ms | 1.59x | 1 | LATERAL JOIN |
96
+ | TypeORM | 54.93ms | 4.51x | 2 | JOIN-based |
97
+ | Prisma | 60.07ms | 4.93x | 3 | Parameter explosion |
97
98
 
98
99
  ### Composite Key Relations (5 tenants × 100 users)
99
100
 
100
101
  | ORM | Median | Ratio | Queries | Notes |
101
102
  |-----|--------|-------|---------|-------|
102
- | **Drizzle** 🏆 | **16.26ms** | **1.00x** | 1 | **LATERAL JOIN with composite** |
103
- | litedbmodel | 22.41ms | 1.38x | 3 | unnest + JOIN |
104
- | TypeORM | 39.25ms | 2.41x | 2 | Multiple OR conditions |
105
- | Prisma | 219.00ms | 13.47x | 3 | Parameter explosion (2000+ params) |
103
+ | **Drizzle** 🏆 | **14.24ms** | **1.00x** | 1 | **LATERAL JOIN with composite** |
104
+ | litedbmodel | 14.62ms | 1.03x | 3 | unnest + JOIN |
105
+ | TypeORM | 29.21ms | 2.05x | 2 | Multiple OR conditions |
106
+ | Prisma | 195.74ms | 13.75x | 3 | Parameter explosion (2000+ params) |
106
107
  | Kysely | N/A | - | - | Cannot batch composite FK |
107
108
 
108
109
  ### Deep Nested Analysis
109
110
 
110
111
  **Single Key:**
111
- - Drizzle fastest with LATERAL JOIN (24ms)
112
- - Kysely close (25ms) with 3 separate queries
113
- - litedbmodel (26ms, 1.06x) with 3 separate queries
112
+ - **litedbmodel fastest (12.18ms, 1.00x)** with 3 batch-loaded separate queries — beats Drizzle's single-query LATERAL JOIN
113
+ - Kysely 1.33x (16.22ms) with 3 separate queries
114
+ - Drizzle 1.59x (19.34ms) with LATERAL JOIN
114
115
 
115
116
  **Composite Key (multi-tenant):**
116
- - **Drizzle fastest (16ms)** with LATERAL JOIN query API
117
- - litedbmodel 1.38x (22ms) with `unnest + JOIN` approach
118
- - Prisma 13x slower with 2000+ parameters
117
+ - **Drizzle fastest (14.24ms)** with LATERAL JOIN query API
118
+ - litedbmodel 1.03x (14.62ms) with `unnest + JOIN` approach
119
+ - Prisma 13.7x slower with 2000+ parameters
119
120
  - **Kysely cannot batch load composite FK** (would require manual tuple matching)
120
121
 
121
- > **Drizzle advantage:** LATERAL JOIN provides fastest nested relation loading for both single and composite keys when using the query API with relations.
122
+ > **litedbmodel single-key advantage:** batch-loaded separate queries with a synchronous cache now edge out Drizzle's single-query LATERAL JOIN on single-key nested relations, while Drizzle retains the lead on composite-key nesting.
122
123
 
123
124
  ---
124
125
 
@@ -398,9 +399,9 @@ WHERE ( "tenant_id"=$1 AND "user_id"=$2
398
399
 
399
400
  ---
400
401
 
401
- ## Why Drizzle is Fastest (Single Key)
402
+ ## Drizzle's Single-Query LATERAL JOIN (Composite Key)
402
403
 
403
- Drizzle's **standard relation API** uses PostgreSQL's `LATERAL JOIN` with `json_agg()` to fetch all nested data in a single DB round-trip:
404
+ Drizzle's **standard relation API** uses PostgreSQL's `LATERAL JOIN` with `json_agg()` to fetch all nested data in a single DB round-trip. This wins on **composite-key** nested relations (14.24ms), though litedbmodel's batch-loaded separate queries now edge it out on **single-key** nesting (12.18ms vs 19.34ms):
404
405
 
405
406
  > **Note:** This is Drizzle's idiomatic approach via `db.query.*.findMany({ with: {...} })`. Other ORMs can achieve similar results with manual SQL, but Drizzle provides this as a built-in pattern.
406
407
 
@@ -538,11 +539,11 @@ WHERE (tenant_id, user_id) IN (($1,$2),($3,$4),...,($1999,$2000))
538
539
 
539
540
  | Scenario | Best Fit | Notes |
540
541
  |----------|----------|-------|
541
- | Write operations (transactions) | **litedbmodel** | Fastest in Nested create, Delete, Upsert Many, etc. |
542
- | Bulk Update (diff values) | **litedbmodel** | **3.9x - 7.6x faster** than others (single query) |
543
- | Nested find all | **litedbmodel** | Fastest at 3.64ms |
544
- | Nested single key (speed) | Drizzle | 1 query via LATERAL JOIN (24ms) |
545
- | Nested composite key (speed) | Drizzle | 16ms via LATERAL JOIN |
542
+ | Write operations (transactions) | **litedbmodel** | Fastest in Create, Nested create, Nested update, Upsert, Create Many |
543
+ | Bulk Update (diff values) | **litedbmodel** | **3.9x - 6.6x faster** than others (single query) |
544
+ | Nested find all | **litedbmodel** | Fastest at 2.16ms |
545
+ | Nested single key (speed) | **litedbmodel** | Fastest at 12.18ms (batch-loaded, beats LATERAL JOIN) |
546
+ | Nested composite key (speed) | Drizzle | 14.24ms via LATERAL JOIN |
546
547
  | Nested relation SQL quality | **litedbmodel** | Readable + debuggable; stable query patterns (PG) |
547
548
  | Log Analysis / Monitoring | **litedbmodel** | Consistent query patterns |
548
549
  | SQL Fingerprint Stability (PG) | **litedbmodel** | Most predictable in prepared-statement setups |
@@ -550,13 +551,14 @@ WHERE (tenant_id, user_id) IN (($1,$2),($3,$4),...,($1999,$2000))
550
551
  | Data Integrity | **litedbmodel** | Explicit transactions required for writes |
551
552
 
552
553
  **litedbmodel excels at:**
553
- - **Read operations** (Find unique, Nested find unique, Nested find all - all fastest)
554
- - **Write operations** (Nested create, Delete, Upsert Many, Update Many - fastest)
555
- - **Bulk update with different values** (3.9x - 7.6x faster)
554
+ - **Read operations** (Find all, Filter/paginate, Find unique, Nested find unique, Nested find all - all fastest)
555
+ - **Write operations** (Create, Nested create, Nested update, Upsert, Create Many, Update Many - fastest)
556
+ - **Nested relations, single key** (12.18ms - fastest, beats Drizzle's LATERAL JOIN)
557
+ - **Bulk update with different values** (3.9x - 6.6x faster)
556
558
  - **Consistent performance** across all operations
557
559
  - **Data integrity** via required transactions
558
560
 
559
- **vs Prisma:** litedbmodel is **1.5x - 13.5x faster** across operations
561
+ **vs Prisma:** litedbmodel is **1.4x - 13.7x faster** across operations
560
562
  **vs Query Builders:** litedbmodel matches or beats Kysely/Drizzle in most operations
561
563
 
562
564
  > **litedbmodel provides best-in-class performance with safety guarantees:**
@@ -569,6 +571,6 @@ WHERE (tenant_id, user_id) IN (($1,$2),($3,$4),...,($1999,$2000))
569
571
 
570
572
  ---
571
573
 
572
- *Last updated: March 2026*
574
+ *Last updated: July 2026 (litedbmodel v2.0.2)*
573
575
  *Benchmark methodology: Based on [Prisma orm-benchmarks](https://github.com/prisma/orm-benchmarks)*
574
576