Weaviate docker container consume 35gb of memory with only 100k records

I am using the following:

docker run --name weaviate_instance --memory=36g -p 8080:8080 -p 50051:50051 -v /Volumes/weaviate:/data cr.weaviate.io/semitechnologies/weaviate:1.24.11

after this, I imported 100k records with 768x1 vectors. It is able to import all these without hitting memory limit. However, when I restarted it and let it sit idle, it slowly consumed up to 33.75gb and then just died. I am surprised since I was informed weaviate should handle >1 million.

after some reading I suspect I need to lower vectorCacheMaxObjects. If this is the right thing to do, I can’t find any documentation on how to do it after you have already created the schema (class obj) and already imported.

right now, if I start my docker container, it will die within 3 min. so I am not sure if I have no choice but delete the container and start from scratch with a lower vectorCacheMaxObjects during schema creation and batch import.

hi @00.lope.naughts !! Welcome to our community :hugs:

That is not really expected.

By default, weaviate comes with the environment variable LIMIT_RESOURCES set to false.

This means it will eat up all resources it needs, considering it is available. :slight_smile:

Check this documentation on resource planning:

Not sure why it died or are using that amount of memory. Can you provide any logs on that?

Now, for changing a collection configuration, be aware of the mutability of a collection schema, as described here

If the configuration is not mutable, you will need to create a new collection and migrate your data over to that new collection. We have a nice guide that can help you on that here.

Now, just for “fun” I have created a test environment here, using that very same docker command you provided (only changed memory to 10g):

import weaviate
import numpy as np
import weaviate.classes as wvc

client = weaviate.connect_to_local()

collection = client.collections.create(
    "Question",
    vectorizer_config=wvc.config.Configure.Vectorizer.none(),
    vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
        distance_metric=wvc.config.VectorDistances.COSINE # select prefered distance metric
    ),
)

with collection.batch.dynamic() as batch:
    for i in range(100000):
        batch.add_object(
            properties={"data": "data " + str(i)},
            vector=np.random.rand(768)
        )

This will basically import 100k objects, with random vectors of 768 dimensions.

It took 2.44 minutes to ingest all that data (on a macbook pro m2 with 32G, everything running local), and is consuming around 1G of memory. I was able to kill the docker process and start it again.

Can you make sure you have only those 100k objects and has not imported in loop? (I have seen this before :thinking: )

You can do that with:

collection.aggregate.over_all(total_count=True)

and it should return:
AggregateReturn(properties={}, total_count=100000)

Let me know if this helps :slight_smile:

Thanks for your prompt respond. I am totally new to weaviate. I will go through the doc and understand the basic. One general question I have concerning that doc is I don’t even know how to change those parameters without keep recreating new docker container, or schema (the class obj) and deleting all data in the process. If there are other tutorials that focus on how to change things after an initial setup, that will be nice.

For my specific issue, I am confident it only contains 100k, I did a query like yours and confirm this. one diff is when I insert my data, I use the batch API like this:

with self.client.batch.configure(batch_size=batch_size) as batch:
  for listing_json in tqdm(listings):
    listing_json = self._preprocess_listing_json(listing_json)
    key = self._create_key(listing_json, embedding_type)

    try:
      batch.add_data_object(
          data_object=listing_json,
          class_name=class_name,
          vector=listing_json['embedding'],
          uuid=key
      )
    except ObjectAlreadyExistsException as e:
      etc etc

I do eventually have >1M so that resource planning guide would be required. however, I imagine 100k, I should be just “play” with it “out of the box”. I will try to reproduce it and post more logs. Another data point is I am running on a Mac with pretty of disk space, 12 CPUs/38 GPUs and 96gb. Of course it also depends on restriction docker places. But I also tried to allocate very generously at docker settings.

As mentioned on the docs, only some of the parameters are mutable.

For changing those parameters, check this doc:

Thanks!

Hi @00.lope.naughts
Can you please share if vectorCacheMaxObjects worked for you we are facing the same issue your help would be appreaciated :slight_smile:

@Samuel_Jude_S you mean for 100k objects?

The issue you are facing is also memory consumption?

I have difficulty changing things more dynamically, i.e. after you have created the docker container, defined your collection, and inserted data. so I have to delete the collection and re-define it like this:

collection = local_client.collections.create(
“Question”,
vectorizer_config=wvc.config.Configure.Vectorizer.none(),
vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
distance_metric=wvc.config.VectorDistances.COSINE, # select prefered distance metric
vector_cache_max_objects=2000000
),
)

I found it confusing 'cos I was introduced to some v3 syntax on one page, but decide to do it in v4 as recommended, and they just switched names on you. I am not clear how this specific param will solve (or not solve my issue). If you know, please post what it does. I will update what I find out could be wrong with my issue.

After some experimentation, I found what could be wrong. I batch insert a json which has a key (‘embedding’) that is list of float. The issue is that I am creating the collection with properties that include this key! (should have pop and assigned that to the vector). I am surprised that despite defining it explicitly (as Property) in my collection, my data violated the “schema” but weaviate is totally silent about it. I can imagine 768 numbers are being inverted indexed like mad and could explain my very slow batch inserts and extreme memory consumption.

I tried a barebone # of properties and it is behaving a lot better. Will add back to whole thing and hope all are still well.

Oh… I have seen this error before, hahaha.

It is fairly common, so don’t beat yourself :wink:

Here we can say those famous words:

“Not a bug, but a feature” hehehe

this was due to Auto Schema:

If you disable Auto Schema, and define your collection accordingly, it will complain about non expected properties while ingesting.

Thanks for sharing!

Hi Duda
Yes Iam trying to do a async indexing and import 200k plus records with weaviate ram of 60gb after import it quickly rises to max ram and it dies :confused: any thoughts on why this may happen?
Runnning in weaviate version 1.24.12

Docker stats :

Do you set resource limits to your docker container?

Maybe that can help.

Yes I am setting the limit_resources to true I am using Open AI vectors which are 1536d

I actually use docker compose to configure the weaviate instance like this:

environment:
PERSISTENCE_DATA_PATH: ‘/var/lib/weaviate’
LIMIT_RESOURCES: true

however, I haven’t figured out how to set this back to false, while keeping the docker container, collections, indexes and everything intact. Is this actually possible? or once you created it, you have to commit to it.

Hi! Considering you have mapped in your docker compose the /var/lib/weaviate to a docker persistent volume, it would be there after restarting.

So, considering you have this mapped, you can change the LIMIT_RESOURCES (or any other environment variable) to the value you want and restart docker.

this is in the docker-compose.yml, if I go change it and do the docker-compose command, it will wipe out my existing container and recreate a new one (instead of reconfiguring). this could be a limitation of docker itself? My question is if there’s another way to reset that LIMIT_RESOURCES env var AFTER you have already created the container.

I don’t think it will wipe out, but it will mount an empty volume on that path.

What you can do is to copy the data from the cluster to a folder, add the volume mapping, and move that back to the container that has the mapped volume.

You can change the LIMIT_RESOURCES, however you need to restart the container.

Facing same issue

when i have uploaded 12000 images it was taking 430MB eachnode
as i added more photos now it is 25k then it starts behaving weird, it start taking 6GB of ram each node as not much ram left in machine it restarted and again starting taking more ram and stuck in restarting loop , attaching image of logs

each image is around 35-50KB

logs images link → weaviate issue images - Google Drive

docker yml is below

cat docker-compose.yml
version: '3.3'
services:
  weaviate-node-1:
    init: true
    command:
    - --host
    - 0.0.0.0
    - --port
    - '8080'
    - --scheme
    - http
    image: cr.weaviate.io/semitechnologies/weaviate:1.24.10
    ports:
    - 8080:8080
    - 6060:6060
    - 50051:50051
    - 7007:2112
    restart: on-failure:0
    volumes:
      - ./data-node-1:/var/lib/weaviate
    environment:
      ASYNC_INDEXING: 'true'
      PROMETHEUS_MONITORING_ENABLED: 'true'
      LOG_LEVEL: 'debug'
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      CLUSTER_HOSTNAME: 'node1'
      CLUSTER_GOSSIP_BIND_PORT: '7100'
      CLUSTER_DATA_BIND_PORT: '7101'
      IMAGE_INFERENCE_API: http://xxx.xx.xxx.25:8000
      DEFAULT_VECTORIZER_MODULE: img2vec-neural
      ENABLE_MODULES: img2vec-neural
      GOMEMLIMIT: '3050MiB'
      LIMIT_RESOURCES: 'true'

    networks:
      - default
    deploy:
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.hostname == ubuntu-s-8vcpu-16gb-fra1-01

  weaviate-node-2:
    init: true
    command:
    - --host
    - 0.0.0.0
    - --port
    - '8080'
    - --scheme
    - http
    image: cr.weaviate.io/semitechnologies/weaviate:1.24.10
    ports:
    - 8081:8080
    - 6061:6060
    - 50052:50051
    restart: on-failure:0
    volumes:
      - ./data-node-2:/var/lib/weaviate
    environment:
      LOG_LEVEL: 'debug'
      QUERY_DEFAULTS_LIMIT: 25
      LIMIT_RESOURCES: 'true'
      GOMEMLIMIT : '3750MiB'
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      CLUSTER_HOSTNAME: 'node2'
      ASYNC_INDEXING: 'true'
      CLUSTER_GOSSIP_BIND_PORT: '7102'
      CLUSTER_DATA_BIND_PORT: '7103'
      CLUSTER_JOIN: 'weaviate-node-1:7100'
      IMAGE_INFERENCE_API: http://xxx.xx.xxx.25:8000
      DEFAULT_VECTORIZER_MODULE: img2vec-neural
      ENABLE_MODULES: img2vec-neural
    networks:
      - default
    deploy:
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.hostname == ubuntu-s-8vcpu-16gb-fra1-01

  weaviate-node-3:
    init: true
    command:
    - --host
    - 0.0.0.0
    - --port
    - '8080'
    - --scheme
    - http
    image: cr.weaviate.io/semitechnologies/weaviate:1.24.10
    ports:
    - 8082:8080
    - 6062:6060
    - 50053:50051
    restart: on-failure:0
    volumes:
      - ./data-node-3:/var/lib/weaviate
    environment:
      LOG_LEVEL: 'debug'
      ASYNC_INDEXING: 'true'
      LIMIT_RESOURCES: 'true'
      GOMEMLIMIT : '3750MiB'
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      CLUSTER_HOSTNAME: 'node3'
      CLUSTER_GOSSIP_BIND_PORT: '7104'
      CLUSTER_DATA_BIND_PORT: '7105'
      CLUSTER_JOIN: 'weaviate-node-1:7100'
      IMAGE_INFERENCE_API: http://xxx.xx.xxx.25:8000
      DEFAULT_VECTORIZER_MODULE: img2vec-neural
      ENABLE_MODULES: img2vec-neural
    networks:
      - default
    deploy:
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.hostname == ubuntu-s-8vcpu-16gb-fra1-01

networks:
  default:```



Schema is given below 

schemaConfig = {
‘class’: ‘TestImg16’,
‘vectorizer’: ‘img2vec-neural’,
“vectorIndexType”: “flat”,
“vectorIndexConfig”: {
“bq”: {
“enabled”: True,
“rescoreLimit”: 200,
“cache”: True,
},
},
‘moduleConfig’: {
‘img2vec-neural’: {
‘imageFields’: [
‘image’
]
}
},
‘properties’: [
{
“name”: “sku_id”,
“dataType”: [“string”]
},
{
“name”: “product_id”,
“dataType”: [“string”]
},
{
“name”: “brand”,
“dataType”: [“string”]
},
{
“name”: “some_i”,
“dataType”: [“string”]
},
{
“name”: “color”,
“dataType”: [“string”]
},
{
“name”: “parentCategory”,
“dataType”: [“string”]
},
{
“name”: “childCategories”,
“dataType”: [“text”],
“type”: “class”,
“cardinality”: “multiple”
}
]
}

try:
a = client.schema.create_class(schemaConfig)
print(“Schema defined”)
except Exception as e:
print(str(e) + “Schema already defined, skipping…”)




pushing in batch of 20 base_64_images given. below

public void pushToVectorDb(List<Map<String, Object>> dataObjs) {
if (dataObjs.size() > 0) {
ObjectsBatcher batcher = singleWeaviateClient.weaviateClientMethod().batch().objectsBatcher();
for (Map<String, Object> prop : dataObjs) {
batcher.withObject(WeaviateObject.builder()
.className(className)
.properties(prop)
.id(prop.get(“some_i”).toString())
.build());
}
Result<ObjectGetResponse> a = batcher
.withConsistencyLevel(ConsistencyLevel.ONE)
.run();

        for (ObjectGetResponse b : a.getResult()) {
            if (!(b.getResult().toString().contains
                    ("SUCCESS"))) {

                LOGGER.error("ERROR while bulk import -> " + b.getId());
                LOGGER.error("ERROR " + b.getResult().toString());
            } else {
                LOGGER.info("Completed bulk import -> " + b.getId());
            }
        }
    }
}

Map<String, Object> properties = new HashMap<>();
properties.put(“image”, finalObject1.base64Image);
properties.put(“sku_id”, finalObject1.sku_id);
properties.put(“product_id”, finalObject1.product_id);
properties.put(“brand”, finalObject1.brand);
properties.put(“some_i”, finalObject1.uuid.toString());
properties.put(“parentCategory”, finalObject1.parent_category);
properties.put(“childCategories”, childCategories.toArray(new String[0]));
properties.put(“color”, finalObject1.color);

            dataObjs.add(properties);