Guides Markdown

Exporting answers

Get big SQL answers out of SkimmerDB: streamed as NDJSON or CSV, or exported in the background to a file you download, resumably.

A SQL answer as JSON stops at 10,000 rows. Two ways get more out:

WhenHow
StreamThe answer fits the query's time limit (10 s free, 30 s pro)?format=ndjson or ?format=csv on /v1/sql or /v1/namespaces/{name}/sql
ExportBigger or slower: a job in the background, a file kept 24 hoursPOST /v1/sql/exports

Streaming

curl
curl -sN "$B/sql?format=csv" -H "Authorization: Bearer $KEY" \
  -d '{"sql": "SELECT id, customer, amount, placed_at FROM orders WHERE placed_at >= DATE '\''2026-01-01'\''"}' > orders.csv

Rows go out as they're made. A plain scan of one namespace (SELECT ... FROM ns WHERE ...) streams any number of rows in flat memory; joins, groups and sorts are computed first, up to a cap of rows held (at least 1,000,000). See SQL: streamed answers for the formats and how errors show.

Exports

curl -s $B/sql/exports -H "Authorization: Bearer $KEY" \
  -d '{"sql": "SELECT * FROM orders", "format": "csv"}'
# {"id": "ex_5f0c...", "status": "queued", ...}

curl -s $B/sql/exports/ex_5f0c... -H "Authorization: Bearer $KEY"
# {"id": "ex_5f0c...", "status": "done", "rows": 4200000, "bytes": 310442017, "download": "/v1/sql/exports/ex_5f0c.../download", ...}

curl -s -C - -o orders.csv $B/sql/exports/ex_5f0c.../download -H "Authorization: Bearer $KEY"
from skimmerdb import SkimmerDB

db = SkimmerDB()
e = db.wait_export(db.export("SELECT * FROM orders", format="csv").id)
db.download_export(e.id, "orders.csv")        # resumes after a broken transfer
import { SkimmerDB } from "skimmerdb";

const db = new SkimmerDB();
const e = await db.waitExport((await db.export("SELECT * FROM orders", "csv")).id);
const res = await db.downloadExport(e.id);     // downloadExport(id, from) resumes at a byte
  • The job runs the query as a streamed answer does, under a longer time limit (60 s free, 900 s pro), and writes its rows as CSV (a header line, RFC 4180) or NDJSON (an object a row) into object storage under your tenant's own prefix. Status: queued, running (with rows and bytes so far), done, failed (with error), expired. GET /v1/sql/exports lists them.
  • The download streams the file. Range: bytes=first-last (or first-, or -suffix) answers 206 with that part: a broken download resumes where it stopped.
  • Kept 24 hours, then deleted. A server that restarts while an export runs fails it (run it again); a job whose server stops is marked failed within a couple of minutes.
  • Parquet isn't written yet: CSV or NDJSON.
  • Isolation. An export is its tenant's: other tenants get 404, and a key limited to some namespaces sees only the exports it made.

Limits

FreePro
A streamed answer's or an export's rows: a plain scan / other shapesany / at least 1,000,000any / at least 1,000,000
An export's time limit60 s900 s
Exports queued or running at once12
Exports a UTC day10no limit
An export's size1 GB50 GB

Metering. A streamed answer or an export is one query (with what it read and its CPU). The bytes sent back, streamed or downloaded, count as bytes returned; on the free plan (10 GB a month) a stream or download stops when they're used up.