# AsyncSqliteSaver hangs when using astream_events

TL;DR: `AsyncSqliteSaver` holds its database connection open, and `astream_events` waits on it forever. Use the saver as an async context manager and the hang goes away. Nothing is wrong with your graph.

```text
# no error, no traceback. the symptom: this loop never prints anything and never exits:
async for event in graph.astream_events(10, config, version="v1"):
    print(event)
```

## When this applies

- You compiled with `checkpointer=AsyncSqliteSaver...` (not MemorySaver, not Postgres).
- `invoke()` or `stream()` works, but `astream_events()` hangs.
- Killing the process is the only way out.

## When it does not

- If `astream_events` hangs with MemorySaver, the graph itself is stuck (check for an infinite loop, or a node awaiting something that never resolves).
- If it hangs on Postgres, that is a connection-pool issue, not this.

## Fix it

### 1. Use the saver as an async context manager

```python
from langgraph.checkpoint.aiosqlite import AsyncSqliteSaver

async with AsyncSqliteSaver.from_conn_string(":memory:") as saver:
    graph = builder.compile(checkpointer=saver)
    config = {"configurable": {"thread_id": "thread-1"}}
    async for event in graph.astream_events(10, config, version="v1"):
        print(event)
# connection closes here, at the end of the block
```

Expected: events stream normally and the block exits. The context manager closes the connection, which is what the event loop was waiting on.

### 2. For a file-backed database, same pattern

```python
async with AsyncSqliteSaver.from_conn_string("checkpoints.db") as saver:
    graph = builder.compile(checkpointer=saver)
    ...
```

Expected: checkpoints persist to `checkpoints.db` and the process exits cleanly.

### 3. In a long-lived app, do not compile per request

If you need one graph for the whole app lifetime (a web server, a bot), create the saver once at startup inside a lifespan handler and close it at shutdown, instead of compiling inside each request handler.

## Why it happens

`AsyncSqliteSaver` opens a real sqlite connection in async mode. `astream_events` drives the graph through async generators, and the open connection keeps the event loop's cleanup from completing, so the stream never terminates. The sync `SqliteSaver` and the in-memory saver do not hold the loop this way, which is why only the async sqlite saver hangs.

## Edge cases

- `:memory:` databases vanish when the context manager exits. If you need persistence across restarts, use a file path.
- Mixing sync and async savers on the same file can corrupt it. Pick one.
- If you must manage the connection yourself, call the saver's close/aclose explicitly when you are done streaming. The context manager is just the tidy way.

## Compatibility

langgraph 0.0.x through 1.x (Python), `langgraph-checkpoint-sqlite` package. The `async with` pattern is the documented usage.