Most of what this index publishes is analysis of what changed. This one is a decision path: if you want to run AI workloads against storage you control, on hardware you own, what does the stack actually look like in late 2026 and where does it break?
The short version is that the line moved this month. Two releases — covered separately in the October wave — changed what a single machine can hold. If you last priced this out in the spring, the answer is different now.
The five decisions, in order
A local-first AI stack is five choices. Most people get stuck because they make them in the wrong order — picking a vector database before deciding where bytes live, or choosing a table format before knowing whether they need one.
1. Where the bytes live. Self-hosted S3-compatible object storage. This is the foundation and the one decision that is genuinely hard to reverse, because everything above it speaks the S3 API to whatever you pick. MinIO is no longer the default answer — it went to maintenance mode in December 2025 and the main repository was archived read-only in April 2026. The live alternatives are SeaweedFS, Garage, RustFS and Ceph for larger deployments. Guide 8 covers the egress and lock-in argument for staying S3-compatible rather than S3.
2. Whether you need a table format at all. You probably don't, at first. A table format — Iceberg, Delta Lake, Hudi — buys you atomic writes, schema evolution and time travel over files in a bucket. If you are appending Parquet and reading it back, plain files are fine and simpler. Add a format when concurrent writers or schema drift start hurting. Guide 7 is the comparison; Guide 2 explains the small files problem that will eventually force the decision for you.
3. The query engine — and this is the layer October changed. DuckDB and Polars both read Parquet directly from object storage on a single machine. The historical catch was memory: exceed RAM and the job died, which pushed people to clusters they did not otherwise need.
Polars 2.0 turned the out-of-core spill-to-disk engine on by default, kicking in at roughly 80% of available RAM against a default 64 GB disk budget. That makes exceeding memory a normal operating condition rather than a failure. Joins and aggregations that needed distributed compute last quarter can run on one vertically scaled box. Guide 4 covers where DuckDB fits and where it doesn't — the boundary is still real, it just moved.
4. Vector search, if you are doing retrieval. The honest default for most people self-hosting is pgvector: if you already run Postgres, you already have a vector store, and you avoid operating a second database. Move to a dedicated engine — Qdrant, Weaviate, Milvus, LanceDB — when corpus size or query latency actually forces it, not before.
Milvus 3.0 is worth knowing about even if you do not deploy it, because it rebuilt around lake-native storage: the vector index is treated as a rebuildable derivative of what is in object storage, rather than the authoritative copy. That is the direction the whole category is moving, and it is the right mental model to hold regardless of which engine you run. Guide 33 is the selection path; Guide 23 covers decoupling compute from storage at billion scale.
5. Inference. Local models against local data. This is the layer where the local-first story is still weakest, and it is worth being clear about why: your model's working memory does not live on your object storage. KV-cache persistence to an S3-compatible tier is not a shipping product, in October or in the three windows before it. Guide 6 covers the real constraints of running LLMs over S3 data.
Where one box actually stops
Being honest about the ceiling is more useful than cheerleading the floor.
Concurrency, not size, is usually what breaks first. A single machine running Polars or DuckDB handles one serious query well. Ten analysts hitting it simultaneously is a different problem, and no amount of spill-to-disk solves it.
Spill-to-disk is slower than RAM, by a lot. "It completes instead of dying" is a real improvement and is not the same as "it is fast." If a job spills on every run, you have outgrown the box — the default is a safety net, not a capacity plan.
Durability is still your job. Self-hosted object storage on one machine is one disk failure from data loss. Erasure coding across drives, or replication to a second location, is not optional once the data matters.
The write path is the quiet constraint. Ingest that produces thousands of small files will degrade object-storage read performance long before your query engine is the bottleneck, which is the entire subject of Guide 2.
The actual recommendation
For most people reading this: self-hosted S3-compatible storage, Parquet files, no table format yet, Polars or DuckDB for query, pgvector if you need retrieval, and a local inference runtime. Add a table format when concurrency forces it. Add a dedicated vector database when corpus size forces it. Move off one box when concurrent users force it — which will happen before raw data size does.
That stack was defensible six months ago and it is more defensible now, because the memory ceiling that used to push people to clusters prematurely has a supported workaround as of this month.
Guide 32 — the local-first S3 data ecosystem — is the long-form version of this path for constrained environments, and it is the one to read next if you are actually building.