---
title: "Scalar Quantization (SQ)"
description: "Scalar quantization (SQ) is a vector compression technique that can reduce the size of a vector."
url: https://docs.weaviate.io/weaviate/configuration/compression/sq-compression
---

# Scalar Quantization (SQ)

> [!NOTE]
>
> **Compression by Default**
>
> Starting with `v1.33`, you can set a default quantization for new collections using the [`DEFAULT_QUANTIZATION`](https://docs.weaviate.io/deploy/configuration/env-vars#DEFAULT_QUANTIZATION) environment variable. This variable is not set by default, meaning no quantization is applied unless you explicitly configure it. When set (e.g., to 8-bit [RQ quantization](https://docs.weaviate.io/weaviate/configuration/compression/rq-compression)), all newly created collections will use that quantization setting. Note that once set on a collection, quantization can't be disabled. Default quantization won't be applied to a collection if the index type isn't supported (for example PQ and SQ aren't supported for the flat index).

[**Scalar quantization (SQ)**](https://docs.weaviate.io/weaviate/concepts/vector-quantization#scalar-quantization) is a vector compression technique that can reduce the size of a vector.

To use SQ, enable it in the collection definition, then add data to the collection.

## Enable compression for new collection

SQ can be enabled at collection creation time through the collection definition:

**Python**

```py
from weaviate.classes.config import Configure

client.collections.create(
    name="MyCollection",
    vector_config=Configure.Vectors.text2vec_openai(
        name="default",
        quantizer=Configure.VectorIndex.Quantizer.sq(),
    ),
)
```

**JavaScript/TypeScript**

```ts
import { configure } from '@weaviate/node';

const collection = await client.collections.create({
  name: 'MyCollection',
  vectorizers: weaviate.configure.vectors.selfProvided({
    vectorIndexConfig: weaviate.configure.vectorIndex.hnsw({
      quantizer: weaviate.configure.vectorIndex.quantizer.sq(),
    })
  })
})
```

**Go (v5)**

```go
// Define the configuration for SQ. Setting 'enabled' to true
sq_config := map[string]interface{}{
  "enabled": true,
}

// Define the class schema
class := &models.Class{
  Class:      className,
  Vectorizer: "text2vec-openai",
  // Assign the SQ configuration to the vector index config
  VectorIndexConfig: map[string]interface{}{
  	"sq": sq_config,
  },
}

// Create the collection in Weaviate
err = client.Schema().ClassCreator().
  WithClass(class).
  Do(context.Background())
```

**Go (v6)**

```go
_, err := client.Collections.Create(ctx, collections.Collection{
  Name: "MyCollection",
  Vectors: map[string]collections.VectorConfig{
    "default": {
      Vectorizer: openai.Text2Vec{},
      // Set the index explicitly. The client sends compression only with it.
      Index: vectorindex.HNSW{},
      Compression: compression.SQ{},
    },
  },
})
if err != nil {
  // handle error
  panic(err)
}
```

**Java**

```java
client.collections.create("MyCollection",
    col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
        .quantization(Quantization.sq())
    )).properties(Property.text("title")));
```

**C#**

```csharp
await client.Collections.Create(
    new CollectionCreateParams
    {
        Name = "MyCollection",
        Properties = [Property.Text("title")],
        VectorConfig = Configure.Vector(
            "default",
            v => v.Text2VecTransformers(),
            index: new VectorIndex.HNSW
            {
                Quantizer = new VectorIndex.Quantizers.SQ(),
            }
        ),
    }
);
```

## Enable compression for existing collection

> [!NOTE]
>
> **Added in `v1.31`**
>
> The ability to enable SQ compression after collection creation was added in Weaviate `v1.31`.

SQ can also be enabled for an existing collection by updating the collection definition:

**Python**

```py
from weaviate.classes.config import Reconfigure

collection = client.collections.use("MyCollection")
collection.config.update(
    vector_config=Reconfigure.Vectors.update(
        name="default",
        vector_index_config=Reconfigure.VectorIndex.hnsw(
            quantizer=Reconfigure.VectorIndex.Quantizer.sq(
                rescore_limit=20
            ),
        )
    )
)
```

**JavaScript/TypeScript**

```ts
import { configure } from '@weaviate/node';

const collection = client.collections.use('MyCollection');

await collection.config.update({
  vectorizers: [
    weaviate.reconfigure.vectors.update({
      name: 'default',
      vectorIndexConfig: weaviate.reconfigure.vectorIndex.hnsw({
        quantizer: weaviate.reconfigure.vectorIndex.quantizer.sq({
          rescoreLimit: 20,
        }),
      }),
    }),
  ],
})
```

**Go (v5)**

```go
// Get the existing collection configuration
class, err := client.Schema().ClassGetter().
  WithClassName(className).Do(context.Background())

if err != nil {
  log.Fatalf("get class for vec idx cfg update: %v", err)
}

// Get the current vector index configuration
cfg := class.VectorIndexConfig.(map[string]interface{})

// Add SQ configuration to enable scalar quantization
cfg["sq"] = map[string]interface{}{
  "enabled":       true,
  "rescoreLimit":  200,   // Optional: number of candidates to fetch before rescoring
  "trainingLimit": 50000, // Optional: number of vectors to use for training
  "cache":         true,  // Optional: enable caching of quantized vectors
}

// Update the class configuration
class.VectorIndexConfig = cfg

// Apply the updated configuration to the collection
err = client.Schema().ClassUpdater().
  WithClass(class).Do(context.Background())

if err != nil {
  log.Fatalf("update class to use sq: %v", err)
}
```

**Go (v6)**

```go
// Coming soon
```

**Java**

```java
CollectionHandle<Map<String, Object>> collection =
    client.collections.use("MyCollection");
collection.config.update(c -> c.vectorConfig(VectorConfig
    .text2vecTransformers(vc -> vc.quantization(Quantization.sq()))));
```

**C#**

```csharp
await collection.Config.Update(c =>
{
    var vectorConfig = c.VectorConfig["default"];
    vectorConfig.VectorIndexConfig.UpdateHNSW(h =>
        h.Quantizer = new VectorIndex.Quantizers.SQ()
    );
});
```

## SQ parameters

To tune SQ, set these `vectorIndexConfig` parameters.

| Parameter | Type | Default | Details |
| - | - | - | - |
| `sq`: `enabled` | boolean | `false` | Uses SQ when `true`. The Python client does not use the `enabled` parameter. To enable SQ with the v4 client, set a `quantizer` in the collection definition. |
| `sq`: `rescoreLimit` | integer | `20` (`hnsw`) `-1` (`flat`) | The minimum number of candidates to fetch before rescoring. The default depends on the vector index type: `20` under `hnsw`, and `-1` under `flat`, which lets Weaviate pick the limit. |
| `sq`: `trainingLimit` | integer | 100000 | The size of the training set to determine scalar bucket boundaries. |
| `vectorCacheMaxObjects` | integer | `1e12` | Maximum number of objects in the memory cache. By default, this limit is set to one trillion (`1e12`) objects when a new collection is created. For sizing recommendations, see [Vector cache considerations](https://docs.weaviate.io/weaviate/concepts/vector-index#vector-cache-considerations). |

**Python**

```py
from weaviate.classes.config import Configure

client.collections.create(
    name="MyCollection",
    vector_config=Configure.Vectors.text2vec_openai(
        name="default",
        quantizer=Configure.VectorIndex.Quantizer.sq(
            rescore_limit=200,
            training_limit=50000,
            cache=True,
        ),
        vector_index_config=Configure.VectorIndex.hnsw(
            vector_cache_max_objects=100000,
        ),
    ),
)
```

**JavaScript/TypeScript**

```ts
import { configure } from '@weaviate/node';

const collection = await client.collections.create({
  name: 'MyCollection',
  vectorizers: weaviate.configure.vectors.selfProvided({
    vectorIndexConfig: weaviate.configure.vectorIndex.hnsw({
      quantizer: weaviate.configure.vectorIndex.quantizer.sq({
        rescoreLimit: 200,    // The minimum number of candidates to fetch before rescoring
        trainingLimit: 50000, // The size of the training set used to determine the bucket boundaries
      }),
      vectorCacheMaxObjects: 100000 // Maximum number of objects in the vector cache
    })
  })
})
```

**Go (v5)**

```go
// Define a custom configuration for SQ.
sq_with_options_config := map[string]interface{}{
  "enabled":       true,
  "rescoreLimit":  200,   // The number of candidates to fetch before rescoring
  "trainingLimit": 50000, // The number of vectors to use for training the quantizer
  "cache":         true,  // Enable caching of quantized vectors
}

// Define the class schema with the custom SQ config and other HNSW settings
class_with_options := &models.Class{
  Class:      className,
  Vectorizer: "text2vec-openai",
  VectorIndexConfig: map[string]interface{}{
  	"sq": sq_with_options_config,
  	"distance":              "cosine", // Set the distance metric for HNSW
  	"vectorCacheMaxObjects": 100000,   // Configure the vector cache
  },
}

// Create the collection in Weaviate
err = client.Schema().ClassCreator().
  WithClass(class_with_options).
  Do(context.Background())
```

**Go (v6)**

```go
_, err := client.Collections.Create(ctx, collections.Collection{
  Name: "MyCollection",
  Vectors: map[string]collections.VectorConfig{
    "default": {
      Vectorizer: openai.Text2Vec{},
      Compression: compression.SQ{
        RescoreLimit:  200,
        TrainingLimit: 50000,
        Cache:         true,
      },
      Index: vectorindex.HNSW{VectorCacheMaxObjects: 100000},
    },
  },
})
if err != nil {
  // handle error
  panic(err)
}
```

**Java**

```java
client.collections.create("MyCollection",
    col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
        .quantization(Quantization
            .sq(q -> q.cache(true).trainingLimit(50000).rescoreLimit(200)))
        .vectorIndex(Hnsw.of(c -> c.vectorCacheMaxObjects(100000)))
    )).properties(Property.text("title")));
```

**C#**

```csharp
await client.Collections.Create(
    new CollectionCreateParams
    {
        Name = "MyCollection",
        Properties = [Property.Text("title")],
        VectorConfig = Configure.Vector(
            "default",
            v => v.Text2VecTransformers(),
            index: new VectorIndex.HNSW
            {
                VectorCacheMaxObjects = 100000,
                Quantizer = new VectorIndex.Quantizers.SQ
                {
                    TrainingLimit = 50000,
                    RescoreLimit = 200,
                },
            }
        ),
    }
);
```

## Additional considerations

### Multiple vector embeddings (named vectors)

Collections can have multiple [named vectors](https://docs.weaviate.io/weaviate/config-refs/collections#named-vectors). The vectors in a collection can have their own configurations, and compression must be enabled independently for each vector. Every vector is independent and can use [PQ](https://docs.weaviate.io/weaviate/configuration/compression/pq-compression), [BQ](https://docs.weaviate.io/weaviate/configuration/compression/bq-compression), [RQ](https://docs.weaviate.io/weaviate/configuration/compression/rq-compression), [SQ](https://docs.weaviate.io/weaviate/configuration/compression/sq-compression), or no compression.

### Multi-vector embeddings (ColBERT, ColPali, etc.)

> [!NOTE]
>
> **Added in `v1.30`**

Multi-vector embeddings (implemented through models like ColBERT, ColPali, or ColQwen) represent each object or query using multiple vectors instead of a single vector. On an `hnsw` index, multi-vectors support [PQ](https://docs.weaviate.io/weaviate/configuration/compression/pq-compression), [BQ](https://docs.weaviate.io/weaviate/configuration/compression/bq-compression), [RQ](https://docs.weaviate.io/weaviate/configuration/compression/rq-compression), [SQ](https://docs.weaviate.io/weaviate/configuration/compression/sq-compression), or no compression. On an `hfresh` index (from `v1.40`), the MUVERA encoding is always compressed with 1-bit RQ.

During the initial search phase, compressed vectors are used for efficiency. However, when computing the `MaxSim` operation, uncompressed vectors are utilized to ensure more precise similarity calculations. This approach balances the benefits of compression for search efficiency with the accuracy of uncompressed vectors during final scoring.

## Further resources

- [Starter guides: Compression](https://docs.weaviate.io/weaviate/starter-guides/managing-resources/compression)
- [Reference: Vector index](https://docs.weaviate.io/weaviate/config-refs/indexing/vector-index)
- [Concepts: Vector quantization](https://docs.weaviate.io/weaviate/concepts/vector-quantization)
- [Concepts: Vector index](https://docs.weaviate.io/weaviate/concepts/vector-index)
