Query
Query Explain
The explain query type returns the execution plan the engine would use for a given filter — without actually running the query. Use it to verify index selection, diagnose unexpected full scans, and confirm that a newly created index is active before relying on it in production.
Request Shape
Send a POST to the query endpoint with "type": "explain" instead of "type": "scan". Pass the same filter you intend to run. No limit or offset is needed — they are ignored for explain requests.
POST /v1/agents/:id/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json
{
"type": "explain",
"filter": { ... }
}Example — Checking a Single-Field Filter
POST /v1/agents/users/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json
{
"type": "explain",
"filter": {
"field": "plan",
"op": "eq",
"value": "pro"
}
}Response when an index is available
{
"explain": {
"strategy": "index_scan",
"index": "idx_plan",
"hint": "Single-field index on 'plan' — expected O(k) where k = matching records"
}
}Response when no index is available
{
"explain": {
"strategy": "full_scan",
"index": null,
"hint": "No index found for field 'plan' — full strand scan"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
strategy | string | Either index_scan or full_scan. See Strategy Types below. |
index | string | null | The name of the index that will be used, or null for a full scan. |
hint | string | A human-readable description of the chosen strategy including complexity estimate. |
Strategy Types
index_scan
The engine found an index that covers the filter. Query cost is O(k) where k is the number of records matching the filter — not the total number of records in the strand. This is the fast path. The index field names the specific index chosen (single-field, composite, or FTS).
full_scan
No usable index was found. The engine will read every record in the strand and evaluate the filter in memory. Cost is O(n) where n is the total number of records. For large strands this can be slow. The index field is null.
full_scan on a strand you expect to grow or on a hot query path with latency requirements.Recommended Workflow
Use explain as part of your standard index management cycle:
POST /v1/agents/users/query
{ "type": "explain", "filter": { "field": "plan", "op": "eq", "value": "pro" } }
// Response:
{ "explain": { "strategy": "full_scan", "index": null, "hint": "No index found for field 'plan' — full strand scan" } }POST /v1/agents/users/indexes
{ "name": "idx_plan", "field": "plan" }GET /v1/agents/users/indexes
// Response when ready:
{ "indexes": [{ "name": "idx_plan", "field": "plan", "type": "single", "status": "ready" }] }POST /v1/agents/users/query
{ "type": "explain", "filter": { "field": "plan", "op": "eq", "value": "pro" } }
// Response:
{ "explain": { "strategy": "index_scan", "index": "idx_plan", "hint": "Single-field index on 'plan' — expected O(k) where k = matching records" } }Explain with Compound Filters
Explain works with any filter shape, including AND and OR blocks. For compound filters the engine reports the strategy it will use for the dominant (most selective) branch.
POST /v1/agents/users/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json
{
"type": "explain",
"filter": {
"AND": [
{ "field": "plan", "op": "eq", "value": "pro" },
{ "field": "country", "op": "eq", "value": "US" }
]
}
}
// Response when composite index exists:
{
"explain": {
"strategy": "index_scan",
"index": "idx_plan_country",
"hint": "Composite index on ['plan','country'] — expected O(k) where k = matching records"
}
}Explain with FTS Filters
POST /v1/agents/articles/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json
{
"type": "explain",
"filter": {
"field": "content",
"op": "fts",
"value": "cryptographic signing"
}
}
// Response when FTS index exists:
{
"explain": {
"strategy": "index_scan",
"index": "idx_fts_content",
"hint": "FTS index on 'content' — posting-list intersection for 2 query token(s)"
}
}