Weaviate vs Vespa in Docker: 208MB Against 1.72GB, and the 4GB Wall That Decides Your VPS
Two docker run commands on the same 2-core, 1.6GB box: Weaviate answers 200 in eight seconds, Vespa exits with code 2 in five. The difference is not in any feature comparison table.
💡 What You Will Learn
Two docker run commands on the same 2-core, 1.6GB box: Weaviate answers 200 in eight seconds, Vespa exits with code 2 in five. The difference is not in any feature comparison table.
📜 Table of Contents
Two commands, one afternoon. The Weaviate container answered 200 in eight seconds. The Vespa container exited with code 2 in five, before a single Java log line. Every comparison table ranks hybrid retrieval and large-scale ranking; none of them mentions that these two images disagree about what a machine is.
The short version: on 2 cores and 1.6GB, Weaviate runs and Vespa does not. No flag fixes that. Everything below is measured on that box, with the commands to reproduce it.
1. Image size and process model
Host: 2-core Intel Xeon Platinum, 1.6GB RAM, 40GB disk, Docker 24.0.9, kernel 6.6.102.
| Item | Weaviate 1.40.3 | Vespa |
|---|---|---|
| Image size (docker images) | 208MB | 1.72GB |
| Pull time (same link) | under a minute | 1m48s |
| Processes inside | one Go binary | configserver and configproxy JVMs, plus content node and log service |
| Ports | 8080 (HTTP) | 8080 query, 19071 config |
| Readiness | /v1/.well-known/ready returns 200 | 19071/state/v1/health |
| Cold start to 200 here | 7.97s | exit 2 after 5.4s |
The size gap is not lazy packaging. Weaviate is a single Go process that loads capability as modules; /v1/meta lists them by family (text2vec-, multi2vec-, reranker-, generative-), and you only pull the backends you use. Vespa is a JVM system: a config server JVM, a config proxy JVM, then a content node that actually holds data. Each one wants its share of RAM and none of them can skip it.
2. Weaviate under a 600MB hard cap
docker run -d --name wv --memory=600m -p 8080:8080 \ -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \ -e DEFAULT_VECTORIZER_MODULE=none \ -e PERSISTENCE_DATA_PATH=/var/lib/weaviate \ -e CLUSTER_HOSTNAME=node1 \ semitechnologies/weaviate:latest
Cold start to a 200 on the readiness endpoint took 7.97s, polled every 200ms. Idle docker stats read 10.9MB; a second container with identical flags read 16.5MB.
Then a class with self-provided vectors, 10,000 objects at 384 dimensions, batches of 100, 100 requests: 32.12s, or 311 objects per second. Memory after the load: 80.1MB. An aggregate count returned 10,000, nothing dropped. The vectors are random numbers on purpose, they only exercise write and query paths and say nothing about recall.
Then 30 nearest-neighbour queries, top 10: p50 474ms, p90 1309ms, worst 12.9s. The outlier is not a mystery. The write had just finished and HNSW was still building; with the graph incomplete the query falls back to a scan. In production, gate traffic on index completion or push bulk writes off-peak. This box was also serving a site and a stats service, so treat these numbers as conservative.
3. Vespa: the JVM never started
Same command, image swapped to vespaengine/vespa:latest. The container exited after 5.4s with code 2. First log line, verbatim:
panic: Running the Vespa container image requires at least 4GB available memory. See the relevant docs (https://docs.vespa.ai/en/operations/self-managed/docker-containers.html#memory) or set VESPA_IGNORE_NOT_ENOUGH_MEMORY=true
The entrypoint does the check itself, so this is not a kernel OOM kill. Java had not started; the image counted the machine's memory first.
With VESPA_IGNORE_NOT_ENOUGH_MEMORY=true the container reaches Up. For three minutes 19071/state/v1/health returned 000 and the query port did the same, docker logs produced nothing in 25 seconds, and host load average climbed from 0.3 to 24. The container was alive; the service was not.
The docs put a single-node application at 4GB minimum and note on the same page that too little memory is the most common Docker problem with Vespa. This machine has 1.6GB total. That is not a tuning gap, it is a class of hardware. Arguing about Vespa's ranking features on a box like this is pointless when the box cannot host it.
4. Two compose files that work
The Weaviate one mirrors the test above. Note the health check uses wget: the image ships busybox wget and no curl, so a curl-based check stays unhealthy forever.
services:
weaviate:
image: semitechnologies/weaviate:latest
restart: unless-stopped
ports: ["127.0.0.1:8080:8080"]
environment:
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
DEFAULT_VECTORIZER_MODULE: "none"
PERSISTENCE_DATA_PATH: "/var/lib/weaviate"
CLUSTER_HOSTNAME: "node1"
volumes: ["./wv-data:/var/lib/weaviate"]
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/v1/.well-known/ready"]
interval: 10s
timeout: 3s
retries: 5
The Vespa one is for 4GB and up. Run docker info | grep "Total Memory" before you start it:
services:
vespa:
image: vespaengine/vespa:latest
hostname: vespa-container
ports: ["8080:8080", "19071:19071"]
ulimits:
nofile: {soft: 65536, hard: 65536}
nproc: 4096
The hostname is not decorative: the official run command pins vespa-container, the config service registers nodes under it, so keep that value in the compose field. The ulimits are not optional either; the docs ask for nofile and nproc at the system limits or processes inside will not start. Publish 8080 only. 19071 is the config service, and exposing it hands your cluster definition to anyone who can reach it.
5. Choose by memory budget first
- Under 4GB: Weaviate is the only one of the two that gets in. Cross Vespa off regardless of its feature sheet.
- Multi-phase ranking, ranking expressions, online model inference: Vespa's home turf, starting at 8GB. Not an option on a small VPS.
- Vectorization and hybrid search out of the box: Weaviate's modules are listed in
/v1/meta; wire one text2vec backend and you skip building an embedding service. - Thin ops team: Weaviate is one process and
docker logsis the whole story. Vespa first requires understanding how the config server and the content node relate, and failures come with far more to read.
I left Weaviate on the small box and deferred Vespa until there is an 8GB machine to test on. Feature comparison tables are everywhere; none of them tell you that half the candidates cannot start on the machine you already have.
## Related - [Weaviate (16,699 stars) in 2026: hybrid search and generative modules](/post/weaviate-vector-database-2026) - [Vespa (7,037 stars) in 2026: the big-data serving engine for vector search and ranking](/post/vespa-search-engine-2026) - [Self-hosted vector databases in 2026: Qdrant, Milvus, Chroma](/post/vector-database-self-hosted-guide-20260802) - [Vector database comparison 2026: Chroma, Qdrant, Pinecone, Weaviate](/post/vector-database-comparison-2026-chroma-qdrant-pinecone) - [Deploying AI agents with Docker Compose](/post/ai-agent-docker-compose-deploy-2026)Written by our editorial team; tools listed here are tested or verified against public sources. Links point to official sites or GitHub repos for reference only โ no paid placements.