October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Asynchronous SQLite in Python: Async CRUD, Transactions, and WAL

Async SQLite can keep Python's event loop responsive while database operations wait, but it does not make SQLite writes parallel. Learn aiosqlite CRUD, explicit transactions, WAL trade-offs, and how to measure your workload.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use aiosqlite to run SQLite operations from Python coroutines without blocking the event loop while those operations wait for the database. It does not make writes on one SQLite database execute in parallel: SQLite still serializes writers. For reliable async CRUD, use parameterized SQL, keep write transactions short, handle commit and rollback explicitly, and consider WAL when readers and a writer need to overlap.

What asynchronous SQLite changes—and what it does not

With aiosqlite, connection and cursor operations have async interfaces, so your coroutine can yield control while a database action is being processed. The library uses a shared thread and request queue for each connection; actions on that connection are processed without overlapping one another. Async syntax therefore helps keep an event loop responsive, but it is not parallel execution of SQL statements on a single connection.

SQLite’s write concurrency remains the key limit. WAL can allow readers and a writer to make progress at the same time, but it does not turn SQLite into a multi-writer database. The SQLite WAL documentation says, “WAL provides more concurrency as readers do not block writers and a writer does not block readers.”

Basic async CRUD with aiosqlite

For a small application or service using a local database, aiosqlite is a direct way to write coroutine-based CRUD. The example below creates a table, inserts a row with bound parameters, reads it, updates it, and deletes it. Use placeholders for values rather than building SQL from user input.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import aiosqlite

DB_PATH = "app.db"

async def create_item(name: str) -> int:
    async with aiosqlite.connect(DB_PATH) as db:
        async with db.execute(
            "INSERT INTO items (name) VALUES (?)",
            (name,),
        ) as cursor:
            item_id = cursor.lastrowid
        await db.commit()
        return item_id

async def get_item(item_id: int):
    async with aiosqlite.connect(DB_PATH) as db:
        async with db.execute(
            "SELECT id, name FROM items WHERE id = ?",
            (item_id,),
        ) as cursor:
            return await cursor.fetchone()

async def rename_item(item_id: int, name: str) -> bool:
    async with aiosqlite.connect(DB_PATH) as db:
        async with db.execute(
            "UPDATE items SET name = ? WHERE id = ?",
            (name, item_id),
        ) as cursor:
            changed = cursor.rowcount > 0
        await db.commit()
        return changed

async def delete_item(item_id: int) -> bool:
    async with aiosqlite.connect(DB_PATH) as db:
        async with db.execute(
            "DELETE FROM items WHERE id = ?",
            (item_id,),
        ) as cursor:
            deleted = cursor.rowcount > 0
        await db.commit()
        return deleted

The example assumes the table exists and uses a simple schema; add application-specific validation and error handling where needed. If several SQL statements form one unit of work, execute them on the same connection and commit only after all succeed. If an operation fails, roll back before reusing the connection or propagate the error so the failed unit of work is not treated as committed.

Transactions: make boundaries explicit

Related writes should be committed together or rolled back together. Keep the transaction limited to database work: do not hold a write transaction open while awaiting an unrelated network request, user input, or other potentially slow application work. Longer write transactions extend the time other writers may have to wait.

Python’s sqlite3 transaction-control documentation recommends the autocommit interface. With autocommit=False, Python keeps a transaction open, starts it with BEGIN DEFERRED, and expects explicit commit or rollback. Older Python versions and legacy transaction-control modes differ, so check the Python runtime and the behavior of the SQLite wrapper actually deployed rather than assuming one configuration fits every version.

Rank #2

In aiosqlite, transaction operations are awaited on the connection. A transaction for a multi-statement unit of work can follow this pattern:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
async def create_order_and_lines(order_data, lines):
    async with aiosqlite.connect("app.db") as db:
        try:
            async with db.execute(
                "INSERT INTO orders (customer_id) VALUES (?)",
                (order_data["customer_id"],),
            ) as cursor:
                order_id = cursor.lastrowid

            for line in lines:
                await db.execute(
                    "INSERT INTO order_lines (order_id, sku, quantity) "
                    "VALUES (?, ?, ?)",
                    (order_id, line["sku"], line["quantity"]),
                )

            await db.commit()
            return order_id
        except Exception:
            await db.rollback()
            raise

Transaction defaults and behavior depend on the Python and aiosqlite versions and connection configuration. Verify those details for the installed versions, especially when changing autocommit settings.

Should you enable WAL?

WAL is worth considering when the application has concurrent readers and a writer. It improves reader/writer overlap, not independent write parallelism. If writes contend heavily, adding asynchronous calls or enabling WAL does not remove the need to serialize them.

WAL also changes database operations. SQLite creates -wal and -shm companion files and uses checkpointing to transfer WAL content back into the database file. SQLite documents automatic checkpointing by default when the WAL reaches 1000 pages; this is an operational threshold, not a throughput guarantee. Processes using a WAL database must be on the same host, so WAL is not a way to share a database file among clients on multiple machines.

Consideration WAL Rollback journaling
Mixed read/write concurrency Readers do not block the writer, and the writer does not block readers, as documented by SQLite. Does not provide WAL’s documented reader/writer overlap.
Write concurrency Writes are still serialized; WAL does not provide simultaneous independent writers. Writes are still serialized.
Operational files and maintenance Uses -wal and -shm companion files and checkpointing; default automatic checkpoint threshold is 1000 pages, per SQLite. Does not use WAL’s sidecar-file and checkpointing arrangement.
Client location Processes must access the database on the same host, per SQLite. Not stated in the cited WAL documentation as a comparative limit.

Enable WAL based on the application’s read/write pattern and deployment model, and account for its files and checkpoint behavior in backup, monitoring, and shutdown procedures. It is not a universal speed switch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Direct aiosqlite or SQLAlchemy asyncio?

Choose aiosqlite when you want a relatively direct async interface to SQLite and are comfortable managing SQL and transaction boundaries yourself. Choose SQLAlchemy asyncio when its higher-level SQL expression, mapping, and session abstractions fit the application. SQLAlchemy’s async SQLite dialect runs through aiosqlite over pysqlite, so it does not alter SQLite’s write concurrency model.

Choice Abstraction and control Transaction and connection considerations
aiosqlite directly Lower-level connection and cursor API; application controls SQL and units of work. Manage commits, rollbacks, connection lifetime, and any write queue explicitly.
SQLAlchemy asyncio Higher-level SQLAlchemy async interface using its aiosqlite dialect. Pool behavior differs between :memory: and file-backed databases. With an in-memory database, coroutines sharing a single connection also share its transaction state; verify engine and pool configuration for the installed release.

SQLAlchemy documents the async SQLite dialect and its pooling behavior in its aiosqlite dialect documentation. Check that documentation against the SQLAlchemy release in your environment and configure transaction control deliberately. An in-memory database is not automatically equivalent to an isolated database per coroutine when a connection is shared.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Bound write contention instead of assuming it away

For an application with many coroutines that may write at once, queue write work or otherwise bound the number of competing writers. A single application-level writer queue can make ordering and contention easier to reason about; it does not increase SQLite’s underlying write parallelism. Keep each queued transaction short and let independent reads proceed according to the chosen journal mode and connection setup.

If the required workload depends on sustained parallel writes, especially from clients on multiple hosts, evaluate a client/server database. Async syntax is an interface choice, not a way to remove SQLite’s single-writer constraint or WAL’s same-host requirement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to assess throughput for your workload

There is no sound universal transactions-per-second figure for “async SQLite” in the official documentation cited here. Performance depends on the schema, indexes, storage, Python and SQLite versions, durability settings, transaction size, and read/write mix. A result from a different setup should not be treated as a promise for yours.

Benchmark the actual application path on target hardware, comparing configurations only when the workload and conditions remain the same. Record:

  • Throughput and latency percentiles for representative reads and writes.
  • Lock or busy events and how often callers wait or retry.
  • WAL growth and checkpoint behavior when WAL is enabled.
  • Event-loop responsiveness under the same mixed load.
  • The schema, indexes, storage, runtime versions, durability settings, and transaction sizes used for each run.

These measures distinguish database throughput from the separate benefit of keeping the event loop available while database work is waiting.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.