---
title: "Session and segment layout"
description: "How AerospikeSessionService maps ADK sessions to session rows and segment records."
---

# Session and segment layout

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

The [overview](https://aerospike.com/docs/develop/adk-infinite-chat-history#key-terms) explained why a long conversation cannot fit in one Aerospike record. `AerospikeSessionService` splits each ADK _session_ across two kinds of Aerospike records instead.

Think of one session as a conversation folder with two parts:

-   A _session row_ acts like the cover sheet. It holds session-scoped _state_ (metadata your agent updates across turns) and a bookmark that points to where the next turn is written.
-   _Segment records_ act like numbered pages in the transcript. Each page stores the next stretch of _events_ in order. When a page fills up, the service adds another page and moves the bookmark forward.

Your application never manages pages directly. It keeps calling `append_event` to add turns and `get_session` to read history. The service handles paging behind those same ADK APIs.

## What each record holds

| Record | Plain-language role | What is stored |
| :-- | :-- | :-- |
| Session row | Cover sheet for one conversation | Session-scoped state, which segment is active, and when the session last changed |
| Segment record | One page of the transcript | A chronological batch of _events_ (user and assistant turns) |

In Aerospike, all of these records live in the `adk_sessions` set. The session row is keyed by `app_name`, `user_id`, and `session_id`. Each segment adds the same key plus a segment number, so segment 0 holds the earliest turns, segment 1 holds the next batch, and so on.

## How appends and rollover work

Each `append_event` call adds one turn to the active segment record, where the bookmark points.

As the conversation grows, that page accumulates more turns. When it reaches Aerospike’s size limit for a single record, the service starts a fresh segment record and updates the bookmark in the session row. Earlier pages stay unchanged. Nothing is truncated.

That is _segment rollover_. You will see it in the demo when a 20,000-turn session spreads across many segment records instead of one oversized record.

## How reads use the layout

Every read starts at the session row to find which segments exist, then loads _events_ from the segment records.

| What you ask for | What the service does |
| :-- | :-- |
| Full history | Reads every segment from first to last and returns the complete transcript in order |
| Recent turns only (`num_recent_events`) | Reads backward from the latest segment until it has enough turns for model context |
| Turns after a time (`after_timestamp`) | Skips older segments when possible and returns only _events_ from that point forward |

That is why recent reads stay fast on a 20,000-turn session. The service can stop at the last segment or two instead of replaying the entire transcript.

On the next page, you append a 20,000-turn synthetic conversation so you can watch rollover happen and try these read paths yourself.

::: undefined
-   I understand the difference between the session row and segment records.
-   I know why segment rollover happens as history grows.
:::

[Previous  
Install and connect](https://aerospike.com/docs/develop/adk-infinite-chat-history/step/1/part/1/install-and-connect) [Next  
Append 20,000 turns](https://aerospike.com/docs/develop/adk-infinite-chat-history/step/3/part/0/append-20k-turns)