Cache rule schema

Rules in Airbrx are JSON objects stored on a tenant's configuration. The App's rules workshop is the usual edit surface; this page is the underlying shape — for scripting bulk changes, importing rules from another tenant, or generating rules from an external system. For the conceptual model, start with Rules as the differentiator.

Top-level shape

{
  "id": "cache_customer_data",
  "name": "Cache customer queries for 1 hour",
  "description": "Per-user cache on the CUSTOMER table",
  "enabled": true,
  "priority": 10,
  "mode": "all",
  "conditions": { /* what queries match */ },
  "actions":    { /* what happens on match */ },
  "respectSqlHints": true,
  "invalidateRules": [],
  "requireInvalidation": false
}

Required fields

FieldTypeDescription
idstringUnique identifier within the tenant.
namestringHuman-readable display name.
enabledbooleanWhether the rule is active.
priorityinteger (1–100)Evaluation order. Lower number = higher priority. Priority 1 is "most important," 100 is "fallback."
modestring"all" for AND logic across conditions, "either" for OR logic.

Optional fields

FieldTypeDescription
descriptionstringFree-form explanation of the rule's intent.
conditionsobjectMatching criteria. Empty / omitted = match all queries.
actionsobjectWhat happens when the rule matches.
respectSqlHintsbooleanHonor inline SQL comment hints (default true).
invalidateRulesstring[]Rule IDs to invalidate when this DML rule fires.
requireInvalidationbooleanIf true, the DML statement fails when invalidation can't be recorded (default false).

Conditions

Conditions match query metadata. Within a single condition type, operators combine with AND. The rule's mode controls how condition types combine.

Tables

OperatorDescriptionExample
includesTable appears in the query"includes": "ORDERS"
notIncludesTable does not appear"notIncludes": "TEMP_DATA"
includesAnyAny of these tables appear"includesAny": ["ORDERS","SALES"]
includesAllAll of these tables appear"includesAll": ["ORDERS","CUSTOMERS"]

Schema / catalog

OperatorDescriptionExample
equalsExact match"equals": "finance"
matchesRegex pattern"matches": "^prod_.*"
inOne of these values"in": ["finance","accounting"]

Statement type

Common values: SELECT, INSERT, UPDATE, DELETE, SHOW, DESCRIBE, WITH.

OperatorDescriptionExample
equalsExact statement type"equals": "SELECT"
inOne of these types"in": ["SELECT","SHOW"]
notInNot one of these types"notIn": ["INSERT","UPDATE","DELETE"]

SQL pattern

OperatorDescriptionExample
matchesRegex on the statement text"matches": "\\bJOIN\\b"
containsSubstring search"contains": "WHERE customer_id"
startsWithBegins with"startsWith": "SELECT COUNT"

Columns

OperatorDescriptionExample
includesColumn appears"includes": "email"
includesAnyAny of these columns"includesAny": ["ssn","credit_card"]
includesAllAll of these columns"includesAll": ["first_name","last_name"]

User

OperatorDescriptionExample
equalsSpecific user"equals": "admin@company.com"
matchesEmail pattern"matches": ".*@contractors\\.com"
inList of users"in": ["user1","user2"]

Parameterized queries

Match queries with parameter placeholders — :name, ?, $1:

{
  "conditions": {
    "hasParameters": true,
    "parameters": {
      "customer_id": { "equals": "VIP123" },
      "region":      { "in": ["US","CA","MX"] },
      "ssn":         { "exists": true }
    }
  }
}
ConditionDescription
hasParametersBoolean — query has parameter placeholders
parameters.<name>.equalsExact parameter value
parameters.<name>.inValue in list
parameters.<name>.matchesRegex on value
parameters.<name>.existsParameter is bound
parameters.<name>.greaterThanNumeric comparison
parameters.<name>.lessThanNumeric comparison

Parameter values are automatically included in cache keys when present — you don't need to specify them in cacheKeyElements.

Modes

"mode": "all" (default) — every condition must match. "mode": "either" — any condition matching is enough.

Actions

Cache TTL

{
  "actions": {
    "cache": { "ttlSeconds": 3600 }
  }
}
TTLMeaning
0Don't cache — bypass
601 minute
36001 hour
8640024 hours
6048001 week

Stale-while-revalidate

Opt a cache rule into stale-while-revalidate by adding a staleWhileRevalidate block on the cache action. When a cached entry is past its TTL but within the SWR window, the Gateway returns the cached value immediately and fires a background refresh against the warehouse. See the cookbook recipe for when to reach for it.

{
  "actions": {
    "cache": {
      "ttlSeconds": 3600,
      "staleWhileRevalidate": {
        "enabled": true,
        "windowSeconds": 86400
      }
    }
  }
}
FieldTypeDescription
enabledbooleanWhether SWR applies to this rule. Default false; omitting the block has the same effect.
windowSecondsinteger or nullHow far past TTL the Gateway will serve a stale result before falling through to a synchronous miss. null means "serve stale until a refresh succeeds" — unbounded; rare.

Validation. enabled: true with no windowSeconds is a load-time error — tenants must explicitly choose a stale ceiling (including null for forever). Negative or non-finite values are also rejected.

Invalidation precedence. An invalidation marker against a cache rule always suppresses its stale-cached response, even inside the SWR window. SWR bounds latency; invalidation bounds correctness, and correctness wins.

Cache key elements

What makes a cached entry unique. The Gateway hashes these inputs to compute the cache key.

{
  "actions": {
    "cacheKeyElements": ["userId", "warehouse", "standardizedSql"]
  }
}
ElementDescriptionUse when
standardizedSqlNormalized SQL textAlways (recommended baseline)
statementOriginal SQL textExact-match scenarios
userIdUser identifierPer-user isolation (RLS)
userRoleUser's roleRole-based sharing
userGroupsUser's groupsGroup-based sharing
warehouseTarget warehouseWarehouse-specific results
warehouseSizeWarehouse size/tierSize-specific caching
catalogCatalog nameCatalog isolation
schemaSchema nameSchema isolation
tablesTable namesTable-aware caching
columnsColumn namesColumn-aware caching
tenantIdTenant identifierMulti-tenant deployments (auto-included for cross-tenant scenarios)

These are included automatically and don't need to be listed: proxyVersion (cache invalidates on Gateway upgrades), sessionState (session vars and catalog/schema context), describeOnly (separates schema queries from data queries), parameterValues (parameter values for parameterized queries).

Invalidation rules (DML)

A rule that matches DML statements (INSERT/UPDATE/DELETE) can name cache rules to invalidate when it fires:

{
  "id": "orders-dml",
  "name": "Orders Table Changes",
  "priority": 5,
  "conditions": {
    "statementType": { "in": ["INSERT","UPDATE","DELETE"] },
    "tables": { "includes": "ORDERS" }
  },
  "actions": {},
  "invalidateRules": ["cache-orders-aggregates","cache-orders-recent"]
}

Pair with "requireInvalidation": true on a cache rule to refuse cache hits if recent invalidation activity can't be confirmed — right default for compliance-critical caches.

Worked example

{
  "id": "cache_customer_data",
  "name": "Cache customer queries per user for 1 hour",
  "description": "Aggregate reads on CUSTOMER, isolated per user (RLS).",
  "enabled": true,
  "priority": 10,
  "mode": "all",
  "conditions": {
    "tables":         { "includes": "CUSTOMER" },
    "statementType":  { "equals": "SELECT" }
  },
  "actions": {
    "cache": { "ttlSeconds": 3600 },
    "cacheKeyElements": ["userId", "warehouse", "standardizedSql"]
  }
}

See also