# Checkpointer progression

```python
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()  # dev and tests, ships with langgraph
```

```python
from langgraph.checkpoint.sqlite import SqliteSaver
import sqlite3
checkpointer = SqliteSaver(sqlite3.connect("checkpoint.db"))  # needs langgraph-checkpoint-sqlite
```

```python
from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string("postgresql://...")  # needs langgraph-checkpoint-postgres
```

```python
graph = builder.compile(checkpointer=checkpointer)
```

## Rules

- Async graphs need the async variants: AsyncSqliteSaver, AsyncPostgresSaver. Sync savers in async graphs fail.
- Every invoke/stream needs `{"configurable": {"thread_id": "..."}}`. The thread is the unit of persistence; without it, history is not resumable.
- Time travel (`get_state`, `update_state`, re-invoke from a past checkpoint) works on any checkpointer. Build your "retry this turn" and "edit and resume" UX on it.
- Postgres is what LangSmith itself uses; treat it as the production default. SQLite is for local workflows and experiments.
- Deploying new graph code against old checkpoints: LangGraph runs the latest code against persisted state, so every deploy is a state-migration event. Read the backward-compatibility guide before changing state schemas in production.