# Performance and cost

> What every answer tells you about its cost, and the habits that keep queries fast and object-storage reads few.

SkimmerDB keeps every namespace in object storage and uses servers' RAM and disk as a cache.
So the cost and speed of a query depend mostly on two things: whether the namespace is warm,
and how much the query has to read. Every answer tells you both.

## What every answer reports

| Field | Meaning |
|---|---|
| `took_ms` | Time the engine spent on the query. |
| `temperature` | `warm`: the namespace was open. `local`: opened from the server's disk. `cold`: opened from object storage. |
| `store_gets` | Object-storage reads the query made (0 when everything was cached). |
| `store_bytes` | Bytes those reads fetched. |
| `cpu_ms` | CPU the query used. Metered per tenant, not billed. |
| `partial`, `timed_out` | The answer may be incomplete: a storage read failed, or the plan's time limit passed. |

Search, count, vector and SQL answers carry them (warm answers all but `cpu_ms`), and your usage
(`GET /v1/usage`) sums them per day: queries, `store_gets`, `store_bytes`, `cpu_ms`.

## Warm, local, cold

- **Warm** queries read RAM and local disk only. A filtered text search on a small namespace
  answers in well under a millisecond (`"took_ms": 0.41` in the [quickstart](/quickstart)); a
  vector query on 1.3M vectors in under a millisecond.
- **Cold** queries first open the namespace from object storage. A small namespace (a few KB)
  opens in a single read; a bigger one in a round trip or two. A cold vector query without a
  filter or text reads only the clusters it probes, in two rounds, without downloading the
  namespace. Opening a 10M-row namespace from object storage for SQL measured under a second.
- An idle namespace costs nothing but its stored bytes: nothing runs for it until the next
  query.

> **Tip** When an agent is about to start a session on a namespace, warm it first:
> `POST /v1/namespaces/{name}/warm` with the searches it is likely to run. It opens the
> namespace and fetches what those searches need, so the session's first queries are warm.

## Habits that keep queries fast

- **Filter first.** Filters prune the search before any document is read. A selective filter
  (`{"user": "u-17"}`) over a big namespace is the cheapest thing you can add to a query.
- **Give a regex a literal.** `ERR-[0-9]+` and `G-[A-Z0-9]{10}` use the index; `.*[0-9]$` has
  to read every document (refused past 100,000 documents unless you send `"scan": true`).
- **Page with cursors.** Pass `next` back as `cursor`: each page continues where the last
  stopped. In SQL, prefer a `WHERE` on a key or time window to large `OFFSET`s.
- **Count exactly only when you need to.** `count` is exact; on huge namespaces `"exact": false`
  answers from a sample, with a 95% interval.
- **Ask for what you'll show.** `limit` is 20 by default (10 for vector queries); hits return
  the matched line and metadata, not whole documents.
- **Keep namespaces to what a query needs.** A namespace per user or agent stays small and
  opens in one read; one query never has to skip other users' data. Keep together only what
  you aggregate together. See [Choosing namespaces](/guides/data-model#choosing-namespaces).
- **Time windows in SQL.** Store times as integer seconds and filter with `WHERE ts >= ...`:
  blocks outside the window are skipped by their min/max without being read.

## Habits that keep writes cheap

- **Batch.** Up to 10,000 documents (64 MB) a request: one request against your rate limit and
  one atomic entry. Many tiny requests work but use up the rate limit.
- **Import files.** CSV, NDJSON and Parquet go straight into columns, up to 1,000,000 rows a
  request (about 440,000 rows a second for CSV on 8 vCPUs). See [Importing files](/guides/import).
- **Append when you can.** Events written once are the cheapest to store, compact and query;
  every update writes a new version.
- **Use `"wait": true` only when the next step reads what you wrote.**
- **Back off on `429 write_busy`** for `Retry-After` seconds; the clients do it for you.

## Time limits

A search, count or vector query runs at most 10 seconds on free and 30 on pro; SQL has the same
limits. A search past it answers what it found so far (`"timed_out": true`, `"partial": true`);
a count or SQL query fails with `422 query_timeout`. See [Limits and plans](/reference/limits).

## What you pay for

Storage (GB-months as stored), documents and bytes written, queries, and the object-storage
reads cold queries make. CPU is metered and shown, not billed. Current prices:
[skimmerdb.com/pricing](https://skimmerdb.com/pricing).
