WAL mode doesn't really have "read-only" connection (if you try to open a read-only connection by marking as READ_ONLY with sqlite_open_v2, it will error out for WAL mode). A "supposedly" read-only connection can end up doing writes for example, consolidating WAL log into the main DB file. That can cause SQLITE_BUSY errors. You pretty much have to set the sqlite_busy_timeout in any cases.