Skip to content
Gauge

ax-check.com

SlateDB

slatedb.io

ax-check.com

Checked 1 October 2026

B

81/100

Agents haven’t verified setup

Quickstart installs cleanly in five languages, no pricing page needed

14 of 23 checks passed; the only attention item is a missing Markdown homepage. SlateDB is free Apache 2.0 OSS, so no pricing page exists.

2 fixes to start with

Concrete changes, backed by what we found.

Onboarding

Resolve the blocker that stopped agent setup.

Agents cannot progress through onboarding without human help. Provide an agent-accessible path through authentication and setup.

Docs

Return Markdown when clients request text/markdown.

Homepage returned text/html for a text/markdown request; no Markdown representation offered.

Recorded coding sessions

Same task, 3 models, no slatedb.io account. Recorded 1 October 2026 on Pi.

3 recorded · 2m 24s

2m 24s · recorded

Session findings

Select a finding to see it in context.

piv0.84.2
modelQwen 3.8 Maxcwd/sandbox/repo
Help me build a simple example using SlateDB. Tell me how pricing works, and briefly tell me whether this product will be easy for you to manage. Let me know if you get blocked. If this product has no developer workflow you can act on, say so plainly and stop. Stay light: use the hosted product through its SDK or API. Do not start local service stacks or wait for long-running commands; if the quickstart requires either, say so plainly and stop.
Thinking…

The user wants a simple SlateDB example and asks about pricing, so I need to clarify what SlateDB actually is—it's a cloud-backed embedded LSM key-value database that integrates with object storage like S3 and MinIO. Let me check if there's an existing SlateDB repo or example in the current directory first.

$ pwd; ls -la; cat README* 2>/dev/null | head -50{"content":[{"text":"/sandbox/repo\ntotal 16\ndrwxr-xr-x 3 root root 4096 Sep 18 08:00 .\ndrwxr-xr-x 7 root root 4096 Oct 1 17:27 ..\ndrwxr-xr-x 8 root root 40…ctrl+o
{"content":[{"text":"/sandbox/repo\ntotal 16\ndrwxr-xr-x 3 root root 4096 Sep 18 08:00 .\ndrwxr-xr-x 7 root root 4096 Oct  1 17:27 ..\ndrwxr-xr-x 8 root root 4096 Sep 24 20:05 .git\n-rw-r--r-- 1 root root  408 Sep 18 08:00 .gitignore\n","type":"text"}]}
$ which cargo rustc python3 pip3 curl node 2>/dev/null; echo "---"; cargo --version 2>/dev/null; python3 --version 2>/dev/null{"content":[{"text":"/usr/local/cargo/bin/cargo\n/usr/local/cargo/bin/rustc\n/usr/local/bin/python3\n/usr/local/bin/pip3\n/usr/bin/curl\n/usr/local/bin/node\n--…ctrl+o
{"content":[{"text":"/usr/local/cargo/bin/cargo\n/usr/local/cargo/bin/rustc\n/usr/local/bin/python3\n/usr/local/bin/pip3\n/usr/bin/curl\n/usr/local/bin/node\n---\ncargo 1.83.0 (5ffbef321 2024-10-29)\nPython 3.12.3\n","type":"text"}]}
Thinking…

I need to verify what SlateDB actually is—whether it's a hosted product or an embedded library—so I'm checking if I have network access to look it up.

$ cd /tmp && timeout 25 curl -sS -o /dev/null -w "%{http_code}\n" https://crates.io/api/v1/crates/slatedb 2>&1; echo "exit=$?"{"content":[{"text":"403\nexit=0\n","type":"text"}]}
$ cd /tmp && timeout 25 curl -sS https://crates.io/api/v1/crates/slatedb 2>&1 | head -c 2000; echo; echo "===PYPI==="; timeout 25 curl -sS https://pypi.org/pypi/slatedb/json 2>&1 | head -c 800{"content":[{"text":"\n===PYPI===\n{\"info\":{\"author\":null,\"author_email\":null,\"bugtrack_url\":null,\"classifiers\":[],\"description\":\"# SlateDB Python …ctrl+o
{"content":[{"text":"\n===PYPI===\n{\"info\":{\"author\":null,\"author_email\":null,\"bugtrack_url\":null,\"classifiers\":[],\"description\":\"# SlateDB Python Binding\\n\\n`bindings/python` contains the official UniFFI-based Python package for SlateDB.\\n\\n## Requirements\\n\\n- Python 3.10 or newer\\n\\n## Install\\n\\n```bash\\npip install slatedb\\n```\\n\\n## API Model\\n\\n- `ObjectStore.resolve(...)` opens an object store from a URL such as `memory:///`\\n- `DbBuilder` opens a writable database and `DbReaderBuilder` opens a read-only reader\\n- most database operations are `async` and should be used with `asyncio`\\n- `WriteBatch` is mutated synchronously and then consumed by `db.write(...)`\\n- `db.shutdown()` and `reader.shutdown()` explicitly close native resources\\n\\n## Quick Start\\n\\n```python\\nimport asyncio\\n\\nfrom slatedb.uniffi import (\\n ","type":"text"}]}
Thinking…

Network is partially available (pypi works, crates.io 403 - probably blocked by user agent). Let me check if crates.io works with a user-agent header, and check the pypi package for slatedb (wheels available for linux x86_64?).

Note: SlateDB is an embedded LSM key-value store written in Rust that persists to object storage. It is NOT a hosted product with pricing. So the "pricing" question — SlateDB is open source (Apache-2.0), free. There is no hosted service / pricing page as far as I know. Let me verify by checking their website / GitHub.

Let me test: pip install slatedb (needs wheel for platform), and check crates.io with user-agent.

$ cd /tmp && timeout 30 curl -sS -A "pi-agent/1.0 (sandbox)" https://crates.io/api/v1/crates/slatedb 2>&1 | python3 -c "import sys,json; d=json.load(sys.stdin); c=d['crate']; print(c['name'], c['max_sta…{"content":[{"text":"Traceback (most recent call last):\n File \"<string>\", line 1, in <module>\nKeyError: 'license'\n","type":"text"}]}ctrl+o
cd /tmp && timeout 30 curl -sS -A "pi-agent/1.0 (sandbox)" https://crates.io/api/v1/crates/slatedb 2>&1 | python3 -c "import sys,json; d=json.load(sys.stdin); c=d['crate']; print(c['name'], c['max_stable_version'], c['license'], c['repository'], c['homepage'], c['downloads'])" 2>&1 | head -5

$ cd /tmp && timeout 30 curl -sS https://pypi.org/pypi/slatedb/json 2>/dev/null | python3 -c "{"content":[{"text":"version: 0.17.0\nlicense: None\nrequires_python: >=3.10\nurls: []\nreleases: ['0.6.1', '0.7.0', '0.8.0', '0.8.1', '0.9.0', '0.9.2']\n","typ…ctrl+o
cd /tmp && timeout 30 curl -sS https://pypi.org/pypi/slatedb/json 2>/dev/null | python3 -c "
import sys,json
d=json.load(sys.stdin)
i=d['info']
print('version:',i['version'])
print('license:',i.get('license'))
print('requires_python:',i.get('requires_python'))
print('urls:',[u['filename'] for u in i.get('urls',[])][:20])
print('releases:',sorted(d['releases'].keys())[-6:])
"

{"content":[{"text":"version: 0.17.0\nlicense: None\nrequires_python: >=3.10\nurls: []\nreleases: ['0.6.1', '0.7.0', '0.8.0', '0.8.1', '0.9.0', '0.9.2']\n","type":"text"}]}
Thinking…

Let me get details. crates.io responded (KeyError means JSON parsed but key missing—probably 'license' is under crate as 'license'? Let me print full). Also check pypi files for wheels for linux x86_64 (need to check releases[0.17.0] filenames).

Also check whether slatedb is a hosted product at all — check slatedb.io website.

$ cd /tmp && timeout 30 curl -sS -A "pi-agent/1.0" https://crates.io/api/v1/crates/slatedb 2>/dev/null | python3 -c "{"content":[{"text":"name = slatedb\nmax_stable_version = 0.17.0\nlicense = None\nrepository = https://github.com/slatedb/slatedb\nhomepage = https://slatedb.io…ctrl+o
cd /tmp && timeout 30 curl -sS -A "pi-agent/1.0" https://crates.io/api/v1/crates/slatedb 2>/dev/null | python3 -c "
import sys,json; d=json.load(sys.stdin); c=d.get('crate',d)
for k in ('name','max_stable_version','license','repository','homepage','description','downloads','documentation'):
    print(k,'=',c.get(k))
" 2>&1 | head -20

{"content":[{"text":"name = slatedb\nmax_stable_version = 0.17.0\nlicense = None\nrepository = https://github.com/slatedb/slatedb\nhomepage = https://slatedb.io\ndescription = A cloud native embedded storage engine built on object storage.\ndownloads = 1535754\ndocumentation = None\n","type":"text"}]}
$ cd /tmp && timeout 30 curl -sS https://pypi.org/pypi/slatedb/json 2>/dev/null | python3 -c "{"content":[{"text":"slatedb-0.17.0-py3-none-macosx_11_0_arm64.whl 9088240\nslatedb-0.17.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 10506645\ns…ctrl+o
cd /tmp && timeout 30 curl -sS https://pypi.org/pypi/slatedb/json 2>/dev/null | python3 -c "
import sys,json; d=json.load(sys.stdin)
for f in d['releases']['0.17.0']: print(f['filename'], f['size'])
print('--- 0.9.2 ---')
for f in d['releases']['0.9.2']: print(f['filename'], f['size'])
"

{"content":[{"text":"slatedb-0.17.0-py3-none-macosx_11_0_arm64.whl 9088240\nslatedb-0.17.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 10506645\nslatedb-0.17.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 9861833\nslatedb-0.17.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl 11077448\nslatedb-0.17.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 11480253\nslatedb-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 10565492\nslatedb-0.17.0-py3-none-musllinux_1_2_aarch64.whl 10731527\nslatedb-0.17.0-py3-none-musllinux_1_2_armv7l.whl 10090715\nslatedb-0.17.0-py3-none-musllinux_1_2_i686.whl 10772065\nslatedb-0.17.0-py3-none-musllinux_1_2_x86_64.whl 10942403\nslatedb-0.17.0-py3-none-win32.whl 8168230\nslatedb-0.17.0-py3-none-win_amd64.whl 9263577\nslatedb-0.17.0.tar.gz 1108783\n--- 0.9.2 ---\nslatedb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7651103\nslatedb-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7281383\nslatedb-0.9.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl 8128613\nslatedb-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8718608\nslatedb-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl 7147007\nslatedb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 7530910\nslatedb-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl 7820960\nslatedb-0.9.2-cp310-cp310-musllinux_1_2_armv7l.whl 7511866\nslatedb-0.9.2-cp310-cp310-musllinux_1_2_i686.whl 7895645\nslatedb-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl 7817276\nslatedb-0.9.2-cp311-cp311-macosx_10_12_x86_64.whl 7121181\nslatedb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl 6923995\nslatedb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7651086\nslatedb-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7279468\nslatedb-0.9.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl 8126839\nslatedb-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8714250\nslatedb-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl 7147804\nslatedb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 7531148\nslatedb-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl 7821068\nslatedb-0.9.2-cp311-cp311-musllinux_1_2_armv7l.whl 7508887\nslatedb-0.9.2-cp311-cp311-musllinux_1_2_i686.whl 7893852\nslatedb-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl 7817068\nslatedb-0.9.2-cp312-cp312-macosx_10_12_x86_64.whl 7117779\nslatedb-0.9.2-cp312-cp312-macosx_11_0_arm64.whl 6921333\nslatedb-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7651827\nslatedb-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7278223\nslatedb-0.9.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl 8131398\nslatedb-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8722313\nslatedb-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl 7155719\nslatedb-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 7543683\nslatedb-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl 7822080\nslatedb-0.9.2-cp312-cp312-musllinux_1_2_armv7l.whl 7508050\nslatedb-0.9.2-cp312-cp312-musllinux_1_2_i686.whl 7894249\nslatedb-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl 7826892\nslatedb-0.9.2-cp313-cp313-macosx_10_12_x86_64.whl 7117985\nslatedb-0.9.2-cp313-cp313-macosx_11_0_arm64.whl 6920995\nslatedb-0.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7651827\nslatedb-0.9.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7279039\nslatedb-0.9.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl 8130838\nslatedb-0.9.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8721709\nslatedb-0.9.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl 7156118\nslatedb-0.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 7543608\nslatedb-0.9.2-cp313-cp313-musllinux_1_2_aarch64.whl 7822413\nslatedb-0.9.2-cp313-cp313-musllinux_1_2_armv7l.whl 7508900\nslatedb-0.9.2-cp313-cp313-musllinux_1_2_i686.whl 7894238\nslatedb-0.9.2-cp313-cp313-musllinux_1_2_x86_64.whl 7827741\nslatedb-0.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7650646\nslatedb-0.9.2-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7220857\nslatedb-0.9.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8729154\nslatedb-0.9.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl 7162935\nslatedb-0.9.2-cp313-cp313t-musllinux_1_2_aarch64.whl 7819927\nslatedb-0.9.2-cp313-cp313t-musllinux_1_2_armv7l.whl 7449902\nslatedb-0.9.2-cp313-cp313t-musllinux_1_2_i686.whl 7834833\nslatedb-0.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl 7825717\nslatedb-0.9.2-cp314-cp314-macosx_11_0_arm64.whl 6917494\nslatedb-0.9.2-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7647411\nslatedb-0.9.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7278645\nslatedb-0.9.2-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl 8131036\nslatedb-0.9.2-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8718121\nslatedb-0.9.2-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl 7154623\nslatedb-0.9.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 7539429\nslatedb-0.9.2-cp314-cp314-musllinux_1_2_aarch64.whl 7817850\nslatedb-0.9.2-cp314-cp314-musllinux_1_2_armv7l.whl 7506714\nslatedb-0.9.2-cp314-cp314-musllinux_1_2_i686.whl 7895744\nslatedb-0.9.2-cp314-cp314-musllinux_1_2_x86_64.whl 7822192\nslatedb-0.9.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7650770\nslatedb-0.9.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7221827\nslatedb-0.9.2-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8716689\nslatedb-0.9.2-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl 7161021\nslatedb-0.9.2-cp314-cp314t-musllinux_1_2_aarch64.whl 7818158\nslatedb-0.9.2-cp314-cp314t-musllinux_1_2_armv7l.whl 7449807\nslatedb-0.9.2-cp314-cp314t-musllinux_1_2_i686.whl 7836257\nslatedb-0.9.2-cp314-cp314t-musllinux_1_2_x86_64.whl 7824436\nslatedb-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7648699\nslatedb-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7279185\nslatedb-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8719538\nslatedb-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl 7149647\nslatedb-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl 7819301\nslatedb-0.9.2-pp310-pypy310_pp73-musllinux_1_2_armv7l.whl 7505790\nslatedb-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl 7883813\nslatedb-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl 7826059\nslatedb-0.9.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 7648896\nslatedb-0.9.2-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl 7279433\nslatedb-0.9.2-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl 8116526\nslatedb-0.9.2-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl 8719155\nslatedb-0.9.2-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl 7148967\nslatedb-0.9.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 7541642\nslatedb-0.9.2-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl 7818553\nslatedb-0.9.2-pp311-pypy311_pp73-musllinux_1_2_armv7l.whl 7505552\nslatedb-0.9.2-pp311-pypy311_pp73-musllinux_1_2_i686.whl 7883844\nslatedb-0.9.2-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl 7825997\nslatedb-0.9.2.tar.gz 469289\n","type":"text"}]}
Thinking…

Good. SlateDB has prebuilt wheels for linux x86_64, so a Python quickstart works without building from source. And it's an embedded library — no local service stack needed if using the in-memory object store (memory:///).

Now: pricing. SlateDB is open source (Apache-2.0), hosted product? Let me check slatedb.io for a pricing page. Historically, SlateDB Inc. planned a managed/hosted offering but I'm not sure it exists publicly. Let me fetch slatedb.io and check for pricing.

Let me also verify the pip install works and run a quickstart.

$ cd /tmp && timeout 30 curl -sSL https://slatedb.io/ 2>&1 | python3 -c "{"content":[{"text":"LINKS: ['/favicon.svg', 'https://slatedb.io/', '/index.md', 'https://fonts.googleapis.com', 'https://fonts.gstatic.com', 'https://fonts.goo…ctrl+o
cd /tmp && timeout 30 curl -sSL https://slatedb.io/ 2>&1 | python3 -c "
import sys,re,html
t=sys.stdin.read()
t=re.sub(r'<script.*?</script>','',t,flags=re.S)
t=re.sub(r'<style.*?</style>','',t,flags=re.S)
links=re.findall(r'href=\"([^\"]+)\"',t)
txt=re.sub(r'<[^>]+>',' ',t); txt=html.unescape(re.sub(r'\s+',' ',txt))
print('LINKS:', links[:40])
print('TEXT:', txt[:1500])
"

{"content":[{"text":"LINKS: ['/favicon.svg', 'https://slatedb.io/', '/index.md', 'https://fonts.googleapis.com', 'https://fonts.gstatic.com', 'https://fonts.googleapis.com/css2?family=Marcellus&family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,500;0,8..60,600;0,8..60,700;1,8..60,400;1,8..60,500;1,8..60,600;1,8..60,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap', '/_astro/index.CjTHiM0L.css', '/', '/docs/get-started/introduction/', '/blog/', 'https://discord.gg/mHYmGy5MgA', 'https://github.com/slatedb/slatedb', '/docs/get-started/introduction/', '/blog/', 'https://discord.gg/mHYmGy5MgA', 'https://github.com/slatedb/slatedb', '/docs/get-started/introduction/', 'https://github.com/slatedb/slatedb', 'https://www.dropbox.com/', 'https://www.prisma.io/', 'https://www.helix-db.com/', 'https://www.tensorlake.ai/', 'https://s2.dev/', 'https://goldsky.com/', 'https://gadget.dev/', 'https://merklemap.com/', 'https://opendata.dev/', 'https://massive.com/', '/docs/get-started/quickstart/', '/docs/operations/configuration/', 'https://github.com/slatedb/slatedb/blob/main/LICENSE', '/docs/design/overview/', '/docs/design/readers/', '/docs/design/consistency/', '/docs/operations/tuning/', '/docs/design/clones/', '/docs/design/overview/', '/docs/design/readers/', '/docs/design/consistency/', '/docs/operations/tuning/']\nTEXT:  SlateDB — An embedded database built on object storage docs blog discord github ★ 3.5k docs blog discord github ★ 3.5k Build reliably on object storage. SlateDB is an OSS embedded key-value database and LSM-engine built on object storage. Read the docs GitHub SlateDB brings the durability, consistency, and economics of object storage to your online systems without sacrificing performance or paying per-request API costs. clients → Rust Go OpenJDK Node.js Python Rust core with Go, Java, Node & Python bindings. object storage → Amazon Web Services Cloudflare Google Cloud Runs on S3, R2, GCS & most object stores. license → Apache Apache 2.0 free and open source. the engine Fig. 1 ref /docs/design/overview/ → Fig. 2 ref /docs/design/readers/ → Fig. 3 ref /docs/design/consistency/ → Fig. 4 ref /docs/operations/tuning/ → Fig. 5 ref /docs/design/clones/ → Zero-disk architecture Persist data directly to object storage. Keep 99.999999999% durability and cost profile of S3-class storage without local disks or cross-AZ storage traffic. ref /docs/design/overview/ → Flexible deployment SlateDB ensures a single writer through a formally verified manifest fencing protocol but supports multiple readers for read-side scaling. Compaction can run embedded or as a separate process to enforce separation of concerns. ref /docs/design/readers/ → Transactional semantics Transactions, snapshots, and optimistic concurrency control mechanisms ensure that SlateDB is suitable for the most demanding trans\n","type":"text"}]}
$ cd /tmp && for u in https://slatedb.io/pricing https://slatedb.io/pricing/ https://www.slatedb.io/pricing; do echo "== $u"; timeout 20 curl -sS -o /dev/null -w "%{http_code}\n" -L "$u" 2>&1; done{"content":[{"text":"== https://slatedb.io/pricing\n404\n== https://slatedb.io/pricing/\n404\n== https://www.slatedb.io/pricing\n404\n","type":"text"}]}
Thinking…

Confirmed: SlateDB is OSS (Apache 2.0), no hosted product, no pricing page (404). There's no managed/hosted SlateDB service publicly — so "pricing" = free; your only cost is object storage you bring (S3/GCS/R2) requests + storage. I should say plainly: no pricing exists because there's no hosted/paid product.

Now the quickstart: check docs quickstart page for Python to follow official API. Then write example and run it. The user said stay light: use SDK/API, no local service stacks, no long-running commands. In-memory object store works with zero infra. Let me fetch the quickstart docs.

$ cd /tmp && timeout 30 curl -sSL https://slatedb.io/docs/get-started/quickstart/ 2>/dev/null | python3 -c "{"content":[{"text":" Quick Start | SlateDB Skip to content SlateDB Search Ctrl K Cancel Docs Blog GitHub Discord Getting Started Introduction Quick Start FAQ D…ctrl+o
cd /tmp && timeout 30 curl -sSL https://slatedb.io/docs/get-started/quickstart/ 2>/dev/null | python3 -c "
import sys,re,html
t=sys.stdin.read()
t=re.sub(r'<script.*?</script>','',t,flags=re.S); t=re.sub(r'<style.*?</style>','',t,flags=re.S)
txt=html.unescape(re.sub(r'\s+',' ',re.sub(r'<[^>]+>',' ',t)))
print(txt[:3000])
"

{"content":[{"text":" Quick Start | SlateDB Skip to content SlateDB Search Ctrl K Cancel Docs Blog GitHub Discord Getting Started Introduction Quick Start FAQ Design Overview Files SSTs Writes Reads Readers Compaction Segmented Compaction Merge Operators Garbage Collection Change Data Capture Caching Checkpoints Compression Block Transforms Clones Time Consistency Operations CLI Compatibility Configuration Configuring Foyer Cache Data Modeling Errors Logging Metrics Tuning Benchmarks Tutorials Connect to Azure Blob Storage Connect to S3 Connect to Google Cloud Storage Range Scans Checkpoint & Restore Standalone Compactor Standalone Garbage Collector API Reference Go Java Node Python Rust RFCs RFC 0001: Manifest Design RFC 0002: Compaction RFC 0003: Timestamps & Time-To-Live RFC 0004: Checkpoints and Clones RFC 0005: Range Scans RFC 0006: Merge Operator RFC 0007: Error API RFC 0008: Synchronous Commit & Durability RFC 0009: Separate Object Store for WAL RFC 0010: Settings design RFC 0011: Transaction RFC 0012: Tracking Timestamps for Sequence Numbers RFC 0013: Compaction State Persistence RFC 0014: Persistence format for the write-ahead log (WAL) RFC 0016: Custom Comparators RFC 0017: Compaction Filters RFC 0018: Expose Row Information RFC 0019: Streaming and Change Data Capture (CDC) RFC 0020: Range Metadata and Size Estimation RFC 0021: Metrics RFC 0022: Prefix Bloom Filters via Pluggable Filter Policies RFC 0023: Targeted Cache Warming and Best-Effort Block Cache Eviction RFC 0024: RFC: Segment-Oriented Compaction RFC 0025: Distributed Compaction RFC 0026: Garbage Collector Boundary Files for Sequenced Metadata RFC 0027: Decoupled Pluggable Object Store Cache RFC 0028: Subcompactions RFC 0029: GC-Safe SST ULID Timestamps RFC 0030: Pluggable WAL RFC 0031: Block Cache Policy RFC 0032: Cached Probing for Sequenced Metadata RFC 0033: Query Tracing RFC 0034: Add ObjectStoreMirror SlateDB — online slatedb/slatedb 3.5k Introduction GitHub Discord Select theme Dark Light Auto On this page Overview Installation Usage Copy as Markdown Copied On this page Overview Installation Usage Quick Start Get started with SlateDB in minutes SlateDB is implemented in Rust and ships official bindings for Go, Java, Node.js, and Python. Pick your language below to install the library and run a minimal example backed by an in-memory object store. Installation Section titled “Installation” Rust Go Java Node.js Python Terminal window cargo add slatedb tokio --features tokio/macros,tokio/rt-multi-thread Terminal window go get slatedb.io/slatedb-go The Go binding uses cgo and links against the slatedb_uniffi shared library. You need Go 1.25+, CGO_ENABLED=1 , a C toolchain, and the slatedb_uniffi library on your loader path. Gradle: dependencies { implementation(\"io.slatedb:slatedb-uniffi:<version>\") } \")}\"> Maven: < dependency > < groupId >io.slatedb</ groupId > < artifactId >slatedb-uniffi</ artifactId > < version > &lt; version &gt; </ version > </ dependency >  io.slatedb  slatedb-uniffi \n","type":"text"}]}
$ cd /tmp && timeout 30 curl -sSL https://slatedb.io/index.md 2>/dev/null | head -60; echo "=== docs index"; timeout 20 curl -sSL "https://slatedb.io/docs/get-started/quickstart/index.md" 2>/dev/null | …{"content":[{"text":"# SlateDB\n\n> SlateDB is an embedded key-value storage engine built on object storage.\n\nSlateDB is an open-source (Apache-2.0) embedded …ctrl+o
cd /tmp && timeout 30 curl -sSL https://slatedb.io/index.md 2>/dev/null | head -60; echo "=== docs index"; timeout 20 curl -sSL "https://slatedb.io/docs/get-started/quickstart/index.md" 2>/dev/null | head -80

{"content":[{"text":"# SlateDB\n\n> SlateDB is an embedded key-value storage engine built on object storage.\n\nSlateDB is an open-source (Apache-2.0) embedded key-value database, implemented\nas an LSM tree, that depends on object storage alone for durability — Amazon S3,\nGoogle Cloud Storage, Azure Blob Storage, MinIO, and Cloudflare R2. It is built\nin async Rust with bindings for Rust, Go, Java, Node, and Python.\n\nIt is the natural, object-native successor to RocksDB. \"Diskless\" systems that\ndelegate durability to object storage are the future of database systems: the\neconomics are phenomenal, object storage provides 99.999999999% durability and\nhandles replication for you, and data written once can be read by an arbitrary\nnumber of readers without additional ETL. SlateDB brings those properties to\nonline, low-latency workloads.\n\n## When to use SlateDB\n\nSlateDB is a **library**, not a server or a hosted service. It ships as an\nembedded engine with no HTTP server; you link it into your own application and\nit communicates directly with the object store you configure.\n\nYou can use it as:\n\n- The storage core inside any data system (e.g.  database, cache, stream\n  processor, or workflow engine) you are building.\n- A cheap, elastic, object-native replacement for local-disk LSM engines like\n  RocksDB, WiredTiger, or Pebble.\n- Durable state for stateless or serverless compute where attaching and\n  replicating local disks is impractical.\n- Single-writer, multi-reader deployments that scale reads independently of\n  writes over a shared bucket.\n\n## When not to use SlateDB\n\n- You need single-digit-microsecond reads/writes. Object storage request\n  latencies are an order of magnitude higher (~50–100ms per request); SlateDB\n  batches writes and caches reads to amortize this, but it does not match a\n  local NVMe engine on raw latency.\n- You need SQL, a query planner, or a relational schema — SlateDB is a\n  key-value / LSM engine that exposes a small byte-oriented API and does not\n  enforce schemas or serialization.\n\n## Key features\n\n- **Object-store native** — durability comes from object storage alone; no\n  disk of record and no replication for you to manage. A local disk is\n  optional and used only as cache.\n- **Cheap and durable** — inherits object storage's ~11 nines of durability at\n  a fraction of the cost of replicated block storage or NVMe.\n- **Transactions & snapshot isolation.**\n- **Single-writer, multi-reader** — open as many readers as you want against\n  the same bucket, isolated from the writer.\n- **Checkpoints & forks** — O(1) branching by marking a manifest as retained.\n- **Rescaling via views** — split a database by key range as an O(1) manifest\n  view instead of copying data.\n- **Pluggable, distributed compaction** — run compaction on separate machines\n  so it never contends with production traffic.\n- **Multi-language** — async Rust core with Go, Java, Node, and Python bindings.\n\n=== docs index\n<!DOCTYPE html><html lang=\"en\" class=\"astro-zetdm5md\"> <head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>404 — page not found | SlateDB</title><link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\"><meta name=\"description\" content=\"The page you're looking for isn't here.\"><meta name=\"robots\" content=\"noindex\"><link rel=\"preconnect\" href=\"https://fonts.googleapis.com\"><link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin><link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Marcellus&family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,500;0,8..60,600;0,8..60,700;1,8..60,400;1,8..60,500;1,8..60,600;1,8..60,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap\"><script async src=\"https://www.googletagmanager.com/gtag/js?id=G-NZVNL1PGYN\"></script> <script>(function(){const GA_MEASUREMENT_ID = \"G-NZVNL1PGYN\";\n\n\twindow.dataLayer = window.dataLayer || [];\n\tfunction gtag() {\n\t\tdataLayer.push(arguments);\n\t}\n\tgtag('js', new Date());\n\tgtag('config', GA_MEASUREMENT_ID);\n})();</script><style>a:where(.astro-dv46nlzh){color:var(--sl-social-icon-color);padding:.5em;margin:-.5em;display:inline-flex;align-items:center;justify-content:center;position:relative}.sr-only:where(.astro-dv46nlzh){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border-width:0;z-index:-1;left:0;top:0}.social-icon:where(.astro-dv46nlzh){display:inline-flex;align-items:center;justify-content:center;width:var(--sl-social-icon-size, 1.5rem);height:var(--sl-social-icon-size, 1.5rem);flex-shrink:0}.social-icon:where(.astro-dv46nlzh) svg:where(.astro-dv46nlzh){width:100%;height:100%;fill:currentColor}a:where(.astro-dv46nlzh):hover .social-icon:where(.astro-dv46nlzh) svg:where(.astro-dv46nlzh){fill:var(--sl-social-icon-hover-color)}\n</style>\n<link rel=\"stylesheet\" href=\"/_astro/404.KhL261W5.css\"><script type=\"module\" src=\"/_astro/page.EAfesrhc.js\"></script></head> <body class=\"astro-zetdm5md\"> <script>\n    // This ensures that the theme is always dark on the website.\n    // We don't support light mode because the Rive animation\n    // doesn't look good in light mode since the background\n    // is hardcoded to white.\n    document.documentElement.dataset.theme = 'light'\n</script> <div class=\"page astro-zetdm5md\"> <header class=\"header astro-zetdm5md\"> <div class=\"header-content astro-zetdm5md\"> <a href=\"/\" class=\"site-title astro-zetdm5md\"> <img src=\"/img/logo-full.svg\" alt=\"SlateDB\" class=\"astro-zetdm5md\"> </a> <div class=\"right-group astro-zetdm5md\"> <nav class=\"header-links astro-zetdm5md\"> <a href=\"/docs/get-started/introduction/\" class=\"header-link astro-zetdm5md\">docs</a> <a href=\"https://discord.gg/mHYmGy5MgA\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"header-link astro-zetdm5md\">discord</a> <a href=\"https://github.com/slatedb/slatedb\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"header-link astro-zetdm5md\" id=\"github-link\">github <span class=\"star-count astro-zetdm5md\"><span class=\"star-icon astro-zetdm5md\">★</span>3.5k</span></a> </nav> <button class=\"mobile-menu-toggle astro-zetdm5md\" id=\"mobile-menu-toggle\" aria-label=\"Toggle menu\" aria-expanded=\"false\"> <span class=\"menu-icon menu-icon-bars astro-zetdm5md\"><?xml version=\"1.0\" encoding=\"UTF-8\"?><svg id=\"Bars\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><rect x=\"1\" y=\"11\" width=\"22\" height=\"2\"/><rect x=\"1\" y=\"19\" width=\"22\" height=\"2\"/><rect x=\"1\" y=\"3\" width=\"22\" height=\"2\"/></svg></span> <span class=\"menu-icon menu-icon-times astro-zetdm5md\"><?xml version=\"1.0\" encoding=\"UTF-8\"?><svg id=\"Times\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><polygon points=\"14 13 15 13 15 14 16 14 16 15 17 15 17 16 18 16 18 17 19 17 19 18 20 18 20 19 21 19 21 20 22 20 22 21 21 21 21 22 20 22 20 21 19 21 19 20 18 20 18 19 17 19 17 18 16 18 16 17 15 17 15 16 14 16 14 15 13 15 13 14 11 14 11 15 10 15 10 16 9 16 9 17 8 17 8 18 7 18 7 19 6 19 6 20 5 20 5 21 4 21 4 22 3 22 3 21 2 21 2 20 3 20 3 19 4 19 4 18 5 18 5 17 6 17 6 16 7 16 7 15 8 15 8 14 9 14 9 13 10 13 10 11 9 11 9 10 8 10 8 9 7 9 7 8 6 8 6 7 5 7 5 6 4 6 4 5 3 5 3 4 2 4 2 3 3 3 3 2 4 2 4 3 5 3 5 4 6 4 6 5 7 5 7 6 8 6 8 7 9 7 9 8 10 8 10 9 11 9 11 10 13 10 13 9 14 9 14 8 15 8 15 7 16 7 16 6 17 6 17 5 18 5 18 4 19 4 19 3 20 3 20 2 21 2 21 3 22 3 22 4 21 4 21 5 20 5 20 6 19 6 19 7 18 7 18 8 17 8 17 9 16 9 16 10 15 10 15 11 14 11 14 13\"/></svg></span> </button> </div> <div class=\"mobile-menu astro-zetdm5md\" id=\"mobile-menu\"> <a href=\"/docs/get-started/introduction/\" class=\"mobile-menu-link astro-zetdm5md\">docs</a> <a href=\"https://discord.gg/mHYmGy5MgA\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mobile-menu-link astro-zetdm5md\">discord</a> <a href=\"https://github.com/slatedb/slatedb\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mobile-menu-link astro-zetdm5md\" id=\"mobile-github-link\">github <span class=\"star-count astro-zetdm5md\"><span class=\"star-icon astro-zetdm5md\">★</span>3.5k</span></a> </div> </div> </header> <main class=\"astro-zetdm5md\"> <section class=\"hero astro-zetdm5md\"> <div class=\"hero-art astro-zetdm5md\" aria-hidden=\"true\"> <img src=\"/img/slatedb-sisyphus.png\" alt=\"\" width=\"1122\" height=\"1402\" loading=\"eager\" decoding=\"async\" class=\"astro-zetdm5md\"> </div> <div class=\"hero-text astro-zetdm5md\"> <div class=\"error-num astro-zetdm5md\">404</div> <p class=\"hero-sub astro-zetdm5md\">\nThe page you're looking for may never exist.\n</p> <div class=\"hero-ctas astro-zetdm5md\"> <a class=\"cta cta-primary astro-zetdm5md\" href=\"/\">Home</a> <a class=\"cta cta-secondary astro-zetdm5md\" href=\"/docs/get-started/introduction/\"> <span class=\"astro-zetdm5md\">Docs</span> </a> </div> </div> </section> </main> <footer class=\"footer astro-zetdm5md\"> <div class=\"footer-content astro-zetdm5md\"> <div class=\"footer-icons astro-zetdm5md\"> <a href=\"/docs/get-started/introduction/\" rel=\"me\" class=\"sl-flex astro-dv46nlzh\"><span class=\"sr-only astro-dv46nlzh\">Introduction</span><span class=\"social-icon astro-dv46nlzh\"><?xml version=\"1.0\" encoding=\"UTF-8\"?><svg id=\"Book_Heart\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><polygon points=\"18 6 18 9 17 9 17 10 16 10 16 11 15 11 15 12 14 12 14 13 13 13 13 14 12 14 12 13 11 13 11 12 10 12 10 11 9 11 9 10 8 10 8 9 7 9 7 6 8 6 8 5 11 5 11 6 12 6 12 7 13 7 13 6 14 6 14 5 17 5 17 6 18 6\"/><path d=\"m20,17h1v-1h1V2h-1v-1H4v1h-1v1h-1v18h1v1h1v1h17v-1h1v-1h-1v-1h-1v-3Zm-2,4H5v-1h-1v-2h1v-1h13v4ZM4,3h16v12H4V3Z\"/></svg></span></a><a href=\"https://github.com/slatedb/slatedb\" rel=\"me\" class=\"sl-flex astro-dv46nlzh\"><span class=\"sr-only astro-dv46nlzh\">GitHub</span><span class=\"social-icon astro-dv46nlzh\"><?xml version=\"1.0\" encoding=\"UTF-8\"?><svg id=\"Github\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><polygon points=\"23 9 23 15 22 15 22 17 21 17 21 19 20 19 20 20 19 20 19 21 18 21 18 22 16 22 16 23 15 23 15 18 14 18 14 17 15 17 15 16 17 16 17 15 18 15 18 14 19 14 19 9 18 9 18 6 16 6 16 7 15 7 15 8 14 8 14 7 10 7 10 8 9 8 9 7 8 7 8 6 6 6 6 9 5 9 5 14 6 14 6 15 7 15 7 16 9 16 9 18 7 18 7 17 6 17 6 16 4 16 4 17 5 17 5 19 6 19 6 20 9 20 9 23 8 23 8 22 6 22 6 21 5 21 5 20 4 20 4 19 3 19 3 17 2 17 2 15 1 15 1 9 2 9 2 7 3 7 3 5 4 5 4 4 5 4 5 3 7 3 7 2 9 2 9 1 15 1 15 2 17 2 17 3 19 3 19 4 20 4 20 5 21 5 21 7 22 7 22 9 23 9\"/></svg></span></a><a href=\"https://discord.gg/mHYmGy5MgA\" rel=\"me\" class=\"sl-flex astro-dv46nlzh\"><span class=\"sr-only astro-dv46nlzh\">Discord</span><span class=\"social-icon astro-dv46nlzh\"><svg id=\"Discord\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M22,11V8H21V6H20V5H18V4H15V5H9V4H6V5H4V6H3V8H2v3H1v7H3v1H5v1H7V18H6V17H8v1H9v1h6V18h1V17h2v1H17v2h2V19h2V18h2V11ZM9,15H7V14H6V12H7V11H9v1h1v2H9Zm9-1H17v1H15V14H14V12h1V11h2v1h1Z\"/></svg></span></a> </div> <div class=\"copyright-wrapper astro-zetdm5md\"> <p class=\"astro-zetdm5md\"> <img src=\"https://raw.githubusercontent.com/commonhaus/artwork/main/foundation/brand/svg/CF_logo_horizontal_single_default.svg\" height=\"20\" alt=\"Commonhaus Foundation\" class=\"astro-zetdm5md\"><br class=\"astro-zetdm5md\">\nCopyright © <a href=\"https://slatedb.io\" class=\"astro-zetdm5md\">SlateDB</a>. All rights reserved. For details on our trademarks, please visit our <a href=\"https://www.commonhaus.org/policies/trademark-policy/\" class=\"astro-zetdm5md\">Trademark Policy</a> and <a href=\"https://www.commonhaus.org/trademarks/\" class=\"astro-zetdm5md\">Trademark List</a>.<br class=\"astro-zetdm5md\">\nTrademarks of third parties are owned by their respective holders and their mention here does not suggest any endorsement or association.\n</p> </div> </div> </footer> </div>  <script type=\"module\">const o=e=>{document.readyState===\"loading\"?document.addEventListener(\"DOMContentLoaded\",e):e()};o(()=>{const e=document.getElementById(\"mobile-menu-toggle\"),t=document.getElementById(\"mobile-menu\");e&&t&&(e.addEventListener(\"click\",()=>{const n=e.getAttribute(\"aria-expanded\")===\"true\";e.setAttribute(\"aria-expanded\",(!n).toString()),t.classList.toggle(\"open\",!n)}),t.querySelectorAll(\".mobile-menu-link\").forEach(n=>{n.addEventListener(\"click\",()=>{e.setAttribute(\"aria-expanded\",\"false\"),t.classList.remove(\"open\")})}))});</script></body></html>","type":"text"}]}
Thinking…

Confirmed: SlateDB is a library, not a hosted service. No pricing page (404), Apache-2.0 OSS.

Now get the Python quickstart usage section from the docs, then install and run. Let me extract the Python section of the quickstart page more fully.

$ cd /tmp && timeout 30 curl -sSL https://slatedb.io/docs/get-started/quickstart/ 2>/dev/null > qs.html; python3 - <<'EOF'{"content":[{"text":"-----\ncargo add slatedb tokio --features tokio/macros,tokio/rt-multi-thread\n-----\npackage main\nimport ( \"bytes\" \"fmt\"\n sl…ctrl+o
cd /tmp && timeout 30 curl -sSL https://slatedb.io/docs/get-started/quickstart/ 2>/dev/null > qs.html; python3 - <<'EOF'
import re,html
t=open('/tmp/qs.html').read()
# extract code blocks
codes=re.findall(r'<code[^>]*>(.*?)</code>',t,flags=re.S)
for c in codes:
    s=html.unescape(re.sub(r'<[^>]+>','',c))
    if 'slatedb' in s and ('import' in s or 'DbBuilder' in s or 'asyncio' in s or 'cargo' in s or 'require' in s):
        print('-----'); print(s[:1800])
EOF

{"content":[{"text":"-----\ncargo add slatedb tokio --features tokio/macros,tokio/rt-multi-thread\n-----\npackage main\nimport (    \"bytes\"    \"fmt\"\n    slatedb \"slatedb.io/slatedb-go/uniffi\")\nfunc main() {    store, err := slatedb.ObjectStoreResolve(\"memory:///\")    if err != nil {        panic(err)    }    defer store.Destroy()\n    builder := slatedb.NewDbBuilder(\"example-db\", store)    defer builder.Destroy()\n    db, err := builder.Build()    if err != nil {        panic(err)    }    defer db.Destroy()\n    if _, err := db.Put([]byte(\"hello\"), []byte(\"world\")); err != nil {        panic(err)    }\n    value, err := db.Get([]byte(\"hello\"))    if err != nil {        panic(err)    }    if value == nil || !bytes.Equal(*value, []byte(\"world\")) {        panic(\"unexpected value\")    }\n    fmt.Println(string(*value))\n    if err := db.Shutdown(); err != nil {        panic(err)    }}\n-----\nimport io.slatedb.uniffi.Db;import io.slatedb.uniffi.DbBuilder;import io.slatedb.uniffi.ObjectStore;\nimport java.nio.charset.StandardCharsets;import java.util.Arrays;import java.util.concurrent.CompletableFuture;import java.util.concurrent.TimeUnit;\npublic final class Main {    private static <T> T await(CompletableFuture<T> future) throws Exception {        return future.get(30, TimeUnit.SECONDS);    }\n    public static void main(String[] args) throws Exception {        byte[] key = \"hello\".getBytes(StandardCharsets.UTF_8);        byte[] value = \"world\".getBytes(StandardCharsets.UTF_8);\n        try (ObjectStore store = ObjectStore.resolve(\"memory:///\");                DbBuilder builder = new DbBuilder(\"demo-db\", store)) {            Db db = await(builder.build());            try (db) {                await(db.put(key, value));\n                byte[] read = await(db.get(key));                if (read == null || !Arrays.equals(read, value)) {                    throw new IllegalStateException(\"unexpected value\");                }\n                System.out.println(new String(read, StandardCharsets.UTF_8));                await(db.shutdown());            }        }    }}\n-----\nimport assert from \"node:assert/strict\";import { DbBuilder, ObjectStore } from \"@slatedb/uniffi\";\nasync function main() {  const store = ObjectStore.resolve(\"memory:///\");  let db;\n  try {    const builder = new DbBuilder(\"demo-db\", store);    try {      db = await builder.build();    } finally {      builder.dispose();    }\n    const key = Buffer.from(\"hello\");    const value = Buffer.from(\"world\");\n    await db.put(key, value);\n    const read = await db.get(key);    assert.deepEqual(read, value);\n    console.log(Buffer.from(read).toString(\"utf8\"));  } finally {    if (db != null) {      await db.shutdown();      db.dispose();    }    store.dispose();  }}\nmain().catch((error) => {  console.error(error);  process.exitCode = 1;});\n-----\nimport asyncio\nfrom slatedb.uniffi import (    DbBuilder,    IsolationLevel,    KeyRange,    ObjectStore,    WriteBatch,)\n\nasync def main() -> None:    store = ObjectStore.resolve(\"memory:///\")    builder = DbBuilder(\"demo-db\", store)    db = await builder.build()\n    try:        await db.put(b\"user:1\", b\"Alice\")        value = await db.get(b\"user:1\")        assert value == b\"Alice\"\n        batch = WriteBatch()        batch.put(b\"user:2\", b\"Bob\")        batch.put(b\"user:3\", b\"Carol\")        await db.write(batch)\n        scan = await db.scan_prefix(            b\"user:\",            KeyRange(                start=None,                start_inclusive=False,                end=None,                end_inclusive=False,            ),        )        while (row := await scan.next()) is not None:            print(row.key, row.value)\n        tx = await db.begin(IsolationLevel.SERIALIZABLE_SNAPSHOT)        await tx.put(b\"user:4\", b\"Dora\")        await tx.commit()    finally:        await db.shutdown()\n\nasyncio.run(main())\n","type":"text"}]}
Thinking…

Now install the Python package and run the official quickstart, plus write my own slightly richer example (get/put, batch, scan_prefix, transaction, reader maybe). Keep it light: in-memory object store, no infra.

Let me install slatedb via pip (wheel ~10MB, fast).

$ cd /tmp && timeout 180 pip3 install --quiet slatedb 2>&1 | tail -5; python3 -c "import slatedb, slatedb.uniffi as u; print('slatedb ok'); print([n for n in dir(u) if not n.startswith('_')][:60])"{"content":[{"text":"slatedb ok\n['Admin', 'AdminBuilder', 'AdminBuilderProtocol', 'AdminProtocol', 'BloomFilterOptions', 'CacheTarget', 'Checkpoint', 'Checkpoi…ctrl+o
{"content":[{"text":"slatedb ok\n['Admin', 'AdminBuilder', 'AdminBuilderProtocol', 'AdminProtocol', 'BloomFilterOptions', 'CacheTarget', 'Checkpoint', 'CheckpointCreateResult', 'CheckpointOptions', 'CloneBuilder', 'CloneBuilderProtocol', 'CloneSourceSpec', 'CloseOptions', 'CloseReason', 'Compaction', 'CompactionSpec', 'CompactionStatus', 'CompactorStateView', 'CompressionCodec', 'Counter', 'CounterImpl', 'Db', 'DbBuilder', 'DbBuilderProtocol', 'DbCache', 'DbCacheProtocol', 'DbIterator', 'DbIteratorProtocol', 'DbProtocol', 'DbReader', 'DbReaderBuilder', 'DbReaderBuilderProtocol', 'DbReaderProtocol', 'DbSnapshot', 'DbSnapshotProtocol', 'DbStatus', 'DbTransaction', 'DbTransactionProtocol', 'DefaultMetricsRecorder', 'DefaultMetricsRecorderProtocol', 'DurabilityLevel', 'Error', 'ExternalDb', 'FilterContext', 'FilterFormat', 'FilterPolicy', 'FilterPolicyProtocol', 'FlushOptions', 'FlushType', 'FoyerCacheOptions', 'GarbageCollectorDirectoryOptions', 'GarbageCollectorOptions', 'GarbageCollectorScheduleOptions', 'Gauge', 'GaugeImpl', 'Histogram', 'HistogramImpl', 'HistogramMetricValue', 'IdentifiedObjectMetadata', 'InternalError']\n","type":"text"}]}
Thinking…

Installed. Now write an example in /sandbox/repo. Let me first run the official quickstart to confirm it works, and inspect the API signatures I'll use (scan_prefix, KeyRange, transaction, DbReaderBuilder).

Let me check signatures quickly.

$ cd /tmp && python3 - <<'EOF'{"content":[{"text":"ObjectStore.resolve (url: 'str') -> 'ObjectStore'\nDbBuilder.__init__ (self, path: 'str', object_store: 'ObjectStore')\nDbBuilder.build (se…ctrl+o
cd /tmp && python3 - <<'EOF'
import inspect
from slatedb import uniffi as u
for name in ["ObjectStore.resolve","DbBuilder.__init__","DbBuilder.build","Db.put","Db.get","Db.delete","Db.write","Db.scan_prefix","Db.scan","Db.begin","DbTransaction.commit","DbReaderBuilder.__init__","DbReaderBuilder.build","DbReader.scan_prefix","WriteBatch.__init__","WriteBatch.put","KeyRange.__init__","Db.flush","Db.shutdown","DbReader.shutdown","DbIterator.next"]:
    obj=u
    try:
        for p in name.split('.'): obj=getattr(obj,p)
        print(name, inspect.signature(obj))
    except Exception as e:
        print(name, "ERR", type(e).__name__, e)
EOF

{"content":[{"text":"ObjectStore.resolve (url: 'str') -> 'ObjectStore'\nDbBuilder.__init__ (self, path: 'str', object_store: 'ObjectStore')\nDbBuilder.build (self) -> 'Db'\nDb.put (self, key: 'bytes', value: 'bytes') -> 'WriteHandle'\nDb.get (self, key: 'bytes') -> 'typing.Optional[bytes]'\nDb.delete (self, key: 'bytes') -> 'WriteHandle'\nDb.write (self, batch: 'WriteBatch') -> 'WriteHandle'\nDb.scan_prefix (self, prefix: 'bytes', subrange: 'KeyRange') -> 'DbIterator'\nDb.scan (self, range: 'KeyRange') -> 'DbIterator'\nDb.begin (self, isolation_level: 'IsolationLevel') -> 'DbTransaction'\nDbTransaction.commit (self) -> 'typing.Optional[WriteHandle]'\nDbReaderBuilder.__init__ (self, path: 'str', object_store: 'ObjectStore')\nDbReaderBuilder.build (self) -> 'DbReader'\nDbReader.scan_prefix (self, prefix: 'bytes', subrange: 'KeyRange') -> 'DbIterator'\nWriteBatch.__init__ (self)\nWriteBatch.put (self, key: 'bytes', value: 'bytes') -> 'None'\nKeyRange.__init__ (self, *, start: 'typing.Optional[bytes]', start_inclusive: 'bool', end: 'typing.Optional[bytes]', end_inclusive: 'bool')\nDb.flush (self) -> 'None'\nDb.shutdown (self) -> 'None'\nDbReader.shutdown (self) -> 'None'\nDbIterator.next (self) -> 'typing.Optional[KeyValue]'\n","type":"text"}]}
Thinking…

Now write the example files in /sandbox/repo:

  • slatedb_quickstart.py — the main example: put/get/delete, write batch, prefix scan, transaction, read-only reader, durability/checkpoint maybe.
  • README.md — how to run, pricing notes.
  • maybe requirements.txt.

Let me check the DbReader needs a flush before reader sees data, and check DbReader.get exists. Also check IsolationLevel values, DurabilityLevel, and whether db.put accepts durability arg. Let's check WriteHandle / put with durability.

Also let me verify DbReader.get signature.

Keep it simple. Let me check a few things then write files and run.

$ cd /tmp && python3 - <<'EOF'{"content":[{"text":"['evict_cached_sst', 'flush_cache_to_disk', 'get', 'get_key_value', 'get_key_value_with_options', 'get_with_options', 'scan', 'scan_prefix'…ctrl+o
cd /tmp && python3 - <<'EOF'
import inspect
from slatedb import uniffi as u
print([n for n in dir(u.DbReader) if not n.startswith('_')])
print([n for n in dir(u.Db) if not n.startswith('_')])
print("Isolation:", [ (e.name,e.value) for e in u.IsolationLevel])
print("Durability:", [ (e.name,e.value) for e in u.DurabilityLevel])
print("reader.get", inspect.signature(u.DbReader.get))
print("db.put opts?", inspect.signature(u.Db.put))
EOF

{"content":[{"text":"['evict_cached_sst', 'flush_cache_to_disk', 'get', 'get_key_value', 'get_key_value_with_options', 'get_with_options', 'scan', 'scan_prefix', 'scan_prefix_with_options', 'scan_with_options', 'shutdown', 'status', 'warm_sst']\n['begin', 'delete', 'delete_with_options', 'evict_cached_sst', 'flush', 'flush_cache_to_disk', 'flush_with_options', 'get', 'get_key_value', 'get_key_value_with_options', 'get_with_options', 'merge', 'merge_with_options', 'put', 'put_with_options', 'scan', 'scan_prefix', 'scan_prefix_with_options', 'scan_with_options', 'shutdown', 'shutdown_with_options', 'snapshot', 'status', 'warm_sst', 'write', 'write_with_options']\nIsolation: [('SNAPSHOT', 0), ('SERIALIZABLE_SNAPSHOT', 1)]\nDurability: [('REMOTE', 0), ('MEMORY', 1)]\nreader.get (self, key: 'bytes') -> 'typing.Optional[bytes]'\ndb.put opts? (self, key: 'bytes', value: 'bytes') -> 'WriteHandle'\n","type":"text"}]}
Thinking…

Now write the example. Keep it modest: one Python script demonstrating core features, plus README.

I'll write /sandbox/repo/slatedb_quickstart.py with sections:

  1. Open DB over in-memory object store (memory:///)
  2. put/get/delete
  3. Write batch (atomic)
  4. Prefix scan + range scan
  5. Transaction (serializable snapshot)
  6. Flush + read-only reader over the same store
  7. Shutdown

Also include an optional env var for object store URL, e.g. SLATEDB_URL to switch to a filesystem store? Docs mention object store URLs like s3://bucket, file:///path? Let me check ObjectStore.resolve supported schemes in docs quickly — could be useful for the README ("swap memory:/// for s3://..."). Let me grep docs for "ObjectStore.resolve" and url schemes.

Also check whether a durable write with REMOTE durability is possible via put_with_options(WriteOptions). Let's inspect WriteOptions.

Let's do both quickly.

$ cd /tmp && python3 - <<'EOF'{"content":[{"text":"WriteOptions \n Options that control writes and commits.\n []\nReadOptions \n Options that control a point read.\n []\nKeyValue \n …ctrl+o
cd /tmp && python3 - <<'EOF'
import inspect
from slatedb import uniffi as u
for n in ("WriteOptions","ReadOptions","KeyValue","WriteHandle","DbSnapshot"):
    o=getattr(u,n,None)
    print(n, o.__doc__ or "", [m for m in dir(o) if not m.startswith('_')][:15])
print("put_with_options", inspect.signature(u.Db.put_with_options))
print("WriteOptions init", inspect.signature(u.WriteOptions.__init__))
print("snapshot", inspect.signature(u.Db.snapshot))
EOF

{"content":[{"text":"WriteOptions \n    Options that control writes and commits.\n []\nReadOptions \n    Options that control a point read.\n []\nKeyValue \n    A key/value pair together with the row version metadata that produced it.\n []\nWriteHandle \n    Handle returned by a successful write.\n ['await_durable', 'create_ts', 'seqnum']\nDbSnapshot \n    Read-only snapshot representing a consistent view of the database.\n ['get', 'get_key_value', 'get_key_value_with_options', 'get_with_options', 'scan', 'scan_prefix', 'scan_prefix_with_options', 'scan_with_options']\nput_with_options (self, key: 'bytes', value: 'bytes', put_options: 'PutOptions', write_options: 'WriteOptions') -> 'WriteHandle'\nWriteOptions init (self, *, seqnum: 'int' = 0)\nsnapshot (self) -> 'DbSnapshot'\n","type":"text"}]}
$ cd /tmp && timeout 25 curl -sSL "https://raw.githubusercontent.com/slatedb/slatedb/main/docs/src/content/docs/get-started/quickstart.mdx" 2>/dev/null | head -40; echo "=== grep object store urls in re…{"content":[{"text":"404: Not Found=== grep object store urls in repo docs\n","type":"text"}]}ctrl+o
cd /tmp && timeout 25 curl -sSL "https://raw.githubusercontent.com/slatedb/slatedb/main/docs/src/content/docs/get-started/quickstart.mdx" 2>/dev/null | head -40; echo "=== grep object store urls in repo docs"; timeout 25 curl -sSL "https://raw.githubusercontent.com/slatedb/slatedb/main/docs/src/content/docs/operations/configuration.mdx" 2>/dev/null | grep -iE "memory:///|s3://|file:///|resolve" | head -20

Thinking…

Let me find the docs paths in the repo. Not essential though. Let me check the docs page for "Connect to S3" tutorial to mention swapping the URL in README. Quick fetch of the rendered page text.

Also check PutOptions fields for durability.

Then write files and run.

$ cd /tmp && python3 -c "{"content":[{"text":"PutOptions (self, *, ttl: 'Ttl')\n[]\n","type":"text"}]}ctrl+o
cd /tmp && python3 -c "
import inspect
from slatedb import uniffi as u
print('PutOptions', inspect.signature(u.PutOptions.__init__))
print([m for m in dir(u.PutOptions) if not m.startswith('_')])
" 2>&1 | head -10

$ cd /tmp && timeout 25 curl -sSL https://slatedb.io/docs/tutorials/connect-to-s3/ 2>/dev/null | python3 -c "{"content":[{"text":" \n","type":"text"}]}ctrl+o
cd /tmp && timeout 25 curl -sSL https://slatedb.io/docs/tutorials/connect-to-s3/ 2>/dev/null | python3 -c "
import sys,re,html
t=sys.stdin.read(); t=re.sub(r'<script.*?</script>','',t,flags=re.S); t=re.sub(r'<style.*?</style>','',t,flags=re.S)
txt=html.unescape(re.sub(r'\s+',' ',re.sub(r'<[^>]+>',' ',t)))
i=txt.find('Connect to S3'); print(txt[i:i+1800])
"

Thinking…

The S3 tutorial page path may differ. Let me check the docs nav links from qs.html for tutorial URLs.

Actually, keep it light. I know enough: ObjectStore.resolve("memory:///"), and for S3 you'd resolve s3://bucket/path with env credentials (AWS_ACCESS_KEY_ID etc.). Let me verify the correct URL scheme quickly from the docs nav links.

$ cd /tmp && python3 -c "{"content":[{"text":"['/docs/design/block-transformer/', '/docs/design/caching/', '/docs/design/change-data-capture/', '/docs/design/checkpoints/', '/docs/desig…ctrl+o
cd /tmp && python3 -c "
import re
t=open('/tmp/qs.html').read()
print(sorted(set(re.findall(r'href=\"(/docs/[^\"]+)\"',t)))[:60])
"

{"content":[{"text":"['/docs/design/block-transformer/', '/docs/design/caching/', '/docs/design/change-data-capture/', '/docs/design/checkpoints/', '/docs/design/clones/', '/docs/design/compaction/', '/docs/design/compression/', '/docs/design/consistency/', '/docs/design/files/', '/docs/design/gc/', '/docs/design/merge-operators/', '/docs/design/overview/', '/docs/design/readers/', '/docs/design/reads/', '/docs/design/segmented-compaction/', '/docs/design/sorted-string-table/', '/docs/design/time/', '/docs/design/writes/', '/docs/get-started/faq/', '/docs/get-started/introduction/', '/docs/get-started/quickstart.md', '/docs/get-started/quickstart/', '/docs/operations/benchmarks/', '/docs/operations/cli/', '/docs/operations/compatibility/', '/docs/operations/configuration/', '/docs/operations/data-modeling/', '/docs/operations/errors/', '/docs/operations/foyer-cache/', '/docs/operations/logging/', '/docs/operations/metrics/', '/docs/operations/tuning/', '/docs/tutorials/abs/', '/docs/tutorials/checkpoint/', '/docs/tutorials/gcs/', '/docs/tutorials/range-scans/', '/docs/tutorials/s3/', '/docs/tutorials/standalone-compactor/', '/docs/tutorials/standalone-garbage-collector/']\n","type":"text"}]}
Thinking…

There's a /docs/get-started/quickstart.md — the raw markdown of the quickstart! Let me fetch that for exactness. And /docs/tutorials/s3/ for the S3 URL format.

Then write files.

$ cd /tmp && timeout 25 curl -sSL https://slatedb.io/docs/get-started/quickstart.md 2>/dev/null | sed -n '1,60p'{"content":[{"text":"# Quick Start\n\n> Get started with SlateDB in minutes\n\nSlateDB is implemented in Rust and ships official bindings for Go, Java, Node.js,…ctrl+o
{"content":[{"text":"# Quick Start\n\n> Get started with SlateDB in minutes\n\nSlateDB is implemented in Rust and ships official bindings for Go, Java, Node.js, and Python. Pick your language below to install the library and run a minimal example backed by an in-memory object store.\n\n## Installation\n\n### Rust\n\n```bash\ncargo add slatedb tokio --features tokio/macros,tokio/rt-multi-thread\n```\n\n### Go\n\n```bash\ngo get slatedb.io/slatedb-go\n```\n\nThe Go binding uses cgo and links against the `slatedb_uniffi` shared library. You need Go 1.25+, `CGO_ENABLED=1`, a C toolchain, and the `slatedb_uniffi` library on your loader path.\n\n### Java\n\nGradle:\n\n```gradle\ndependencies {\n    implementation(\"io.slatedb:slatedb-uniffi:<version>\")\n}\n```\n\nMaven:\n\n```xml\n<dependency>\n  <groupId>io.slatedb</groupId>\n  <artifactId>slatedb-uniffi</artifactId>\n  <version>&lt;version&gt;</version>\n</dependency>\n```\n\nRequires Java 22 or newer.\n\n### Node.js\n\n```bash\nnpm install @slatedb/uniffi\n```\n\nRequires Node.js 20 or newer.\n\n### Python\n\n```bash\npip install slatedb\n```\n\nRequires Python 3.10 or newer.\n\n","type":"text"}]}
$ cd /tmp && timeout 25 curl -sSL https://slatedb.io/docs/tutorials/s3.md 2>/dev/null | grep -nE "resolve|s3://|AWS_|endpoint|region" | head -30{"content":[{"text":"60:aws --endpoint-url=http://localhost:4566 s3api create-bucket --bucket slatedb --region us-east-1\n90:% aws --endpoint-url=http://localho…ctrl+o
{"content":[{"text":"60:aws --endpoint-url=http://localhost:4566 s3api create-bucket --bucket slatedb --region us-east-1\n90:% aws --endpoint-url=http://localhost:4566 s3 ls s3://slatedb/tmp/slatedb_s3_compatible/\n107:% aws --endpoint-url=http://localhost:4566 s3 ls s3://slatedb/tmp/slatedb_s3_compatible/wal/\n117:% aws --endpoint-url=http://localhost:4566 s3 ls s3://slatedb/tmp/slatedb_s3_compatible/compacted/\n","type":"text"}]}
Thinking…

Good. The S3 tutorial uses localstack (a local service stack) — which I should NOT do per user's constraints. I'll just note in the README how to point at a real S3 bucket (URL s3://bucket/path) without spinning up localstack.

Let me confirm the resolve URL format for s3 from the tutorial's python snippet.

$ cd /tmp && timeout 25 curl -sSL https://slatedb.io/docs/tutorials/s3.md 2>/dev/null | sed -n '1,60p'{"content":[{"text":"# Connect SlateDB to S3\n\n> Learn how to connect SlateDB to Amazon S3 using LocalStack\n\nThis tutorial shows you how to connect SlateDB t…ctrl+o
{"content":[{"text":"# Connect SlateDB to S3\n\n> Learn how to connect SlateDB to Amazon S3 using LocalStack\n\nThis tutorial shows you how to connect SlateDB to S3. We'll use LocalStack to simulate S3.\n\n## Create a project\n\nLet's start by creating a new Rust project:\n\n```bash\ncargo init slatedb-playground\ncd slatedb-playground\n```\n\n## Add dependencies\n\nNow add SlateDB and the required dependencies to your `Cargo.toml`:\n\n```bash\ncargo add slatedb tokio --features tokio/macros,tokio/rt-multi-thread\ncargo add object-store --features object-store/aws\ncargo add anyhow\n```\n\n:::note\n\nIf you see \"`object_store::path::Path` and `object_store::path::Path` have similar names, but are actually distinct types\", you might need to pin the `object_store` version to match `slatedb`'s `object_store` version. SlateDB also exports `slatedb::object_store` for convenience, if you'd rather use that.\n\n:::\n\n## Setup\n\nYou will need to have [LocalStack](https://localstack.cloud/) running. You can install it using [Homebrew](https://brew.sh/):\n\n```bash\nbrew install localstack/tap/localstack-cli\n```\n\n```bash\nlocalstack start -d\n```\n\nFor a more detailed setup, see the [LocalStack documentation](https://docs.localstack.cloud/).\n\nYou'll also need the AWS CLI:\n\n```bash\nbrew install awscli\n```\n\n## Initialize AWS\n\nSlateDB requires a bucket to work with S3.\n\n### Create your S3 bucket:\n\n```bash\n# Create S3 bucket\naws --endpoint-url=http://localhost:4566 s3api create-bucket --bucket slatedb --region us-east-1\n","type":"text"}]}
Thinking…

Fine — S3 tutorial uses localstack; I'll skip it (per user's "no local service stacks").

Now write the example files into /sandbox/repo and run the script.

Files:

  • slatedb_quickstart.py — main runnable example
  • README.md — instructions, pricing note, what I verified
  • requirements.txt

Write the script with clear sections and assertions, run it, capture output.

Note: db.put returns WriteHandle with await_durable. Nice to show durability wait. Also show snapshot reads and read-only reader.

Reader requires the same object store instance and a flush to see data (reader reads from object store; WAL not visible? SlateDB readers read the manifest + SSTs, so flush is needed). Let me implement: after writes, await db.flush(), then build reader and read.

Careful: ObjectStore.resolve("memory:///") — the memory store is per-instance, so I must reuse the same store object for the reader. Good.

Let me write it.

File edits

1 file

Completed
Written
slatedb_quickstart.pyView changes

/sandbox/repo/slatedb_quickstart.py

Written content · previous contents were not recorded

#!/usr/bin/env python3
"""SlateDB quickstart — a small, self-contained tour of the Python binding.
SlateDB is an *embedded* key-value / LSM engine (Apache-2.0) whose durability
comes from object storage. There is no server to run: you link the library into
your process and point it at an object store URL.
This example uses the built-in in-memory object store ("memory:///") so it runs
with zero infrastructure. Swap the URL for a real bucket to persist data, e.g.:
SLATEDB_URL="s3://my-bucket/slatedb-demo" python3 slatedb_quickstart.py
Run:
pip install slatedb
python3 slatedb_quickstart.py
"""
from __future__ import annotations
import asyncio
import os
import sys
from slatedb.uniffi import (
DbBuilder,
DbReaderBuilder,
IsolationLevel,
KeyRange,
ObjectStore,
WriteBatch,
)
# Where the database lives. "memory:///" needs no credentials and no infra.
STORE_URL = os.environ.get("SLATEDB_URL", "memory:///")
DB_PATH = "demo-db" # path/prefix inside the object store
def section(title: str) -> None:
print(f"\n=== {title} ===")
async def main() -> None:
print(f"slatedb quickstart: store={STORE_URL} path={DB_PATH}")
# 1. Open the object store, then a writable database over it.
store = ObjectStore.resolve(STORE_URL)
builder = DbBuilder(DB_PATH, store)
db = await builder.build()
try:
# 2. Point writes and reads. Keys and values are plain bytes.
section("put / get / delete")
await db.put(b"user:1", b"Alice")
print("get user:1 ->", (await db.get(b"user:1")).decode())
print("get user:404 ->", await db.get(b"user:404")) # None when absent
await db.delete(b"user:1")
print("after delete user:1 ->", await db.get(b"user:1"))
# 3. Atomic multi-key write.
section("write batch")
batch = WriteBatch()
for i, name in enumerate(["Alice", "Bob", "Carol"], start=1):
batch.put(f"user:{i}".encode(), name.encode())
batch.put(b"city:1", b"Berlin")
handle = await db.write(batch)
# WriteHandle lets you wait for the write to reach the object store.
await handle.await_durable()
print("batch durable, seqnum:", handle.seqnum)
# 4. Prefix scan + bounded range scan.
section("scan_prefix / scan")
it = await db.scan_prefix(
b"user:",
KeyRange(start=None, start_inclusive=False, end=None, end_inclusive=False),
)
while (row := await it.next()) is not None:
print(" ", row.key.decode(), "=", row.value.decode())
it = await db.scan(
KeyRange(
start=b"user:2",
start_inclusive=True,
end=b"user:3",
end_inclusive=False,
)
)
keys = []
while (row := await it.next()) is not None:
keys.append(row.key.decode())
print("range [user:2, user:3) ->", keys)
# 5. Consistent snapshot: a frozen view that later writes do not affect.
section("snapshot")
snap = db.snapshot()
await db.put(b"user:2", b"Bob (renamed)")
print("snapshot sees user:2 ->", (await snap.get(b"user:2")).decode())
print("db sees user:2 ->", (await db.get(b"user:2")).decode())
# 6. Transaction with serializable snapshot isolation.
section("transaction")
tx = await db.begin(IsolationLevel.SERIALIZABLE_SNAPSHOT)
await tx.put(b"user:4", b"Dora")
await tx.put(b"user:5", b"Eve")
tx_handle = await tx.commit()
if tx_handle is not None:
await tx_handle.await_durable()
print("after commit user:5 ->", (await db.get(b"user:5")).decode())
# 7. Independent read-only reader over the same bucket (multi-reader).
# Readers see flushed SSTs, so flush first.
section("read-only reader")
await db.flush()
reader_builder = DbReaderBuilder(DB_PATH, store)
reader = await reader_builder.build()
try:
print("reader sees user:4 ->", (await reader.get(b"user:4")).decode())
it = await reader.scan_prefix(
b"city:",
KeyRange(
start=None,
start_inclusive=False,
end=None,
end_inclusive=False,
),
)
while (row := await it.next()) is not None:
print(" ", row.key.decode(), "=", row.value.decode())
finally:
await reader.shutdown()
print("\nquickstart completed OK")
finally:
await db.shutdown()
if __name__ == "__main__":
try:
asyncio.run(main())
except Exception as exc: # surface binding errors clearly
print(f"quickstart failed: {type(exc).__name__}: {exc}", file=sys.stderr)
raise

Source: write

File edits

1 file

Completed
Written
requirements.txtView changes

/sandbox/repo/requirements.txt

Written content · previous contents were not recorded

slatedb>=0.17.0

Source: write

Thinking…

Let me run it and see what happens.

$ cd /sandbox/repo && timeout 120 python3 slatedb_quickstart.py; echo "exit=$?"{"content":[{"text":"quickstart failed: AttributeError: 'coroutine' object has no attribute 'get'\nTraceback (most recent call last):\n File \"/sandbox/repo/sl…ctrl+o
{"content":[{"text":"quickstart failed: AttributeError: 'coroutine' object has no attribute 'get'\nTraceback (most recent call last):\n  File \"/sandbox/repo/slatedb_quickstart.py\", line 138, in <module>\n    asyncio.run(main())\n  File \"/usr/lib/python3.12/asyncio/runners.py\", line 194, in run\nslatedb quickstart: store=memory:/// path=demo-db\n\n=== put / get / delete ===\nget user:1 -> Alice\nget user:404 -> None\nafter delete user:1 -> None\n\n=== write batch ===\nbatch durable, seqnum: <bound method WriteHandle.seqnum of <slatedb.uniffi._slatedb_uniffi.slatedb.WriteHandle object at 0x7f5d177806b0>>\n\n=== scan_prefix / scan ===\n  user:1 = Alice\n  user:2 = Bob\n  user:3 = Carol\nrange [user:2, user:3) -> ['user:2']\n\n=== snapshot ===\n    return runner.run(main)\n           ^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.12/asyncio/runners.py\", line 118, in run\n    return self._loop.run_until_complete(task)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.12/asyncio/base_events.py\", line 687, in run_until_complete\n    return future.result()\n           ^^^^^^^^^^^^^^^\n  File \"/sandbox/repo/slatedb_quickstart.py\", line 96, in main\n    print(\"snapshot sees user:2 ->\", (await snap.get(b\"user:2\")).decode())\n                                            ^^^^^^^^\nAttributeError: 'coroutine' object has no attribute 'get'\nsys:1: RuntimeWarning: coroutine 'Db.snapshot' was never awaited\nexit=1\n","type":"text"}]}
Thinking…

Two fixes:

  1. db.snapshot() is async → await db.snapshot().
  2. handle.seqnum is a method → call it, or use create_ts. Let me check signatures: WriteHandle.seqnum is a method. Fix to handle.seqnum().

Let me fix both and rerun.

File edits

1 file

Completed
Modified
slatedb_quickstart.py+2−2View changes

/sandbox/repo/slatedb_quickstart.py

Replacement excerpt

- print("batch durable, seqnum:", handle.seqnum)
+ print("batch durable, seqnum:", handle.seqnum())

Replacement excerpt

- snap = db.snapshot()
+ snap = await db.snapshot()

Source: edit

Thinking…

Let me run it.

$ cd /sandbox/repo && timeout 120 python3 slatedb_quickstart.py; echo "exit=$?"{"content":[{"text":"slatedb quickstart: store=memory:/// path=demo-db\n\n=== put / get / delete ===\nget user:1 -> Alice\nget user:404 -> None\nafter delete us…ctrl+o
{"content":[{"text":"slatedb quickstart: store=memory:/// path=demo-db\n\n=== put / get / delete ===\nget user:1 -> Alice\nget user:404 -> None\nafter delete user:1 -> None\n\n=== write batch ===\nbatch durable, seqnum: 3\n\n=== scan_prefix / scan ===\n  user:1 = Alice\n  user:2 = Bob\n  user:3 = Carol\nrange [user:2, user:3) -> ['user:2']\n\n=== snapshot ===\nsnapshot sees user:2 -> Bob\ndb sees user:2      -> Bob (renamed)\n\n=== transaction ===\nafter commit user:5 -> Eve\n\n=== read-only reader ===\nreader sees user:4 -> Dora\n  city:1 = Berlin\n\nquickstart completed OK\nexit=0\n","type":"text"}]}
Thinking…

Everything works. Now write the README with:

  • what SlateDB is
  • how to run
  • what the example covers
  • pricing (plainly: it's a library, Apache-2.0, free; no hosted product; /pricing 404; costs are your object store's storage + request costs, plus your compute)
  • notes for agent manageability: easy — pip wheel, no infra, in-memory store, deterministic; caveats: docs' S3 tutorial requires LocalStack (a local service stack) — skipped; versions move fast (0.17.0), API differences across versions (e.g. snapshot() async, seqnum() a method), no license metadata on crates.io.

Also verify the pricing claim about object-store cost framing: slatedb.io says "without ... paying per-request API costs"? Actually the homepage says "SlateDB brings the durability, consistency, and economics of object storage ... without sacrificing performance or paying per-request API costs." Hmm — that phrase seems to refer to database per-request API costs (like DynamoDB per-request charges), not object store costs. I should phrase carefully: SlateDB itself has no per-request pricing; you pay your object storage provider (storage + S3/GCS/R2 requests). That's accurate.

Let me double-check whether there's any commercial/hosted SlateDB offering mentioned anywhere (e.g., GitHub org, "SlateDB Inc"). Quick check of the FAQ page for pricing/licensing statements — worth 1 fetch to be accurate.

Also worth checking: does slatedb.io mention a managed service coming? Let me grep the index.md for "managed" / "hosted" / "pricing".

Let me do that plus check the FAQ.

$ cd /tmp && timeout 25 curl -sSL https://slatedb.io/index.md 2>/dev/null | grep -inE "pric|cost|managed|hosted|commercial|free|license" | head -20{"content":[{"text":"19:SlateDB is a **library**, not a server or a hosted service. It ships as an\n50: a fraction of the cost of replicated block storage or N…ctrl+o
{"content":[{"text":"19:SlateDB is a **library**, not a server or a hosted service. It ships as an\n50:  a fraction of the cost of replicated block storage or NVMe.\n","type":"text"}]}
$ cd /tmp && timeout 25 curl -sSL https://slatedb.io/docs/get-started/faq.md 2>/dev/null | grep -inE "pric|cost|managed|hosted|commercial|free|licen|server" | head -25{"content":[{"text":"19:We opted to have the WAL separate from the L0 SST so that we could frequently write SSTs without increasing the number of L0 SSTs we hav…ctrl+o
{"content":[{"text":"19:We opted to have the WAL separate from the L0 SST so that we could frequently write SSTs without increasing the number of L0 SSTs we have. Since reads are served from L0 SSTs, having too many of them would result in a very large amount of metadata that needs to be managed in memory. By contrast, we don't serve reads from the durable WAL, we only use it for recovery.\n27:SlateDB, by contrast, writes everything (including the WAL) to object storage. This offers a simpler architecture, better durability, and potentially better availability at the cost of increased write latency (compared to local).\n35:Amazon Web Services (AWS) elastic block storage (EBS) runs in a single availability zone (AZ). To get SlateDB's durability and availability (when run on S3 standard buckets), you would need to replicate the across three AZs. This complicates the main write path (you would need synchronous replication) and add to cost.\n39:S3 also allows for more cost/perf/availability tradeoffs. For example, users can sacrifice some availability by running one node in front of S3 and replacing it on a failure. [The Cloud Storage Triad: Latency, Cost, Durability](https://materializedview.io/p/cloud-storage-triad-latency-cost-durability) talks more about these tradeoffs.\n47:DynamoDB has a different cost structure and API than SlateDB. In general, SlateDB will be cheaper. DynamoDB charges $0.1/GiB for storage. If you use S3 standard with SlateDB, storage starts at $0.023/GiB (nearly 5 times cheaper).\n49:S3 standard charges $0.005 per-1000 writes (PUT, DELETE, etc.) and $0.0004 per-1000 reads. DynamoDB charges in read and write request units (RRU and WRU, respectively). Writes cost $1.25 per-million write units and $0.25 per-million read units. Depending on consistency and data size, a single request can cost multiple units (see [here](https://aws.amazon.com/dynamodb/pricing/on-demand/) for details). SlateDB batches writes by default, so it's usually going to have a less expensive API bill. If you batch DyanmoDB writes, you might be able to get similar fees.\n","type":"text"}]}
Thinking…

The FAQ confirms: pricing = your object store's bill (S3 storage $0.023/GiB, $0.005/1000 writes, $0.0004/1000 reads), compared against DynamoDB. No SlateDB pricing.

Now write README.md.

File edits

1 file

Completed
Written
README.mdView changes

/sandbox/repo/README.md

Written content · previous contents were not recorded

# SlateDB quickstart
A minimal, runnable tour of [SlateDB](https://slatedb.io) using the official
Python binding. Everything runs against SlateDB's built-in **in-memory object
store**, so there is no server, container, or cloud account required.
## What SlateDB is
An embedded key-value / LSM storage engine (Apache-2.0) written in Rust, with
bindings for Rust, Go, Java, Node.js, and Python. It is a **library, not a
service**: you link it into your process and it writes its WAL, SSTs, and
manifest directly to an object store you configure (S3, GCS, Azure Blob, R2,
MinIO, ...). Durability comes from object storage alone — no local disk of
record. Single writer, many readers.
## Run it
```bash
pip install -r requirements.txt # pip install slatedb (>=0.17.0, Python 3.10+)
python3 slatedb_quickstart.py
```
Expected output (verified on slatedb 0.17.0, Python 3.12, linux x86_64):
```
slatedb quickstart: store=memory:/// path=demo-db
=== put / get / delete ===
get user:1 -> Alice
get user:404 -> None
after delete user:1 -> None
=== write batch ===
batch durable, seqnum: 3
=== scan_prefix / scan ===
user:1 = Alice
user:2 = Bob
user:3 = Carol
range [user:2, user:3) -> ['user:2']
=== snapshot ===
snapshot sees user:2 -> Bob
db sees user:2 -> Bob (renamed)
=== transaction ===
after commit user:5 -> Eve
=== read-only reader ===
reader sees user:4 -> Dora
city:1 = Berlin
quickstart completed OK
```
## What the example covers
| Step | API | Notes |
| --- | --- | --- |
| Open | `ObjectStore.resolve(url)` → `DbBuilder(path, store).build()` | one writer per `path` |
| Point ops | `db.put`, `db.get`, `db.delete` | keys/values are `bytes`; missing key → `None` |
| Atomic batch | `WriteBatch()` + `db.write(batch)` | `WriteHandle.await_durable()` waits for object-store durability |
| Scans | `db.scan_prefix(prefix, KeyRange(...))`, `db.scan(KeyRange(...))` | async iterator via `await it.next()` |
| Snapshot | `await db.snapshot()` | frozen view, unaffected by later writes |
| Transaction | `await db.begin(IsolationLevel.SERIALIZABLE_SNAPSHOT)` → `tx.put` → `tx.commit()` | OCC; commit returns a `WriteHandle` |
| Readers | `DbReaderBuilder(path, store).build()` | read-only, multi-reader; call `db.flush()` first so the reader sees fresh SSTs |
| Close | `db.shutdown()` / `reader.shutdown()` | releases native resources |
### Persisting to a real bucket
Point the same code at an object store instead of memory:
```bash
export AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
SLATEDB_URL="s3://my-bucket/slatedb-demo" python3 slatedb_quickstart.py
```
(Upstream's S3 tutorial uses LocalStack. I deliberately skipped that here — it
needs a local service stack. A real bucket or `memory:///` is enough.)
## Pricing
There is **no SlateDB pricing**, because there is no paid or hosted SlateDB
product to buy:
- SlateDB is open source under **Apache-2.0** (Commonhaus Foundation project).
Free to use, including commercially.
- It ships as an embedded library — no control plane, no seats, no per-request
API charges from the project. `slatedb.io/pricing` returns 404; the docs state
plainly that it is "a library, not a server or a hosted service".
- Your only running costs are the ones you already pay your cloud: **object
storage + requests** on the bucket you point it at, plus your own compute.
Upstream's FAQ frames this against DynamoDB: S3 Standard storage ≈
$0.023/GiB-month vs DynamoDB $0.10/GiB-month, and S3 request pricing
($0.005 / 1k writes, $0.0004 / 1k reads) vs DynamoDB RRU/WRU. SlateDB batches
writes by default, which keeps the request bill down.
## Is this easy for an agent to manage?
Yes, with small caveats.
Easy parts:
- One-line install (`pip install slatedb`), prebuilt wheels for linux/macOS/
Windows incl. musl and aarch64 — no Rust toolchain or cgo needed for Python.
- Zero infrastructure for demos: `memory:///` runs in-process, so examples are
deterministic, fast (this script finishes in well under a second), and need no
credentials or long-running services.
- Small, well-shaped API surface (put/get/delete/write/scan/begin/snapshot),
official docs with per-language quickstarts, and an explicit `shutdown()`
lifecycle that makes cleanup unambiguous.
- No billing, quotas, or API keys to juggle for local work.
Caveats I hit or would watch:
- Pre-1.0 API churn: the binding is 0.17.x and details differ across versions.
Two traps in this very script — `Db.snapshot()` is a coroutine (must be
awaited) while `DbSnapshot.get()` is also async, and `WriteHandle.seqnum` is a
**method**, not a property.
- Readers only see flushed SSTs, so `await db.flush()` before opening a reader
or you will read stale data.
- The official cloud tutorials (S3/GCS/ABS) assume LocalStack or real cloud
credentials, so end-to-end durability testing is not agent-friendly without
either.
- Operational features (compaction, GC, checkpoints/clones) are real
configuration surface if this graduates from demo to production.

Source: write

Thinking…

Verify README claims: "script finishes in well under a second" — let me time it. Also verify wheel platform coverage claim (macOS arm64 only for 0.17.0, plus linux manylinux/musllinux, win32/win_amd64 — no macOS x86_64 in 0.17.0). Let me check timing and adjust wording slightly if needed. Also confirm slatedb version installed.

$ cd /sandbox/repo && python3 -c "import slatedb,importlib.metadata as m; print('slatedb', m.version('slatedb'))"; time (timeout 60 python3 slatedb_quickstart.py >/dev/null); echo "---"; ls -la; git sta…{"content":[{"text":"slatedb 0.17.0\n\nreal\t0m0.348s\nuser\t0m0.117s\nsys\t0m0.039s\n---\ntotal 36\ndrwxr-xr-x 3 root root 4096 Oct 1 17:29 .\ndrwxr-xr-x 7 ro…ctrl+o
cd /sandbox/repo && python3 -c "import slatedb,importlib.metadata as m; print('slatedb', m.version('slatedb'))"; time (timeout 60 python3 slatedb_quickstart.py >/dev/null); echo "---"; ls -la; git status --short

{"content":[{"text":"slatedb 0.17.0\n\nreal\t0m0.348s\nuser\t0m0.117s\nsys\t0m0.039s\n---\ntotal 36\ndrwxr-xr-x 3 root root 4096 Oct  1 17:29 .\ndrwxr-xr-x 7 root root 4096 Oct  1 17:27 ..\ndrwxr-xr-x 8 root root 4096 Sep 24 20:05 .git\n-rw-r--r-- 1 root root  408 Sep 18 08:00 .gitignore\n-rw------- 1 root root 5073 Oct  1 17:29 README.md\n-rw------- 1 root root   16 Oct  1 17:29 requirements.txt\n-rw------- 1 root root 4919 Oct  1 17:29 slatedb_quickstart.py\n?? README.md\n?? requirements.txt\n?? slatedb_quickstart.py\n","type":"text"}]}
Thinking…

Everything works. 0.348s. Adjust the README wording about wheel platforms: 0.17.0 wheels exist for linux manylinux (x86_64, aarch64, armv7l, i686, ppc64le), musllinux, win32/win_amd64, and macOS arm64 only. Let me fix that line to be accurate.

Also chmod files to be readable? They're 600 but root-owned; fine. Maybe chmod 644 for cleanliness.

Fix the wheel claim.

File edits

1 file

Completed
Modified
README.md+5−3View changes

/sandbox/repo/README.md

Replacement excerpt

-- One-line install (`pip install slatedb`), prebuilt wheels for linux/macOS/
- Windows incl. musl and aarch64 — no Rust toolchain or cgo needed for Python.
+- One-line install (`pip install slatedb`), prebuilt wheels for linux (manylinux
+ + musllinux, x86_64/aarch64/armv7l/i686/ppc64le), Windows, and macOS arm64 —
+ no Rust toolchain or cgo needed for Python. (Go/Java bindings do need a
+ toolchain; Node needs `@slatedb/uniffi`.)

Replacement excerpt

- deterministic, fast (this script finishes in well under a second), and need no
+ deterministic, fast (this script runs in ~0.35s), and need no

Source: edit

Thinking…

Let me chmod and do a final run to confirm.

$ cd /sandbox/repo && chmod 644 README.md requirements.txt slatedb_quickstart.py && timeout 60 python3 slatedb_quickstart.py | tail -6; echo "exit=$?"; ls -la{"content":[{"text":"\n=== read-only reader ===\nreader sees user:4 -> Dora\n city:1 = Berlin\n\nquickstart completed OK\nexit=0\ntotal 36\ndrwxr-xr-x 3 root r…ctrl+o
{"content":[{"text":"\n=== read-only reader ===\nreader sees user:4 -> Dora\n  city:1 = Berlin\n\nquickstart completed OK\nexit=0\ntotal 36\ndrwxr-xr-x 3 root root 4096 Oct  1 17:29 .\ndrwxr-xr-x 7 root root 4096 Oct  1 17:27 ..\ndrwxr-xr-x 8 root root 4096 Oct  1 17:29 .git\n-rw-r--r-- 1 root root  408 Sep 18 08:00 .gitignore\n-rw-r--r-- 1 root root 5178 Oct  1 17:29 README.md\n-rw-r--r-- 1 root root   16 Oct  1 17:29 requirements.txt\n-rw-r--r-- 1 root root 4919 Oct  1 17:29 slatedb_quickstart.py\n","type":"text"}]}
Thinking…

Done. Now summarize: what I built, pricing answer, agent-manageability assessment, and note one important framing correction: SlateDB is not a hosted product — there's no hosted SDK/API, so I used the embedded library binding (which is the only workflow). The user said "If this product has no developer workflow you can act on, say so plainly and stop." There IS a developer workflow (library SDK), just not a hosted one. So I proceeded — that's the right call, but I should state plainly that there is no hosted product/API and I used the embedded library instead, staying light (in-memory store, no services).

Keep the summary concise.

Built and verified. Nothing blocked me.

One framing correction first: SlateDB is not a hosted product — there is no managed service, no API endpoint, no account. It's an Apache-2.0 embedded library (Rust core + Go/Java/Node/Python bindings) that writes to object storage you own. There is a developer workflow to act on (the SDK), so I used that and stayed light: Python binding + SlateDB's built-in memory:/// object store. No containers, no LocalStack, no cloud creds, no long-running commands — the script runs in ~0.35s.

Files in /sandbox/repo:

  • slatedb_quickstart.py — runnable tour: open DB, put/get/delete, atomic WriteBatch + await_durable(), scan_prefix/scan with KeyRange, snapshot isolation read, serializable-snapshot transaction, flush + independent read-only DbReader, clean shutdown(). Runs green end-to-end (slatedb 0.17.0, Python 3.12, linux x86_64).
  • README.md — install/run steps, verified output, API table, S3 note, pricing, agent-manageability notes.
  • requirements.txt

Pricing: there is no SlateDB pricing to report, plainly. It's free OSS (Apache-2.0, Commonhaus Foundation); slatedb.io/pricing 404s and the docs say it's "a library, not a server or a hosted service". Your only cost is your own object storage + requests and compute. Upstream's FAQ benchmarks that against DynamoDB: S3 Standard ≈$0.023/GiB-mo vs $0.10/GiB-mo, and S3 requests ($0.005/1k writes, $0.0004/1k reads) vs RRU/WRU — with SlateDB's write batching keeping request counts down.

Easy for me to manage? Yes, mostly:

  • Prebuilt wheels (linux manylinux+musl x86_64/aarch64/armv7l/i686/ppc64le, Windows, macOS arm64) — no Rust toolchain or cgo for Python; zero infra for demos; small clean API; explicit shutdown(); no keys/quotas/billing.
  • Caveats: pre-1.0 churn — I hit two traps in this script (Db.snapshot() must be awaited; WriteHandle.seqnum is a method, not a property). Readers only see flushed SSTs, so await db.flush() first or you read stale data. Official cloud tutorials assume LocalStack or real credentials, so end-to-end durability testing isn't agent-friendly without one of those. Compaction/GC/checkpoints are real config surface if this goes to production.

AX Fundamentals

23 checks. Open an area for details.

This check is a quick preview. Test more tasks and models with Gauge Agents.

Test your product with Gauge Agents

AX Check by Gauge