한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Game Lag White Paper › L12 Database

Hot row lock contention Hot row lock contention

Cause ID db-hot-row · Primary owner Game team (Server development) · Also Infra team (DB infrastructure)

Open the interactive card with figures and simulations →

When everyone tries to modify the same row (a guild vault, a popular auction house item, a server-wide counter), only one request at a time gets the lock.

Why An event or a popular item concentrates updates on the same row → Effect Requests wait until they get the lock → On screen Failed trades, “Please try again later” messages, timeouts

Symptoms
Dropped action / rollback, Input lag
Factors
Stall, Latency
Who’s affected
One feature only
When
When crowds gather
Owner
Primary owner Game team (Server development) · Also Infra team (DB infrastructure)
Game team action items
Split the row (sharded counters), keep transactions short, aggregate in memory and apply in one write.
Infra team action items
Monitor row lock wait time and count, find the rows where contention concentrates, and share them.
Ballpark numbers
If one request holds the lock for 10 ms, that row can be modified at most 100 times a second. A round trip to another server inside the transaction cuts that number further.
On the graph
Rises with load · Row lock wait count and time
Where to look
MySQL: growth of Innodb_row_lock_waits and Innodb_row_lock_time plus Innodb_row_lock_current_waits, and sys.innodb_lock_waits to find who is waiting on whom. PostgreSQL: sessions whose wait_event_type is Lock in pg_stat_activity and requests whose granted is false in pg_locks; turning on log_lock_waits (off by default) logs long lock waits
Confirmed if
Lock waits climb steeply with events and player count, and most waiting requests point to the same row (same key) in the same table
Ruled out if
Waits spread evenly across many tables and rows: points to disk or CPU saturation. One session holds a lock for a long time without releasing it: a long-open transaction (db-long-tx)
Check with
Infra tools (no game code needed)

Sources

  1. InnoDB Locking MySQL
    When one transaction locks a row (index record), other transactions can’t modify that row and wait
  2. How to Minimize and Handle Deadlocks MySQL
    Recommends keeping transactions small and short and committing right after related changes to reduce conflicts
  3. Server Status Variables MySQL
    Innodb_row_lock_waits and Innodb_row_lock_time give the count and total time of row lock waits; Innodb_row_lock_current_waits gives how many are waiting right now
  4. The innodb_lock_waits and x$innodb_lock_waits Views MySQL
    The waiting query (waiting_query), the blocking session (blocking_pid), and the wait time (wait_age)
  5. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    wait_event_type in pg_stat_activity: Lock means waiting for a heavyweight lock
  6. pg_locks (PostgreSQL Documentation) PostgreSQL
    granted false means that process is waiting to acquire the lock
  7. Error Reporting and Logging (PostgreSQL Documentation) PostgreSQL
    log_lock_waits: logs a message when a lock wait lasts longer than deadlock_timeout; off by default

See also

Same layer: L12 Database

Same symptom (Dropped action / rollback), other layers

View the interactive card with figures and simulations