prisma-sharding 0.0.5 → 0.0.7
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.
- package/README.md +237 -59
- package/dist/cli/migrate.js +327 -70
- package/dist/cli/studio.js +668 -59
- package/dist/cli/test.js +169 -59
- package/dist/cli/update.js +340 -75
- package/dist/cli/utils/command.js +232 -0
- package/dist/cli/utils/postgres.js +55 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +414 -90
- package/dist/index.mjs +414 -90
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Lightweight database sharding library for Prisma with connection pooling, health monitoring, and CLI tools.
|
|
4
4
|
|
|
5
|
+
## Backward Compatibility Policy
|
|
6
|
+
|
|
7
|
+
This package treats its existing public API as stable. Production-hardening releases do not rename
|
|
8
|
+
commands or public methods, change return shapes, move the package import path, remove exported
|
|
9
|
+
errors, or add required fields to public outputs. Internal routing, execution, health, and CLI
|
|
10
|
+
safety fixes preserve existing application code and the compact default CLI format.
|
|
11
|
+
|
|
5
12
|
## Installation
|
|
6
13
|
|
|
7
14
|
```bash
|
|
@@ -38,76 +45,77 @@ await sharding.connect();
|
|
|
38
45
|
|
|
39
46
|
## API
|
|
40
47
|
|
|
41
|
-
| Method | Description
|
|
42
|
-
| ---------------------------- |
|
|
43
|
-
| `getShard(key)` |
|
|
44
|
-
| `getShardById(shardId)` |
|
|
45
|
-
| `getRandomShard()` |
|
|
46
|
-
| `findFirst(fn)` |
|
|
47
|
-
| `runOnAll(fn)` |
|
|
48
|
-
| `getHealth()` |
|
|
49
|
-
| `connect()` / `disconnect()` | Lifecycle methods
|
|
50
|
-
|
|
51
|
-
### Step 2: Create a User (Assign to a Shard)
|
|
52
|
-
|
|
53
|
-
New records should be created on a random shard for even distribution.
|
|
48
|
+
| Method | Description |
|
|
49
|
+
| ---------------------------- | ---------------------------------------------- |
|
|
50
|
+
| `getShard(key)` | Deterministic client for a routing key |
|
|
51
|
+
| `getShardById(shardId)` | Client for a persisted shard owner |
|
|
52
|
+
| `getRandomShard()` | Random assignment; ownership must be recorded |
|
|
53
|
+
| `findFirst(fn)` | Bounded exception-path search across shards |
|
|
54
|
+
| `runOnAll(fn)` | Bounded admin/analytics execution |
|
|
55
|
+
| `getHealth()` | Health status using the existing output shape |
|
|
56
|
+
| `connect()` / `disconnect()` | Lifecycle methods |
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
import { sharding } from '@/config/prisma';
|
|
57
|
-
|
|
58
|
-
const client = sharding.getRandomShard();
|
|
58
|
+
## Shard Ownership
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
email: 'user@example.com',
|
|
63
|
-
username: 'new_user',
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
```
|
|
60
|
+
Every record needs one authoritative shard owner. Choose one of these patterns and use it
|
|
61
|
+
consistently. Cross-shard search is a recovery path, not an ownership strategy.
|
|
67
62
|
|
|
68
|
-
|
|
63
|
+
### Pattern A: Deterministic Ownership
|
|
69
64
|
|
|
70
|
-
|
|
65
|
+
Generate or obtain the routing key before inserting the record, then use the same key for every
|
|
66
|
+
future operation:
|
|
71
67
|
|
|
72
|
-
```
|
|
73
|
-
|
|
68
|
+
```typescript
|
|
69
|
+
import { sharding } from '@/config/prisma';
|
|
74
70
|
|
|
71
|
+
const userId = crypto.randomUUID();
|
|
75
72
|
const client = sharding.getShard(userId);
|
|
73
|
+
const user = await client.user.create({
|
|
74
|
+
data: { id: userId, email: 'user@example.com', username: 'new_user' },
|
|
75
|
+
});
|
|
76
76
|
|
|
77
|
-
const
|
|
77
|
+
const sameUser = await sharding.getShard(userId).user.findUnique({
|
|
78
78
|
where: { id: userId },
|
|
79
79
|
});
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
`
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
That includes:
|
|
82
|
+
Modulo routing uses the existing `hashString(key) % shardCount` placement. The hash function and
|
|
83
|
+
configured shard order are data-placement contracts: changing either can move existing records and
|
|
84
|
+
requires an explicit migration or dual-read plan. Consistent hashing also preserves configured
|
|
85
|
+
shard IDs and supports custom IDs such as `tenant-east`.
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
- Updating user data
|
|
90
|
-
- Creating related records (profiles, posts, settings, etc)
|
|
87
|
+
### Pattern B: Assigned Ownership
|
|
91
88
|
|
|
92
|
-
|
|
89
|
+
Random assignment can distribute new records, but the application must persist the assigned shard
|
|
90
|
+
ID in a directory table, tenant registry, or equivalent ownership metadata:
|
|
93
91
|
|
|
94
|
-
|
|
92
|
+
```typescript
|
|
93
|
+
const { client, shardId } = sharding.getRandomShardWithInfo();
|
|
94
|
+
const user = await client.user.create({ data: { email, username } });
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
await shardDirectory.create({ data: { recordId: user.id, shardId } });
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
const ownership = await shardDirectory.findUniqueOrThrow({
|
|
99
|
+
where: { recordId: user.id },
|
|
100
|
+
});
|
|
101
|
+
const sameUser = await sharding
|
|
102
|
+
.getShardById(ownership.shardId)
|
|
103
|
+
.user.findUnique({ where: { id: user.id } });
|
|
100
104
|
```
|
|
101
105
|
|
|
102
|
-
|
|
106
|
+
The existing `getRandomShard()` method still returns only a client. Calling it for a write and
|
|
107
|
+
later calling `getShard(record.id)` is **not guaranteed to select the same shard**. If you use
|
|
108
|
+
`getRandomShard()`, your application needs another reliable way to record which shard was selected.
|
|
109
|
+
`weight` affects random assignment only; it never changes deterministic `getShard(key)` placement.
|
|
103
110
|
|
|
104
|
-
###
|
|
111
|
+
### Find Without Ownership Metadata
|
|
105
112
|
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
`findFirst()` is bounded, timed, health-aware, and returns when the first non-null result arrives.
|
|
114
|
+
Even so, one call can create work on multiple databases. Treat it as an exception, recovery, or
|
|
115
|
+
administrative path. At high traffic it should not be the normal login, email lookup, user lookup,
|
|
116
|
+
or tenant lookup path; maintain shard ownership metadata instead.
|
|
108
117
|
|
|
109
118
|
```typescript
|
|
110
|
-
// Find user by email across ALL shards (parallel execution)
|
|
111
119
|
const { result: user, client } = await sharding.findFirst(async (c) =>
|
|
112
120
|
c.user.findFirst({ where: { email } })
|
|
113
121
|
);
|
|
@@ -121,10 +129,10 @@ if (user && client) {
|
|
|
121
129
|
}
|
|
122
130
|
```
|
|
123
131
|
|
|
124
|
-
|
|
132
|
+
### Run on All Shards
|
|
125
133
|
|
|
126
134
|
```typescript
|
|
127
|
-
//
|
|
135
|
+
// Appropriate for bounded admin or analytics work, not a normal request path.
|
|
128
136
|
const counts = await sharding.runOnAll(async (client) => client.user.count());
|
|
129
137
|
const totalUsers = counts.reduce((sum, count) => sum + count, 0);
|
|
130
138
|
|
|
@@ -136,6 +144,13 @@ const results = await sharding.runOnAllWithDetails(async (client, shardId) => {
|
|
|
136
144
|
|
|
137
145
|
### Health Monitoring
|
|
138
146
|
|
|
147
|
+
`connect()` initializes all clients and starts background warmup for clients that implement
|
|
148
|
+
`$connect()`, followed by an initial `SELECT 1` when `$queryRaw` is available. Warmup does not delay
|
|
149
|
+
client availability, preserving existing startup behavior. Periodic checks have a deadline, cannot
|
|
150
|
+
overlap, and update the existing `ShardHealth` shape. Deterministic routing still returns the
|
|
151
|
+
record's owner when it is marked unhealthy; cross-shard work schedules healthy, lower-latency
|
|
152
|
+
shards first.
|
|
153
|
+
|
|
139
154
|
```typescript
|
|
140
155
|
// Get health of all shards
|
|
141
156
|
const health = sharding.getHealth();
|
|
@@ -169,6 +184,7 @@ Add to your `package.json`:
|
|
|
169
184
|
{
|
|
170
185
|
"scripts": {
|
|
171
186
|
"db:update": "prisma-sharding-update",
|
|
187
|
+
"migrate:shards": "prisma-sharding-migrate",
|
|
172
188
|
"db:studio": "prisma-sharding-studio",
|
|
173
189
|
"test:shards": "prisma-sharding-test"
|
|
174
190
|
}
|
|
@@ -184,48 +200,155 @@ SHARD_2_URL=postgresql://user:pass@host:5432/db2
|
|
|
184
200
|
SHARD_3_URL=postgresql://user:pass@host:5432/db3
|
|
185
201
|
SHARD_ROUTING_STRATEGY=modulo # or consistent-hash
|
|
186
202
|
SHARD_STUDIO_BASE_PORT=51212 # optional, for studio
|
|
203
|
+
SHARD_STUDIO_REUSE_EXISTING=true # optional, defaults to true
|
|
204
|
+
SHARD_STUDIO_STRICT_PORT_CHECK=false # optional, defaults to false
|
|
205
|
+
SHARD_STUDIO_START_TIMEOUT_MS=15000 # optional, defaults to 15000
|
|
206
|
+
SHARD_STUDIO_VERBOSE=false # optional, defaults to false
|
|
207
|
+
SHARD_CLI_VERBOSE=false # optional, verbose update/migrate output
|
|
208
|
+
PRISMA_SHARDING_VERBOSE=false # optional, library lifecycle logs
|
|
187
209
|
```
|
|
188
210
|
|
|
189
211
|
### Commands
|
|
190
212
|
|
|
191
213
|
#### `prisma-sharding-update` (Recommended)
|
|
192
214
|
|
|
193
|
-
The "All-in-One" command
|
|
194
|
-
|
|
215
|
+
The "All-in-One" development command generates Prisma Client types and synchronizes local/dev
|
|
216
|
+
shards. Use this whenever you change `schema.prisma` during development. It is not a production
|
|
217
|
+
migration workflow.
|
|
195
218
|
|
|
196
219
|
1. Runs `prisma generate` (Updates TypeScript types)
|
|
197
|
-
2. Runs `prisma db push` on all shards (
|
|
220
|
+
2. Runs `prisma db push` on all shards (Synchronizes development databases)
|
|
198
221
|
|
|
199
222
|
```bash
|
|
200
223
|
yarn db:update
|
|
201
224
|
|
|
202
225
|
```
|
|
203
226
|
|
|
204
|
-
|
|
205
|
-
|
|
227
|
+
Default output stays compact:
|
|
228
|
+
|
|
229
|
+
```text
|
|
230
|
+
🔄 Prisma Sharding Update
|
|
231
|
+
|
|
232
|
+
✅ client Generated
|
|
233
|
+
✅ shard_1 Synced
|
|
234
|
+
✅ shard_2 Synced
|
|
235
|
+
✅ shard_3 Synced
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Interactive terminals show a single inline loader while Prisma Client generation and each shard
|
|
239
|
+
sync are running. The loader is replaced by the completed row and is disabled for piped or CI logs.
|
|
240
|
+
|
|
241
|
+
Set `SHARD_CLI_VERBOSE=true` or `SHARD_UPDATE_VERBOSE=true` to include Prisma command
|
|
242
|
+
output, masked database URLs, and detailed diagnostics.
|
|
243
|
+
|
|
244
|
+
Existing flags remain unchanged and are forwarded as provided. For example:
|
|
206
245
|
|
|
207
246
|
```bash
|
|
208
247
|
yarn db:update --force-reset
|
|
209
248
|
|
|
210
249
|
```
|
|
211
250
|
|
|
251
|
+
The command does not inject `--accept-data-loss` automatically.
|
|
252
|
+
|
|
212
253
|
#### `prisma-sharding-migrate`
|
|
213
254
|
|
|
214
|
-
|
|
255
|
+
This is the production/staging path. For each shard it checks migration status and runs
|
|
256
|
+
`prisma migrate deploy`, applying committed migration artifacts without generating the client,
|
|
257
|
+
resetting the database, or using `db push`.
|
|
215
258
|
|
|
216
259
|
```bash
|
|
217
260
|
yarn migrate:shards
|
|
218
261
|
|
|
219
262
|
```
|
|
220
263
|
|
|
264
|
+
Any failed shard makes the command exit non-zero and remains visible in the compact results.
|
|
265
|
+
This command uses the same compact shard rows as `db:update`. Set
|
|
266
|
+
`SHARD_CLI_VERBOSE=true` or `SHARD_MIGRATE_VERBOSE=true` for Prisma command output.
|
|
267
|
+
|
|
268
|
+
Do not use `prisma db push` as a production migration strategy. Commit and review the Prisma
|
|
269
|
+
migration directory, then run `prisma-sharding-migrate` during deployment. Verbose mode includes
|
|
270
|
+
sanitized status/deploy commands, masked database URLs, exit codes, shard IDs, and next-step hints.
|
|
271
|
+
|
|
221
272
|
#### `prisma-sharding-studio`
|
|
222
273
|
|
|
223
274
|
Start Prisma Studio for all shards on sequential ports.
|
|
224
275
|
|
|
225
276
|
```bash
|
|
226
277
|
yarn db:studio
|
|
227
|
-
|
|
278
|
+
```
|
|
228
279
|
|
|
280
|
+
By default, ports are assigned from `SHARD_STUDIO_BASE_PORT`:
|
|
281
|
+
|
|
282
|
+
```text
|
|
283
|
+
shard_1 -> http://localhost:51212
|
|
284
|
+
shard_2 -> http://localhost:51213
|
|
285
|
+
shard_3 -> http://localhost:51214
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Set `SHARD_STUDIO_BASE_PORT` to move the whole range:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
SHARD_STUDIO_BASE_PORT=52000 yarn db:studio
|
|
292
|
+
# shard_1 -> :52000, shard_2 -> :52001, etc.
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Studio startup is safe to run from multiple local APIs. Before starting a shard Studio,
|
|
296
|
+
the CLI checks whether the target port is already active. If it finds an existing Prisma
|
|
297
|
+
Studio on that port, it reuses it instead of spawning another process:
|
|
298
|
+
|
|
299
|
+
```text
|
|
300
|
+
🗄️ Prisma Sharding Studio
|
|
301
|
+
|
|
302
|
+
♻️ shard_1 http://localhost:51212
|
|
303
|
+
♻️ shard_2 http://localhost:51213
|
|
304
|
+
♻️ shard_3 http://localhost:51214
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
If a port is occupied by another process that does not look like Prisma Studio, the shard
|
|
308
|
+
is marked with a warning and the CLI continues with the remaining shards. It will not kill,
|
|
309
|
+
restart, or claim ownership of processes it did not start.
|
|
310
|
+
|
|
311
|
+
Default output is intentionally compact:
|
|
312
|
+
|
|
313
|
+
```text
|
|
314
|
+
🗄️ Prisma Sharding Studio
|
|
315
|
+
|
|
316
|
+
✅ shard_1 http://localhost:51212
|
|
317
|
+
✅ shard_2 http://localhost:51213
|
|
318
|
+
✅ shard_3 http://localhost:51214
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Run with `SHARD_STUDIO_VERBOSE=true` to print port checks, masked database URLs, Prisma
|
|
322
|
+
Studio child-process output, startup timings, and detailed failure diagnostics.
|
|
323
|
+
|
|
324
|
+
Useful Studio environment variables:
|
|
325
|
+
|
|
326
|
+
- `SHARD_STUDIO_BASE_PORT`: first port in the shard Studio range. Defaults to `51212`.
|
|
327
|
+
- `SHARD_STUDIO_REUSE_EXISTING`: reuse already-running Prisma Studio ports. Defaults to `true`.
|
|
328
|
+
- `SHARD_STUDIO_STRICT_PORT_CHECK`: when `true`, any failed shard makes the command exit
|
|
329
|
+
non-zero after stopping Studio processes started by that run. Defaults to `false`.
|
|
330
|
+
- `SHARD_STUDIO_START_TIMEOUT_MS`: maximum time to wait for a newly spawned Studio to become
|
|
331
|
+
reachable. Defaults to `15000`.
|
|
332
|
+
- `SHARD_STUDIO_STABILITY_MS`: short window a newly-ready Studio process must survive before
|
|
333
|
+
it is reported as started. Defaults to `500`.
|
|
334
|
+
- `SHARD_STUDIO_SHUTDOWN_TIMEOUT_MS`: time to wait for owned Studio processes to close during
|
|
335
|
+
shutdown before sending a force-stop signal. Defaults to `5000`.
|
|
336
|
+
- `SHARD_STUDIO_VERBOSE`: print detailed Studio startup diagnostics. Defaults to `false`.
|
|
337
|
+
- `SHARD_STUDIO_DEBUG`: alias for `SHARD_STUDIO_VERBOSE`.
|
|
338
|
+
|
|
339
|
+
When multiple APIs use the same shard configuration locally, the first API starts the Studio
|
|
340
|
+
processes and later APIs reuse the existing Studio ports. Reused-only commands stay quietly
|
|
341
|
+
attached, preventing process supervisors from printing a normal child-exit message. Pressing
|
|
342
|
+
Ctrl+C only stops Studio processes started by the current CLI run; reused processes are left running.
|
|
343
|
+
|
|
344
|
+
If you run Studio beside `nodemon`, prefer an explicit watch scope for the API process. Prisma
|
|
345
|
+
Studio does not need to write to your app source, but broad nodemon defaults can restart on
|
|
346
|
+
generated TypeScript or JSON files produced by other dev tooling:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
nodemon --watch src --ext ts,json \
|
|
350
|
+
--ignore 'src/types/*.generated.ts' \
|
|
351
|
+
--exec tsx --env-file=.env --no-warnings src/server.ts
|
|
229
352
|
```
|
|
230
353
|
|
|
231
354
|
#### `prisma-sharding-test`
|
|
@@ -289,7 +412,7 @@ Verified 5/5 users on correct shards
|
|
|
289
412
|
| `shards` | `ShardConfig[]` | Required | Array of shard configurations |
|
|
290
413
|
| `strategy` | `'modulo' \| 'consistent-hash'` | `'modulo'` | Routing algorithm |
|
|
291
414
|
| `createClient` | `(url, shardId) => TClient` | Required | Factory to create Prisma clients |
|
|
292
|
-
| `healthCheckIntervalMs` | `number` | `30000` |
|
|
415
|
+
| `healthCheckIntervalMs` | `number` | `30000` | Positive health check frequency |
|
|
293
416
|
| `circuitBreakerThreshold` | `number` | `3` | Failures before marking unhealthy |
|
|
294
417
|
|
|
295
418
|
### Shard Config
|
|
@@ -298,7 +421,7 @@ Verified 5/5 users on correct shards
|
|
|
298
421
|
interface ShardConfig {
|
|
299
422
|
id: string; // Unique identifier (e.g., 'shard_1')
|
|
300
423
|
url: string; // PostgreSQL connection string
|
|
301
|
-
weight?: number; //
|
|
424
|
+
weight?: number; // Positive random-assignment weight only
|
|
302
425
|
isReadReplica?: boolean;
|
|
303
426
|
}
|
|
304
427
|
```
|
|
@@ -315,12 +438,64 @@ strategy: 'modulo';
|
|
|
315
438
|
|
|
316
439
|
### Consistent Hash
|
|
317
440
|
|
|
318
|
-
|
|
441
|
+
Uses a precomputed virtual-node ring and binary search. Custom and non-sequential shard IDs are
|
|
442
|
+
supported. Adding or removing shards still changes ownership for part of the keyspace, so plan data
|
|
443
|
+
movement before changing a production shard list.
|
|
319
444
|
|
|
320
445
|
```typescript
|
|
321
446
|
strategy: 'consistent-hash';
|
|
322
447
|
```
|
|
323
448
|
|
|
449
|
+
## Architecture and Scaling
|
|
450
|
+
|
|
451
|
+
The public `PrismaSharding` layer validates and delegates without changing its established surface.
|
|
452
|
+
Internally, the router owns key placement, the manager owns clients and health state, and one
|
|
453
|
+
cross-shard executor owns concurrency, deadlines, health-aware scheduling, stable result ordering,
|
|
454
|
+
and failure isolation. CLI commands share one shard parser and one sanitized child-process runner.
|
|
455
|
+
|
|
456
|
+
| Layer | Responsibility |
|
|
457
|
+
| --- | --- |
|
|
458
|
+
| Public API | Validate, delegate, and preserve existing result shapes |
|
|
459
|
+
| Router | Stable deterministic placement and weighted random assignment |
|
|
460
|
+
| Shard manager | Client lifecycle, initial verification, health, and shutdown |
|
|
461
|
+
| Cross-shard executor | Shared concurrency, deadlines, ordering, and failure isolation |
|
|
462
|
+
| CLI | Safe migration/update/test/Studio orchestration with compact output |
|
|
463
|
+
|
|
464
|
+
Low-level execution behavior is intentionally internal: fan-out concurrency and deadlines are
|
|
465
|
+
central defaults, the hash function is unchanged, health checks use typed Prisma-like capability
|
|
466
|
+
guards, successful `runOnAll()` results retain configured shard order, and errors stay isolated in
|
|
467
|
+
the existing detailed result shape.
|
|
468
|
+
|
|
469
|
+
Normal request flow should be:
|
|
470
|
+
|
|
471
|
+
```text
|
|
472
|
+
routing key or directory lookup -> one shard -> one Prisma operation
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
`findFirst()` and `runOnAll()` use bounded concurrency and per-shard deadlines, but they still
|
|
476
|
+
multiply database work and tail-latency exposure. Reserve them for recovery, administration, and
|
|
477
|
+
analytics. Pending Prisma queries may not be cancellable after an early `findFirst()` result, so
|
|
478
|
+
the caller can resolve before all already-started database work has physically stopped.
|
|
479
|
+
|
|
480
|
+
The executor deadline limits how long the package waits; it does **not** cancel the underlying
|
|
481
|
+
Prisma or PostgreSQL query. Configure a database-level deadline as well, such as PostgreSQL
|
|
482
|
+
`statement_timeout` or the equivalent adapter/provider query timeout, so timed-out work cannot
|
|
483
|
+
continue consuming database resources indefinitely.
|
|
484
|
+
|
|
485
|
+
### Connection Pool Budgeting
|
|
486
|
+
|
|
487
|
+
Each shard client owns or uses a connection pool. Budget the fleet-wide maximum as:
|
|
488
|
+
|
|
489
|
+
```text
|
|
490
|
+
application instances × shards per instance × connections per shard pool
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
For example, 20 application instances × 8 shards × 10 connections can attempt 1,600 database
|
|
494
|
+
connections. Set the adapter's pool limit and connection timeout deliberately per application
|
|
495
|
+
instance and per shard. At larger fleet sizes, use PgBouncer or provider-managed pooling and verify
|
|
496
|
+
that the database's total connection budget includes migrations, administration, and failover
|
|
497
|
+
headroom. The sharding package does not create hidden extra Prisma clients.
|
|
498
|
+
|
|
324
499
|
## Error Handling
|
|
325
500
|
|
|
326
501
|
```typescript
|
|
@@ -337,6 +512,9 @@ try {
|
|
|
337
512
|
|
|
338
513
|
## Custom Logger
|
|
339
514
|
|
|
515
|
+
The default logger prints warnings and errors only. Set `PRISMA_SHARDING_VERBOSE=true` to include
|
|
516
|
+
initialization, shard connection, and shutdown lifecycle messages.
|
|
517
|
+
|
|
340
518
|
```typescript
|
|
341
519
|
const sharding = new PrismaSharding({
|
|
342
520
|
// ...config,
|