Skip to content
Microsoft SQL Server

SQL Server Error 1204

Cannot obtain a LOCK resource at this time

Applies to: All supported SQL Server versions (2016 to 2025), Azure SQL Database, Azure SQL Managed Instance
Last technically reviewed 24 October 2026 on SQL Server 2025 (17.0.1145.4)
The full message
The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions.
Error number
1204
Severity
19 (resource or software problem)
State
Not documented by Microsoft (not reproduced here)
Product
Microsoft SQL Server Database Engine
Versions
All supported SQL Server versions (2016 to 2025), Azure SQL Database, Azure SQL Managed Instance
Last reviewed
24 October 2026

What it means

Error 1204 means SQL Server could not allocate memory for one more lock, because the pool of lock structures for the whole instance is exhausted, so the statement that needed the lock was stopped.

Every lock a query takes uses a small lock structure from a shared pool. When no more structures can be allocated, the statement that asked for one fails with 1204 at severity 19, a resource error: it is about the instance, not about your data or your permissions. Microsoft lists the reasons: SQL Server cannot get more memory (other processes use it, or max server memory is reached), the lock manager has reached its ceiling of 60 percent of the memory available to SQL Server, the locks option was set to a fixed non-default value, or trace flags 1211 or 1224 limit lock escalation while queries take very many locks.

In practice one session holding millions of row or page locks is the usual trigger: a large update or delete in a single transaction on a table where lock escalation cannot happen, or a long-running open transaction that keeps acquiring locks. The failing statement may belong to an innocent user; look for the session that holds the most locks.

Common causes

  • A single transaction that modifies millions of rows while lock escalation is prevented (table option LOCK_ESCALATION = DISABLE, trace flag 1211 or 1224, or concurrent access that blocks escalation).
  • A long-running or forgotten open transaction that keeps accumulating locks.
  • The locks server option set to a fixed number instead of 0 (dynamic).
  • Memory pressure: max server memory is low or other memory clerks (or other processes on the server) take the memory locks would need.

Diagnose it

Read-only These queries only read metadata and dynamic management views. They do not change data, permissions or configuration, so they are safe to run first.

Which sessions hold the most locks?

SELECT TOP (10) request_session_id, COUNT(*) AS num_locks
FROM sys.dm_tran_locks
GROUP BY request_session_id
ORDER BY num_locks DESC;
What to look for

The query Microsoft suggests. One session with a number far above the rest (hundreds of thousands or millions) is usually the cause.

How much memory do locks use?

SELECT type, name, pages_kb
FROM sys.dm_os_memory_clerks
WHERE type = N'OBJECTSTORE_LOCK_MANAGER'
ORDER BY pages_kb DESC;
What to look for

The lock manager memory. Compare it with the memory available to SQL Server (next check); it cannot use more than about 60 percent of it.

What are the locks and memory settings?

SELECT name, value, value_in_use
FROM sys.configurations
WHERE name IN (N'locks', N'max server memory (MB)', N'min server memory (MB)');
What to look for

locks should be 0 (dynamic). Any other value is a fixed ceiling that Microsoft recommends returning to the default.

Which transactions have been open longest?

SELECT TOP (10) st.session_id, at.transaction_begin_time,
       DATEDIFF(MINUTE, at.transaction_begin_time, SYSDATETIME()) AS open_minutes,
       s.login_name, s.program_name
FROM sys.dm_tran_active_transactions AS at
JOIN sys.dm_tran_session_transactions AS st ON st.transaction_id = at.transaction_id
JOIN sys.dm_exec_sessions AS s ON s.session_id = st.session_id
ORDER BY at.transaction_begin_time;
What to look for

A transaction open for a long time from an interactive tool or a stalled job is a common source of piled-up locks.

Which tables prevent lock escalation?

SELECT OBJECT_SCHEMA_NAME(object_id) AS schema_name, name, lock_escalation_desc
FROM sys.tables
WHERE lock_escalation_desc = N'DISABLE';
What to look for

Large modifications on these tables keep every row lock. Run this in the database that the heavy session uses.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Change large modifications into batches

Changes data

Commit in smaller chunks so no single transaction holds millions of locks. Each batch releases its locks when it commits.

Caution: Batching means the change is no longer one atomic transaction. Make the batch loop restartable, and make sure partial progress is acceptable if it stops halfway.

DECLARE @rows int = 1;
WHILE @rows > 0
BEGIN
    DELETE TOP (5000) FROM dbo.AuditLog
    WHERE logged_at < '2025-01-01';
    SET @rows = @@ROWCOUNT;
END;

End the transaction that holds the most locks

Changes database state

Find the session from the first check and ask its owner to commit or roll back. If it must be stopped, KILL rolls the transaction back, which can take as long as the work it did.

Caution: KILL rolls back everything that session did in its open transaction, and the rollback keeps holding locks until it finishes. Confirm with the owner first.

-- after confirming session 87 is the culprit and may be stopped
KILL 87;

Return the locks option to dynamic

Changes configuration

If the first checks show locks is not 0, Microsoft recommends setting it back to 0 so SQL Server allocates lock memory dynamically. It is an advanced option and takes effect after a restart.

Caution: sp_configure changes the whole instance and this option needs a service restart. Plan it in a maintenance window with whoever owns the server.

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'locks', 0;
RECONFIGURE;

Allow lock escalation for the heavy table

Changes schema

If a table was set to LOCK_ESCALATION = DISABLE, consider returning it to TABLE (the default) or AUTO, so very large operations take one table or partition lock instead of millions of row locks. Review trace flags 1211 and 1224 in the same way.

ALTER TABLE dbo.AuditLog SET (LOCK_ESCALATION = TABLE);

Examples

A huge delete on a table that cannot escalate locks

Shown as documented by Microsoft; not reproduced here, because exhausting lock memory affects every session on the instance. Whether this statement fails depends on the number of rows, other sessions and available memory. The state is not documented, so no message header is shown.

ALTER TABLE dbo.AuditLog SET (LOCK_ESCALATION = DISABLE);

BEGIN TRANSACTION;
    DELETE FROM dbo.AuditLog WHERE logged_at < '2025-01-01';   -- tens of millions of rows
COMMIT;
Result
The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions.

How to prevent it

Write maintenance jobs (purges, archiving, mass updates) to work in batches, and keep transactions short in application code. Leave the locks option at 0 and lock escalation at its default unless a measured problem requires otherwise, and document any exception.

Alert on very long open transactions and on sessions holding unusually many locks, so you can act before the lock pool runs out. The transactions, locks and deadlocks lesson explains how locks are taken and released.

Common questions

Is 1204 the same as a lock timeout or a deadlock?

No. A lock timeout (1222) or deadlock (1205) is about one session waiting for another. 1204 means the instance has no memory left to create another lock at all.

Should I just add more memory?

Only after checking the lock counts. If one transaction holds millions of locks, more memory only delays the error; batching that work fixes it.

Does NOLOCK avoid 1204?

It is not a fix. Readers under NOLOCK can return wrong results, and the locks that exhaust memory usually come from large modifications, which take locks regardless.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on SQL Server 2025 (17.0.1145.4). Message text checked against the engine's sys.messages catalogue.

Still stuck on a SQL Server error?

Browse the full SQL Server error library, or get hands-on help from an experienced SQL professional.