Database Deadlock Detected Error
Fix 'deadlock detected' errors in PostgreSQL and other databases. Learn why concurrent transactions deadlock and how to prevent them.
What Does This Error Mean?
A deadlock occurs when two or more transactions are waiting for each other to release locks, creating a circular dependency. The database automatically detects deadlocks and terminates one of the transactions to break the cycle.
Common Causes
Two transactions updating the same rows in different orders
Transaction A locks row 1 and waits for row 2 while Transaction B locks row 2 and waits for row 1
Long-running transactions holding locks while other transactions wait
Missing indexes causing table-level locks instead of row-level locks
Application-level lock ordering inconsistency
How to Fix It
Always lock resources in the same order
Ensure all transactions access tables and rows in the same consistent order.
// ❌ Deadlock prone
// Transaction 1: update A → update B
// Transaction 2: update B → update A
// ✅ Safe: always update in the same order
always update A first, then B
// In application code, sort IDs before updating
transaction(async (tx) => {
const ids = [userId, otherId].sort() // Sort to ensure consistent order
for (const id of ids) {
await tx.users.update({ where: { id }, data: { ... } })
}
})Implement retry logic
Catch deadlock errors and retry the transaction.
import { Prisma } from "@prisma/client"
async function retryOnDeadlock(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
} catch (err) {
if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2034") {
console.log(`Deadlock detected, retrying (${i + 1}/${maxRetries})`)
continue
}
throw err
}
}
}Keep transactions short
Minimize the duration of transactions to reduce lock contention.
// ❌ Long transaction with external API call inside
await prisma.$transaction(async (tx) => {
await tx.users.update(...)
await fetch("https://slow-api.com/data") // 🔴 Holds lock while waiting!
await tx.orders.update(...)
})
// ✅ Do external work outside the transaction
const data = await fetch("https://slow-api.com/data").then(r => r.json())
await prisma.$transaction(async (tx) => {
await tx.users.update(...)
await tx.orders.update({ ...data })
})Related Tools
Use these tools to debug and fix this error:
Related Errors
Other common errors in this category:
401 Unauthorized Error
Learn what a 401 Unauthorized error means, common causes, and how to fix authentication failures in your web applications.
403 Forbidden Error
Learn what 403 Forbidden means, how it differs from 401, and how to fix access denied errors in your applications.
404 Not Found Error
Learn what 404 Not Found means, common causes, and how to fix broken links and missing resources on your website or API.
429 Too Many Requests Error
Learn what 429 Too Many Requests means, how rate limiting works, and how to handle or avoid hitting API rate limits.