Oracle Wait Events Explained: Top 10 and How to Fix Them
When an Oracle session can't make progress on the CPU, it waits — for a disk block, a lock, a log write, a network round trip. Oracle instruments every one of these pauses as a wait event. Add up where the time goes and you have the single most useful lens on database performance: the wait profile.
The guiding principle is Oracle's own performance method, sometimes called tuning by wait: find the events that consume the most DB time, and attack those first. Don't tune what isn't slow.
DB time = CPU + waits
Every report (AWR, ASH, Statspack) breaks total DB time into time on CPU and time spent waiting. Waits are grouped into classes: User I/O, System I/O, Concurrency, Commit, Configuration, Network, and so on. Knowing the class often points straight at the cause.
Here are the ten you'll encounter most, what they mean, and how to approach them.
1. db file sequential read
Class: User I/O. A single-block read, almost always an index access or a table lookup by ROWID. High totals usually mean a lot of index-driven I/O.
Fix: This is the most common top event and is often healthy. Investigate only if it dominates DB time. Look for inefficient index range scans, a missing composite index, or a buffer cache too small to hold the working set. Check the Top SQL by physical reads.
2. db file scattered read
Class: User I/O. Multi-block reads — the signature of full table scans and fast full index scans.
Fix: Decide whether the full scan is appropriate. For a report touching most
of a table, it's fine. For an OLTP lookup, it usually signals a missing index
or a query that can't use one (function on a column, implicit conversion, OR
expansion). Check the access path in the execution plan.
3. log file sync
Class: Commit. The session committed and is waiting for LGWR to flush redo to disk and acknowledge.
Fix: Two flavors. If average waits are high, you have slow redo I/O — move redo logs to faster storage, separate them from datafiles. If the count is huge but each wait is short, the app is committing too often (e.g. row-by-row). Batch commits where correct.
4. log file parallel write
Class: System I/O. LGWR writing redo to the log files. Correlates directly
with log file sync.
Fix: Pure I/O latency on the redo path. Faster/lower-latency storage for redo, and make sure redo logs aren't sharing spindles with hot datafiles.
5. buffer busy waits
Class: Concurrency. A session wants a block that another session is already modifying in memory.
Fix: A hotspot. Classic cause: many sessions inserting into the same blocks of
a table or index. Mitigate with a higher INITRANS, hash-partitioning the hot
object, or reverse-key indexes for monotonically increasing keys. Check the
Segments by Buffer Busy Waits section.
6. gc buffer busy acquire / release (RAC)
Class: Cluster. A RAC node is waiting for a block owned by another instance via Cache Fusion.
Fix: Reduce cross-instance block shipping. Route related workload to a single node (service affinity), or partition data so each instance owns its hot blocks.
7. latch: ... (e.g. latch: cache buffers chains)
Class: Concurrency. Latches are low-level memory serialization. cache buffers
chains contention points at a very hot block read by many sessions at once.
Fix: Find the hot block / hot SQL (ASH is ideal here). Often a tiny lookup table hammered by every session, or an unselective index. Reduce the access frequency or spread the rows.
8. enq: TX - row lock contention
Class: Application. Sessions blocking on a row lock held by an uncommitted transaction.
Fix: This is application locking, not a database tuning problem. Shorten
transactions, commit sooner, and remove "hot row" patterns (e.g. a single counter
row updated by everyone). Use v$session blocking trees to find the holder.
9. read by other session
Class: User I/O. A session is waiting because another session is already reading the same block from disk into the cache.
Fix: Symptom of a hot block combined with physical I/O. Same remedies as
buffer busy waits plus reducing the physical reads (better caching, better
indexing) so the read finishes faster.
10. direct path read / direct path write
Class: User I/O. Reads/writes that bypass the buffer cache — large full scans, parallel query, and temp spills for sorts and hash joins.
Fix: If it's temp activity, your sorts/hashes are spilling to disk: increase
PGA_AGGREGATE_TARGET or fix the query so it processes fewer rows. If it's large
scans, confirm the scan is intended and that parallelism is set sensibly.
A workflow you can reuse
- Open the Top 10 Foreground Events in your AWR/ASH report.
- Take the top 2–3 by total wait time — ignore the long tail.
- Map each to its class and likely cause using the list above.
- Pivot to the Top SQL and Segments sections to find the specific statement or object responsible.
- Apply the targeted fix, then re-measure with a fresh report.
Not sure you can generate that report? See How to Generate an Oracle AWR Report.
Let the diagnosis come to you
Correlating the wait profile with the right SQL and segments — and knowing which of two top events is the real driver — is where experience pays off. DBA Copilot does this correlation automatically: feed it an AWR or ASH report and it identifies the dominant waits, ties them to the responsible SQL, and proposes prioritized, copy-pasteable recommendations.