← Graph

SQLite Busy Handler

concept 5 connections

SQLite C API hook (sqlite3_busy_handler) invoked whenever a connection fails to acquire the write lock. SQLite's shipped busy_timeout is one built-in implementation: a C algorithm using a 12-entry delays array that waits 1 ms the first time but grows to always waiting 100 ms after 12 iterations, so older queries are penalized relative to newer ones — producing long-tail p99.9 latency when writes are steady. Because the C timeout runs inside Ruby's process it holds the GVL, blocking other Puma workers from doing Ruby work during DB waits. Margheim's fix is to implement the busy_handler in Ruby using Kernel#sleep (which releases the GVL) and to make every retry a fair 1 ms wait. The fair Ruby implementation is in the sqlite3 gem main branch and aimed for Rails 8.

category
pattern
about
SQLite Busy Handler concept
Second and third performance fixes (GVL release and fair retry) are implementations of a custom busy_handler.
about
SQLite Busy Handler concept
The recommendation is about implementing the busy_handler in Ruby.
about
SQLite Busy Handler concept
Fair 1 ms retry is a property of the Ruby busy_handler.
concept SQLite Busy Handler
related_to
SQLite tool
busy_handler is a SQLite C API callback for write-lock contention.
concept SQLite Busy Handler
related_to
The native C busy_timeout holds Ruby's GVL; the Ruby re-implementation releases it via Kernel#sleep.

Provenance

Read by
1 extraction