A Savepoint Is a Named Bookmark Inside a Transaction
A regular transaction is all-or-nothing: everything between BEGIN and COMMIT either lands together or gets thrown out together. That's usually what you want — but sometimes you'd like a finer grain. "Try this batch of changes; if it goes wrong, undo just that batch and keep the rest of the transaction alive."
That's what a savepoint is. You drop a named bookmark, do some work, and then either keep the work (RELEASE) or rewind to the bookmark (ROLLBACK TO).
Ada's debit and Boris's credit both stick. The mistaken update to Nobody was rolled back without losing the rest of the transaction.
The Three Commands
Three statements is the whole API:
SAVEPOINT name— set a bookmark.RELEASE SAVEPOINT name— keep the work done since the bookmark; remove the bookmark.ROLLBACK TO SAVEPOINT name— undo everything since the bookmark; the bookmark stays in place so you can try again.
The word SAVEPOINT after RELEASE and ROLLBACK TO is optional — RELEASE risky and ROLLBACK TO risky both work.
The step 2 attempt row never existed as far as the final database is concerned. Everything else lands.
Savepoints Without an Outer Transaction
Here's a small twist: you can issue SAVEPOINT without a BEGIN first. SQLite quietly opens a transaction for you, and the outermost savepoint plays the role of the transaction itself. RELEASE on that savepoint commits, ROLLBACK TO rewinds without committing.
That's why savepoints are sometimes described as "named transactions." But mixing the two styles in real code gets confusing — pick one. Most people use explicit BEGIN ... COMMIT for the outer boundary and savepoints only for the inner partial-undo points.
Nesting Savepoints
Savepoints stack. You can set one inside another and roll the inner one back without touching the outer:
Final contents: a, b, d. Rolling back to inner removed c but left the work done before inner (the insert of b) intact, and the transaction kept going.
Rolling back to an outer savepoint also discards anything done at inner levels — the whole stack above that name unwinds at once:
Both b and c are gone. ROLLBACK TO outer rewinds everything since outer was set, including inner and the c insert.
Why Use Savepoints?
The classic case is processing a batch where individual items are allowed to fail without scrapping the whole batch. Wrap each item in a savepoint; if it fails, roll back to the savepoint and move on:
In real application code, the bad insert raises an error and the application catches it, issues ROLLBACK TO, and continues. Two good rows land; the bad row doesn't poison the batch.
This pattern is also how ORMs and migration tools implement nested transactions — they don't actually nest BEGIN blocks (SQLite doesn't allow that), they map nested calls to savepoints.
A Few Things to Watch
A handful of details that bite people new to savepoints:
COMMITalways commits the whole transaction. It doesn't matter how many open savepoints you have —COMMIT(or its aliasEND) closes the entire outer transaction. Don't think ofRELEASEas a partial commit; nothing is durable until the surrounding transaction commits.ROLLBACK(withoutTO) aborts everything. It ends the transaction and discards all open savepoints. UseROLLBACK TO namewhen you want to keep the transaction alive.- A savepoint stays open until released or rolled back through. Forgetting to
RELEASEdoesn't lose data, but the bookmark just sits there until the transaction ends. - Names aren't required to be unique. If you set
SAVEPOINT stwice,ROLLBACK TO sfinds the most recent one. Useful for recursion; confusing if accidental.
Next: Views
Savepoints give you finer control over writes. The next step is shaping how you read — saving a query as a named, reusable object you can SELECT from like a table. That's a view, and it's coming up next.
Frequently Asked Questions
What is a savepoint in SQLite?
A savepoint is a named marker you set inside a transaction. Later you can ROLLBACK TO that name to undo everything done after it, or RELEASE it to keep the changes and discard the marker. Savepoints let you treat parts of a transaction as smaller, recoverable units.
What's the difference between a savepoint and a transaction in SQLite?
A transaction starts with BEGIN and ends with COMMIT or ROLLBACK. A savepoint is set inside a transaction with SAVEPOINT name and gives you a partial undo point. Rolling back to a savepoint doesn't end the surrounding transaction — you can keep working and commit later.
Can SQLite savepoints be nested?
Yes. You can stack savepoints with different names, and ROLLBACK TO outer undoes everything down to that level, including any inner savepoints. Names don't have to be unique — SQLite uses the most recent savepoint with that name, which is the standard stack behavior.