SapixDBSapixDB/Docs
Home
Community · SaQL

Sort Order

Control whether scan results are returned oldest-first or newest-first using the order field in any SaQL scan query.

Endpoint
MethodPathRelevant fieldValues
POST/v1/agents/:id/queryorder"asc" | "desc"

Default Order

When order is omitted, SapixDB returns records in ascending strand order — oldest record first, newest last. This mirrors the physical write order inside the strand.

SaQL — ascending (default)
POST /v1/agents/events/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "type": "scan",
  "limit": 5
}
SaQL — ascending explicit
{
  "type":  "scan",
  "limit": 5,
  "order": "asc"
}
Strand orderRecords are stored in HLC (Hybrid Logical Clock) sequence. Ascending order is therefore strictly causal — you always read history in the order events actually happened, even across nodes.

Descending Order

Set "order": "desc"to flip the result set so the most-recent record appears first. This is useful for dashboards, activity feeds, and "latest N events" queries.

SaQL — newest first
{
  "type":  "scan",
  "limit": 5,
  "order": "desc"
}
curl
curl -s -X POST http://localhost:7475/v1/agents/events/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer spx_root_YOUR_ROOT_KEY" \
  -d '{"type": "scan", "limit": 5, "order": "desc"}' \
  | python3 -m json.tool

Filters and Sort Order

Filtering always happens before the sort direction is applied. SapixDB collects all records that satisfy the filter predicate, then reverses the result set when order is "desc". The limit is applied after filtering and after reversal.

SaQL — filter then sort descending
{
  "type":   "scan",
  "limit":  10,
  "order":  "desc",
  "filter": {
    "field": "type",
    "op":    "eq",
    "value": "purchase"
  }
}
Filter-before-sort semanticsThe engine never skips a matching record because of sort order. Predicates are evaluated on the full strand first; only the matching subset is sorted and truncated to limit.

Field Reference

FieldTypeDefaultDescription
order"asc" | "desc""asc"Sort direction for the returned records. asc = oldest first (strand order); desc = newest first.
limitintegerMaximum number of records to return. Applied after filtering and after sort direction.
filterobjectnonePredicate applied before sorting. See the SaQL reference for filter syntax.

Python SDK Example

The Python SDK passes the full SaQL body as a dictionary. Sorting is controlled by the same order key.

Python
import requests

BASE = "http://localhost:7475"
AGENT = "events"
HEADERS = {
    "Content-Type": "application/json",
    "Authorization": "Bearer spx_root_YOUR_ROOT_KEY",
}

# Newest 20 purchase events
payload = {
    "type":   "scan",
    "limit":  20,
    "order":  "desc",
    "filter": {"field": "type", "op": "eq", "value": "purchase"},
}

resp = requests.post(
    f"{BASE}/v1/agents/{AGENT}/query",
    json=payload,
    headers=HEADERS,
)
resp.raise_for_status()

for record in resp.json()["records"]:
    print(record["timestamp_hlc"], record["data"])
Tip: combine order with cursor paginationTo page through results newest-first, set "order": "desc" and use after_hlc with the timestamp_hlc of the last record on each page. See Cursor Pagination.