# Session Storage (/database/session-storage)



Adding a database persists runs under a `session_id`. Agent and team sessions contain conversation runs. Workflow sessions contain workflow runs.

## Prerequisites [#prerequisites]

For the SQLite/OpenAI examples:

```bash
uv pip install -U "agno[openai,sqlite]"
export OPENAI_API_KEY="your_openai_api_key"
```

## Configure the Session Table [#configure-the-session-table]

SQL adapters default to `agno_sessions` for session metadata and `agno_runs` for runs. Supported adapters create a required table on the first relevant operation when it does not exist. Set `runs_table` as well as `session_table` when separating environments.

Use `session_table` to store sessions in a custom table:

The PostgreSQL fragment requires a running PostgreSQL database and its connection URL. Install the driver with `uv pip install -U "psycopg[binary]"`, then replace the sample credentials below.

```python
from agno.agent import Agent
from agno.db.postgres import PostgresDb

db = PostgresDb(
    db_url="postgresql+psycopg://user:password@localhost:5432/mydb",
    session_table="my_agent_sessions",
)

agent = Agent(db=db)
```

<Tip>
  Use separate tables when you need database-level isolation between environments.
</Tip>

## What Gets Stored [#what-gets-stored]

The following describes a hydrated session object returned by `get_session()`. SQL adapters store run records separately in `runs_table` and load them into `session.runs`; `runs` is not a column in the physical session table. Fields depend on the owner type and may be absent or `None`. The physical SQL row also stores a `session_type` discriminator; it is not a session-object attribute.

| Field           | Type             | Description                                                  |
| --------------- | ---------------- | ------------------------------------------------------------ |
| `session_id`    | `str`            | Unique session identifier                                    |
| `agent_id`      | `str`            | The agent ID (if agent session)                              |
| `team_id`       | `str`            | The team ID (if team session)                                |
| `workflow_id`   | `str`            | The workflow ID (if workflow session)                        |
| `user_id`       | `str`            | The user this session belongs to                             |
| `session_data`  | `dict`           | Session-specific data and state                              |
| `agent_data`    | `dict`           | Agent configuration and metadata                             |
| `team_data`     | `dict`           | Team configuration and metadata                              |
| `workflow_data` | `dict`           | Workflow configuration and metadata                          |
| `metadata`      | `dict`           | Additional custom metadata                                   |
| `runs`          | `list`           | All the runs (interactions) in this session                  |
| `summary`       | `SessionSummary` | Agent/team summary when enabled; not a WorkflowSession field |
| `created_at`    | `int`            | Unix timestamp when session was created                      |
| `updated_at`    | `int`            | Unix timestamp of last update                                |

## Retrieve Sessions [#retrieve-sessions]

Use `get_session()` to retrieve a stored session:

```python
from agno.agent import Agent
from agno.db.sqlite import SqliteDb

agent = Agent(db=SqliteDb(db_file="agent.db"))

agent.print_response("What is the capital of France?", session_id="session_123")

# Retrieve the session
session = agent.get_session(session_id="session_123")

# Access session data
print(session.session_id)
print(session.runs)  # List of runs with messages and responses
```

## Works With Teams and Workflows [#works-with-teams-and-workflows]

Teams and workflows expose the same `get_session()` interface:

```python
from agno.agent import Agent
from agno.team import Team
from agno.workflow import Workflow
from agno.db.sqlite import SqliteDb

db = SqliteDb(db_file="agno.db")

team = Team(members=[Agent(name="Assistant")], db=db)
workflow = Workflow(db=db)

# Retrieve sessions the same way
team_session = team.get_session(session_id="team_session_123")
workflow_session = workflow.get_session(session_id="workflow_session_456")
```

<Note>
  Workflow sessions store complete pipeline runs rather than conversation messages. See [Workflow Sessions](/sessions/workflow-sessions) for details.
</Note>

## Next Steps [#next-steps]

<CardGroup cols="2">
  <Card title="Session Summaries" icon="compress" iconType="duotone" href="/sessions/session-summaries">
    Condense long conversations to save tokens.
  </Card>

  <Card title="Storage Control" icon="sliders" iconType="duotone" href="/sessions/persisting-sessions/storage-control">
    Choose what gets persisted to your database.
  </Card>
</CardGroup>

## Developer Resources [#developer-resources]

* [AgentSession reference](/reference/agents/session)
* [TeamSession reference](/reference/teams/session)
* [WorkflowSession reference](/reference/workflows/session)
