> ## Documentation Index
> Fetch the complete documentation index at: https://s2.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Reads

> Reads are ordered scans from a stream position, bounded or kept open to follow new records.

Readers can replay history, catch up from a cursor, poll for recent records, or follow a stream live.

S2's CDN-like internal [architecture](/platform/architecture#read-path) allows for a large number of concurrent readers.

## Behavior

A read has three behavioral controls: where it starts, which bounds stop it, and whether it waits at the tail.

Reads can [start from](/api/records/read#starting-point) one of the following:

* record **sequence number**
* record **timestamp**
* a **tail offset**, i.e. N records before the current tail, or the head of the stream if there are fewer records

Sequence numbers are the most precise cursor. Timestamps are useful for time-windowed processing. Tail offsets are useful for "show me the latest activity" views.

<Note>
  S2 returns records in stream order, starting with the earliest record at or after the requested position.
</Note>

[Bounds](/api/records/read#bounds) may be a record count, a byte budget, an end timestamp, or a combination of these. They apply to the full span of the read, including records that arrive while the read is waiting at the tail.

[Wait](/api/records/read#waiting-at-the-tail) determines what happens after a read catches up to the tail. With default options:

* single-batch reads have implicit record count and byte caps, and return immediately
* read sessions have no bounds, and follow indefinitely

## Interfaces

Use the interface that matches the consumer:

| Interface         | Use when                                                                                      |
| ----------------- | --------------------------------------------------------------------------------------------- |
| Single-batch read | You need one bounded response, optionally long polling at the tail.                           |
| Read session      | You need to scan multiple batches, catch up from a cursor, or follow the stream continuously. |
| Check tail        | You only need the current tail position, not the records themselves.                          |

SDK [read sessions](/sdk/reading#read-session) are the preferred interface for continuous consumers because they provide an iterator-style API and reconnect after transient failures. [SSE](/api/records/read#sse) provides a browser-friendly streaming response for the same session model.

## Consistency

Stream operations are **linearizable**. If an `append` has been acknowledged, any subsequent `read` or `check-tail` operation reflects that write.

## Latency

Time-to-first-byte latency for records written in the last 20 seconds to an *Express* stream is expected to be single-digit milliseconds. Otherwise, it can be up to 200 milliseconds.

Tail checks return only the current [tail position](/concepts/streams#positions) and are expected to complete in single-digit milliseconds.

<Note>
  Latency expectations assume an [authenticated client](/api/protocol#authentication) in the same location as the basin.
</Note>

## See also

<CardGroup cols={3}>
  <Card title="Reading SDK" icon="code" href="/sdk/reading">
    Use single-batch reads, read sessions, and check-tail calls.
  </Card>

  <Card title="Read API" icon="globe" href="/api/records/read">
    Review request parameters, SSE sessions, wait behavior, and `416` cases.
  </Card>

  <Card title="Stream positions" icon="water" href="/concepts/streams#positions">
    Head, tail, sequence numbers, and timestamps.
  </Card>
</CardGroup>
