Check plan reuse
The language tabs use earlier client interfaces. Check SDK versions and connection setup before running them.
Send the same question twice to see whether Ask reuses its compiled plan. A plan describes a query; it is not a saved copy of the result rows.
Before you run it: A cache hit does not mean the rows are stale. Changes to the question, schemas or table definition can change cache behavior.
After loading the two sample customers below, both requests should return the same count unless another write occurs. Compare cache separately from rows: reusing a plan means reusing query instructions, not reusing the old answer.
- Ask the first questionKeep its wording and schemas for the comparison.
- Repeat the same questionThe service may reuse a suitable cached plan.
- Read both outputsInspect cache status separately from the newly returned rows.
Follow the example
- Load the sample and confirm Ask is enabled.
- Send the question with its schemas list.
- Repeat the same request.
- Compare cache metadata and returned rows.
Set up the table
Save this definition as customers.toml and send it to POST /v1/tenants/:t/schemas with Content-Type: text/plain before loading rows. The schema walkthrough shows how to register a file; use this page's definition for its sample.
namespace = "shop"
table = "customers"
primary_key = ["id"]
[[columns]]
name = "id"
ty = "str"
required = true
[[columns]]
name = "email"
ty = "str"Load sample rows
# Any handful of customers is fine - the cache hit doesn't depend on the count.
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/rows/shop.customers/_batch" \
-H "Authorization: Bearer $OC_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{ "id": "c_1", "email": "alice@example.com" },
{ "id": "c_2", "email": "bob@example.com" }
]'Run the request
# Call the same question twice - watch the cache field flip.
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/ask" \
-H "Authorization: Bearer $OC_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "nl": "how many customers do I have?", "schemas": ["shop.customers"] }'
# Same body, same headers - just send it again.
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/ask" \
-H "Authorization: Bearer $OC_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "nl": "how many customers do I have?", "schemas": ["shop.customers"] }'Check the result
The illustrated calls show a miss followed by a hit. Some requests may report skip.
First call:
{
"rows": [
{ "count": 2 }
],
"cache": "miss"
}Second call:
{
"rows": [
{ "count": 2 }
],
"cache": "hit"
}The cache values are "hit", "miss", or "skip". "skip" means the engine bypassed the cache - for example when the question depends on state that can't be safely cached.
How the database handles this request
- The cache key is
(canonicalised_nl, sorted_schemas_list). Case, whitespace, and trailing punctuation are normalised before hashing. - Only the plan tree is cached - rows are always read fresh from the row store, so the count reflects current state on a
"hit". - Schema migrations evict entries that reference affected schemas. After you alter
shop.customers, the next call for that question re-plans. - The cache is per-tenant and durable across replicas - it rides the WAL stream that provisioned standbys tail, so a standby that is promoted keeps the entries it has already tailed.
Important limits and checks
- Interpolating values into the question.
"orders from customer c_1"and"orders from customer c_2"are different cache entries. Use a parameterised question:"orders for a given customer id"and bind the value separately when supported, or fall back to/v1/querywith a saved plan. - Re-ordering the schemas list.
["a","b"]and["b","a"]hash to the same key (the engine sorts), but adding or removing a schema does change it. - Expecting stale rows on a hit. The plan is cached. The data is not. A
"hit"still runs the executor against current rows.