Analytics
A dedicated graph analytics engine per project — Cypher and SQL over your own isolated knowledge graph, with scale-to-zero pricing
Overview
Scalix Analytics gives every project its own dedicated graph analytics engine — not a shared cluster. The first query boots a hardware-isolated microVM for your project (cold start ~2.5s, warm queries in milliseconds); after 5 idle minutes it scales to zero and you stop paying for compute. Your graph lives on a persistent per-project volume, so the data is there when the engine wakes back up.
You can query the same data two ways:
- Cypher — full read-only graph queries (
MATCH, traversals, aggregations) - SQL — basic
SELECTstatements, translated to Cypher by the engine
Analytics is available on Pro plans and above, behind a per-service agreement you accept once in Console → Billing → Services (you can set a monthly spend cap there too, as an alert or a hard stop).
Quick start (60 seconds)
- Open Console → your project → Analytics and enable the service if prompted.
- Go to the Load Data tab and click Load sample — a tiny social graph loads through the real ingest API and the Graph Explorer opens.
- Run your first query:
MATCH (a:Person)-[r:KNOWS]->(b:Person)
RETURN a.name, b.name, r.sinceQuerying via the API
Use a project-scoped API key with the prime:read scope:
curl -X POST https://api.scalix.world/v1/prime/query \
-H "Authorization: Bearer $SCALIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "MATCH (n) RETURN n LIMIT 10", "language": "cypher"}'The response is a QueryResult:
{
"columns": ["n"],
"rows": [{"n": {"_id": "0:0", "_labels": ["Person"], "name": "Ada"}}],
"row_count": 1,
"execution_time_ms": 4.2
}For SQL, set "language": "sql". Only basic SELECT is supported today —
anything the translator can't handle returns an honest
400 SQL_NOT_SUPPORTED rather than wrong results. Writes are rejected with
403 READ_ONLY on the query surface; data enters only through ingest.
Loading data
CSV upload
POST /v1/prime/ingest with a raw CSV body (header row required) and the
prime:write scope. Parameters travel as headers:
| Header | Value |
|---|---|
x-scalix-ingest-kind | nodes or rels |
x-scalix-ingest-label | node table name (for nodes) |
x-scalix-ingest-rel-type | relationship name (for rels) |
x-scalix-ingest-from / x-scalix-ingest-to | endpoint node labels (for rels) |
# nodes.csv: id,name,city
curl -X POST https://api.scalix.world/v1/prime/ingest \
-H "Authorization: Bearer $SCALIX_API_KEY" \
-H "Content-Type: text/csv" \
-H "x-scalix-ingest-kind: nodes" \
-H "x-scalix-ingest-label: Customer" \
--data-binary @nodes.csv
# edges.csv: first two columns are the from-id and to-id
curl -X POST https://api.scalix.world/v1/prime/ingest \
-H "Authorization: Bearer $SCALIX_API_KEY" \
-H "Content-Type: text/csv" \
-H "x-scalix-ingest-kind: rels" \
-H "x-scalix-ingest-rel-type: PURCHASED" \
-H "x-scalix-ingest-from: Customer" \
-H "x-scalix-ingest-to: Product" \
--data-binary @edges.csvRules the loader applies:
- Every value loads as a string (cast in your queries as needed).
- For nodes, the
idcolumn — or the first column if there's noid— becomes the node key. Loading the same key twice fails the upload (INGEST_FAILED), it never silently overwrites. - For relationships, the first two CSV columns are the from/to node keys; any further columns become relationship properties.
- Repeated uploads to the same label append.
Import from your database
One click in the Load Data tab (or POST /v1/prime/import-nova) snapshots
your project's ScalixNova Postgres into the graph: every table becomes a node
label, every foreign key becomes a relationship type
({table}_{column}_{referenced_table}). The API key needs both prime:write
and a database read scope. Poll GET /v1/prime/import-nova/{job_id} for
progress. It's a one-shot snapshot (not continuous sync); re-importing the
same rows fails on duplicate keys by design.
Pricing
Three meters, all visible live in the console (rates come from the billing catalog — what you see there is what bills):
| Meter | Rate | What it measures |
|---|---|---|
| Engine time | $0.08/hour | While your project's engine VM is awake (scales to zero after 5 idle minutes) |
| Graph queries | $0.50 per 1,000 | Each Cypher query response |
| Data ingest | $0.045/GB | Bytes uploaded through ingest or database import |
Illustrative: an evening of exploration costs a few cents; a team project querying all workday ≈ $15–40/month; an always-on integration lands near $300/month — at parity with managed graph databases that never scale to zero.
Limits (v1)
| Limit | Value |
|---|---|
| Upload format | CSV only (header row required, UTF-8) |
| Max upload size | 128 MB per request |
| Graph storage | 2 GB per project (fixed volume; 507 STORAGE_FULL when exceeded) |
| Query surface | Read-only; max query length 10,000 chars |
| Concurrency | One engine per project; a large data load briefly queues queries |
| SQL | Basic SELECT only |
Error codes
| Code | Meaning |
|---|---|
READ_ONLY (403) | Write statement on the query endpoint — use ingest |
SQL_NOT_SUPPORTED (400) | SQL feature outside the supported SELECT subset |
BAD_CSV (400) | Missing/invalid header row or column names |
INGEST_TOO_LARGE (413) | Upload exceeds the per-request cap |
STORAGE_FULL (507) | Project graph volume is full |
INGEST_FAILED (400) | Load rejected by the engine (e.g. duplicate node keys) |
ENGINE_UNAVAILABLE (503) | Engine failed to boot — transient; retry |