As pointed out, a reset is automatic since version 3.7.0 when a statement concludes execution. Technically speaking, a prepared statement is a "generator subprobram" and may have three states: "Never Executed", "Executed and produced Result", or "Done Execution". The prepare process generates the subprogram and it is initially in the "Never Executed" state. When you call sqlite3_step it enters the "executing" state and proceeds either to the "Execute and produced Result" state (you get back SQLITE_ROW) and the subprogram is "paused" while you deal with the interim results. This repeats (you call sqlite3_step again) until the subprogram is complete or "Done Execution" at which point it returns SQLITE_DONE. The above sequence may be modified by detection of an ERROR condition in which case the statement / generator subprogram returns an error indication and goes to the complete or "Done Execution" state and returns SQLITE_ERROR (or some other status code). At this point the automatic reset kicks in and returns the statement automatically to the "Never Executed" state in preparation for the next go-round. sqlite3_reset basically takes any subprogram (statement) and, no matter what its current state at the time of the call, resets any intermediate state and returns is to the "Never Executed" state ready to be executed as if for the first time (so that if you are, for example, in the "paused during execution state" to deal with a generated result row, you can "reset" the execution context in preparation for executing the statement anew).