Vectors

A vector database and search behind one API. We run it.

PreviewRequest access

Upload and search right away. We run it.

  • npm install @schift-io/sdk
  • pip install schift
filter: year >= 2024topK: 5
  1. sku-12
  2. sku-7
  3. sku-31
  4. sku-4
  5. sku-19

The work around vector search, handled

  1. Run it yourself: Size cluster nodes, memory and shards

    With Schift: One PUT per collection

  2. Run it yourself: Rebuild and tune the ANN index as rows grow

    With Schift: IVF-PQ managed for you

  3. Run it yourself: Embedding queue, retries, token counts

    With Schift: Add ?embed=body

  4. Run it yourself: Hunt down mixed dimensions after a model change

    With Schift: Dimension and model checked per write

  5. Run it yourself: Compact tombstones, clean up old versions

    With Schift: Compaction and cleanup run daily

  6. Run it yourself: Provision instances for peak load

    With Schift: Pay per GB-month stored and per search

Two ways in, one search

A

Your vectors, stored with the record

Any model, several spaces, one request.

import { VectorClient } from "@schift-io/sdk";

const vectors = new VectorClient({
  apiKey: process.env.SCHIFT_API_KEY!,
  dataUrl: "https://gw.schift.io",
});
const where = "custom/catalog/items";
const model = "google/gemini-embedding-2"; // any model; every write asserts it

await vectors.declare(where, {
  embedding: "external",
  vectors: { text: { dimension: 2048, model } },
  metadata: { sku: "string", year: "int64", tags: "string_list" },
});

await vectors.upsert(
  where,
  [{ id: "sku-1", text: "linen shirt, warm beige",
     metadata: { sku: "S1", year: 2025, tags: ["summer"] },
     vectors: { text: embedding } }], // Float32Array goes as base64 f32
  { models: { text: model } },
);

const { hits } = await vectors.search(where, {
  vector: "text",
  queryVector: queryEmbedding,
  query: "linen shirt", // hybrid: cosine + BM25
  filter: { year: { gte: 2024 }, tags: { contains: "summer" } },
  topK: 10,
}); // [{ id, score, scores: { text, keyword }, text, metadata, updatedAt }]

B

Send text, the server embeds it

Write with ?embed=, search with near=.

import { DataClient } from "@schift-io/sdk";

const data = new DataClient({
  apiKey: process.env.SCHIFT_API_KEY!,
  dataUrl: "https://gw.schift.io",
});

await data.declareSchema("custom/support/tickets", [
  { name: "ticket_id", type: "string", nullable: false },
  { name: "body", type: "string", nullable: false },
  { name: "plan", type: "string", nullable: true },
]);

// 202 once the rows are on disk; the body column is embedded right after
await data.put("custom/support/tickets", [
  { ticket_id: "t-81", body: "Refund still pending after 10 days", plan: "pro" },
  { ticket_id: "t-82", body: "Invoice shows the wrong company name", plan: "free" },
], { embed: "body" });

const { rows } = await data.search("custom/support/tickets", {
  near: "late refund",   // the query text is embedded with the same model
  k: 5,
  where: { plan: "pro" },
}); // rows[i]._score = cosine similarity

What search includes

Filter, then top-k

Nearest k among the rows that match.

"filter": {"year": {"gte": 2024}}

Hybrid search

Cosine and BM25, blended by weight.

"query": "linen shirt", "keywordWeight": 0.3

Weighted multi-space search

Text and image, fused by weight.

"weights": {"text": 0.6, "image": 0.4}

Exact re-ranking

Scores recomputed from stored vectors.

scores: {text, image, keyword}

Record-level edits

Upsert, PATCH metadata, delete by filter.

PATCH /v1/vectors/{where}

Operations record

Every search and write lands in _ops/*.

GET /v1/data/_ops/access

49.6 ms at 170,000 records

Two 2,048-d vectors, 15 metadata fields.

Text-space search p50 / p95
49.6 / 59.3 ms
Filtered search p50
80.9 ms
Hybrid (vector + BM25) p50
124.5 ms
Neighbour recall (text / filtered / fused)
0.979 / 1.0 / 1.0

2026-09-24 UTC, one laptop, local MinIO, synthetic vectors.

What it costs, and what is free

  • Storage

    Free every month1 GBfree storage
    Pay as you go$0.30per GB-month
    Monthly commit1 TB, $210/mo$0.21/GB-month
  • Searches

    Free every month100K searchesfree every month
    Pay as you go$16per 1M searches
    Monthly commit100M searches, $1,000/mo$10/M
  • Embedding tokens

    Free every monthFrom the first tokenbilled as used
    Pay as you go$0.025per 1M tokens
Full price table (Vectors)

Compared with other managed vector databases

Schift VectorsPineconeturbopufferQdrant Cloud
Free allowance1 GB free storage, 100K searches free every monthStarter 2 GBFrom Launch $16/moOne cluster
Monthly minimumPay as you goStandard $50/mo$16/moUsage-based
Capacity planningServerlessServerlessServerlessPick cluster size
Storage rate$0.30 per GB-month$0.33/GB/moVia calculatorDisk, billed hourly
Search billed byOne searchRead units (RU)Data queriedCluster resource hours
Write checksDimension + embedding modelIndex dimensionVector column dimensionCollection vector size
Operations recordEvery org, _ops/*Audit Logs: EnterpriseAudit Logs: ScaleUnlisted
Sources (checked 2026-09-27)

FAQ

Which embedding models can I use?

Any model, when you bring the vectors.

How do I change model or dimension?

Declare a new collection at a new where.

How much can one write carry?

10,000 records or 128 MiB per write.

We run the infra. You focus on customers.

One key, search right away.