A transaction is created automatically every time you write to the database. That transaction closes when the last prepared statement is reset (using sqlite3_reset()) or finalized (via sqlite3_finalize()). If you don't invoke sqlite3_reset() on every prepared statement that you run, then you will likely be leaving some transactions open, which will prevent the checkpoint from happening and resetting the WAL file.