Optimistic Concurrency Control (OCC) is a strategy used in databases and APIs that assumes conflicts between simultaneous updates are rare. Instead of locking a resource while a user is editing it, the system allows anyone to read and attempt to modify the data. The system only checks for a conflict at the exact moment the user tries to save their changes.

Yes, there is a Pessimistic Concurrency Control (PCC) strategy. It takes the opposite approach, assuming that conflicts are highly likely, and prevents them by locking the resource ahead of time.

Here is a direct comparison of how both strategies operate, using a collaborative document editing example (like Google Docs vs. an older document management system):

Direct Comparison

FeatureOptimistic Concurrency Control (OCC)Pessimistic Concurrency Control (PCC)
Core AssumptionConflicts are rare.Conflicts are frequent.
MechanismUses versioning / tokens (like ETags or timestamps) at the moment of saving.Uses locks (Shared or Exclusive) the moment a transaction or edit begins.
User ExperienceMultiple users can view and edit the same data at the exact same time.Only one user can edit a resource at a time; others must wait until the lock is released.
Failure ScenarioA user finishes editing, hits save, but gets rejected with an error because someone else saved first.A user tries to start editing but is blocked immediately by a “Resource is locked” message.
Best Used ForHigh-throughput systems, web APIs, and apps with low chances of users editing the exact same record.Critical data accuracy, long-running batch processes, and systems where conflicts are highly costly.

How They Work in Practice

1. The Optimistic Flow

  1. User A and User B both fetch a bank account record at the same time. The current balance is ₹10,000, and the version token (ETag) is "v1".
  2. User A decides to withdraw ₹2,000.
  3. User B decides to withdraw ₹5,000.
  4. User A hits save first. Their request says: “Update balance to ₹8,000 IF the current version is still v1”. The server checks, matches "v1", applies the change, and bumps the version to "v2".
  5. User B hits save a second later. Their request says: “Update balance to ₹5,000 IF the current version is still v1”. The server checks, sees the current version is now "v2", rejects the request, and returns an error (like 412 Precondition Failed). User B must refresh the data and try again.

2. The Pessimistic Flow

  1. User A clicks “Edit” on the bank account record. The system immediately places an Exclusive Lock on that row in the database.
  2. User B clicks “Edit” on the same record a moment later. The system denies them access or forces their application to wait.
  3. User A takes their time, updates the balance, and hits save. The system saves the data and releases the lock.
  4. User B is finally granted access to edit the newly updated record.

Why REST APIs Prefer Optimistic Concurrency

REST APIs are inherently stateless. Maintaining a pessimistic lock requires the server to remember who owns the lock across multiple HTTP requests. If a client opens a record to edit it and their internet drops (or they walk away from their computer), a pessimistic lock would leave the database resource frozen indefinitely.

Optimistic locking avoids this entirely by keeping the state tracking on the client side using headers like If-Match.

Would you like to see how to implement optimistic locking in a specific programming language, or are you interested in how databases handle pessimistic locks (like SELECT FOR UPDATE)?