1.7 KiB
1.7 KiB
Batch Operations Guide
createMany vs Loop
SLOW (N database round-trips):
for (const userData of users) {
await prisma.user.create({ data: userData })
}
FAST (1 database round-trip):
await prisma.user.createMany({
data: users,
skipDuplicates: true
})
Performance Gain: 50-100x faster for 1000+ records.
Limitations:
- createMany does NOT return created records
- Does NOT trigger middleware or relation cascades
- skipDuplicates skips on unique constraint violations (no error)
Batch Updates
SLOW:
for (const id of orderIds) {
await prisma.order.update({
where: { id },
data: { status: 'shipped' }
})
}
FAST:
await prisma.order.updateMany({
where: { id: { in: orderIds } },
data: { status: 'shipped' }
})
Note: updateMany returns count, not records.
Batch with Transactions
When you need returned records or relation handling:
await prisma.$transaction(
users.map(userData =>
prisma.user.create({ data: userData })
)
)
Use Case: Creating related records where you need IDs for subsequent operations.
Trade-off: Slower than createMany but supports relations and returns records.
Batch Size Considerations
For very large datasets (100k+ records), chunk into batches:
const BATCH_SIZE = 1000
for (let i = 0; i < records.length; i += BATCH_SIZE) {
const batch = records.slice(i, i + BATCH_SIZE)
await prisma.record.createMany({
data: batch,
skipDuplicates: true
})
console.log(`Processed ${Math.min(i + BATCH_SIZE, records.length)}/${records.length}`)
}
Benefits:
- Progress visibility
- Memory efficiency
- Failure isolation (one batch fails, others succeed)