# Rotational Quantization (RQ)

:::callout{intent="info" title="Compression by Default"}
Starting with `v1.33`, you can set a default quantization for new collections using the [`DEFAULT_QUANTIZATION`](../database-configuration/overview.md#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](compression-rq-compression.md)), 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).
:::

[**Rotational quantization (RQ)**](../concepts/vector-quantization.md#rotational-quantization) is a fast vector compression technique that offers significant performance benefits. Three RQ variants are available in Weaviate:

- **8-bit RQ**: Up to 4x compression while retaining almost perfect recall (98-99% on most datasets). **Recommended** for most use cases.
- **4-bit RQ**: Up to 8x compression, roughly half the size of 8-bit RQ, and it depends on rescoring to reach comparable recall. Available for the `hnsw` index only.
- **1-bit RQ**: Close to 32x compression as dimensionality increases with moderate recall across various datasets.

## 8-bit RQ

:::callout{intent="info" title="Added in `v1.32` and `v1.35`"}
**8-bit Rotational quantization (RQ)** for the **HNSW vector index** was added in **`v1.32`**.

**8-bit Rotational quantization (RQ)** for the **flat vector index** was added in **`v1.35`**.
:::

[8-bit RQ](../concepts/vector-quantization.md#8-bit-rq) provides up-to 4x compression while maintaining 98-99% recall in internal testing. It is generally recommended for most use cases as the default quantization techniques.

### Enable compression for new collection

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

:::code-group{sync="languages"}
```python title="Python" {6}
from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
    name="MyCollection",
    vector_config=Configure.Vectors.text2vec_openai(
        quantizer=Configure.VectorIndex.Quantizer.rq()
    ),
    properties=[
        Property(name="title", data_type=DataType.TEXT),
    ],
)
```

```typescript title="JavaScript/TypeScript"
import weaviate, { configure } from 'weaviate-client';
```

```go title="Go" {2-4,10-13}
// Define the configuration for RQ. Setting 'enabled' to true
rq_config := map[string]interface{}{
  "enabled": true,
}

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

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

```java title="Java" {3}
client.collections.create("MyCollection",
    col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
        .quantization(Quantization.rq())
    )).properties(Property.text("title")));
```

```csharp title="C#" {11}
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.RQ(),
            }
        ),
    }
);
```
:::

### Enable compression for existing collection

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

:::code-group{sync="languages"}
```python title="Python"
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.rq(),
        ),
    )
)
```

```typescript title="JS/TS"
import { reconfigure } from 'weaviate-client';

const collection = client.collections.use("MyCollection")
```

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

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

```go title="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 RQ configuration to enable quantization
cfg["rq"] = map[string]interface{}{
  "enabled": true,
}

// 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 rq: %v", err)
}
```
:::

## 4-bit RQ

:::callout{intent="warning" title="Preview — added in `v1.39.0`"}
**4-bit Rotational quantization (RQ)** for the **HNSW vector index** was added in **`v1.39.0`** as a preview feature. The API may change in future releases.
:::

[4-bit RQ](../concepts/vector-quantization.md#4-bit-rq) stores each dimension in 4 bits instead of 8, so a compressed vector is about half the size of the 8-bit equivalent and roughly 8x smaller than the uncompressed vector. It sits between 8-bit RQ and 1-bit RQ: it trades some accuracy in the compressed distance calculation for a smaller index, and it depends more heavily on rescoring against the uncompressed vectors to recover that accuracy.

:::callout{intent="note" title="4-bit RQ requires the `hnsw` index"}
4-bit RQ is supported on the `hnsw` index type only. The `flat` and `hfresh` index types reject `bits` set to `4`, and a `dynamic` index only uses 4-bit RQ after it converts to HNSW. For the bit widths that each index type accepts, see [RQ parameters](#rq-parameters).
:::

### Enable compression for new collection

4-bit RQ can be enabled at collection creation time through the collection definition:

:::code-group{sync="languages"}
```python title="Python" {6-9}
from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
    name="MyCollection",
    vector_config=Configure.Vectors.text2vec_openai(
        quantizer=Configure.VectorIndex.Quantizer.rq(
            bits=4,
            rescore_limit=20,  # Optional: Number of candidates to fetch before rescoring
        )
    ),
    properties=[
        Property(name="title", data_type=DataType.TEXT),
    ],
)
```

```typescript title="JavaScript/TypeScript"
import weaviate, { configure } from 'weaviate-client';
```

```go title="Go" {2-6,12-15}
// Define the configuration for RQ. 'bits' set to 4 requires an hnsw index
rq_config := map[string]interface{}{
  "enabled":      true,
  "bits":         4,
  "rescoreLimit": 20, // Optional: Number of candidates to fetch before rescoring
}

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

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

```java title="Java" {3}
client.collections.create("MyCollection",
    col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
        .quantization(Quantization.rq(q -> q.bits(4)))
    )).properties(Property.text("title")));
```

```csharp title="C#" {11-15}
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.RQ
                {
                    Bits = 4,
                    RescoreLimit = 20, // Optional: Number of candidates to fetch before rescoring
                },
            }
        ),
    }
);
```
:::

### Enable compression for existing collection

4-bit RQ can also be enabled for an existing collection that is not yet compressed, by updating the collection definition. Weaviate re-encodes the existing vectors in the background.

:::code-group{sync="languages"}
```python title="Python"
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.rq(
                bits=4,
                rescore_limit=20,
            ),
        ),
    )
)
```

```go title="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 RQ configuration to enable 4-bit quantization
cfg["rq"] = map[string]interface{}{
  "enabled":      true,
  "bits":         4,
  "rescoreLimit": 20, // Optional: Number of candidates to fetch before rescoring
}

// 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 rq: %v", err)
}
```

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

```csharp title="C#"
await collection.Config.Update(c =>
{
    var vectorConfig = c.VectorConfig["default"];
    vectorConfig.VectorIndexConfig.UpdateHNSW(h =>
        h.Quantizer = new VectorIndex.Quantizers.RQ { Bits = 4, RescoreLimit = 20 }
    );
});
```
:::

## 1-bit RQ

:::callout{intent="info" title="Added in `v1.33` and `v1.35`"}
**1-bit Rotational quantization (RQ)** for the **HNSW vector index** was added in **`v1.33`**.

**1-bit Rotational quantization (RQ)** for the **flat vector index** was added in **`v1.35`**.
:::

[1-bit RQ](../concepts/vector-quantization.md#1-bit-rq) is an quantization technique that provides close to 32x compression as dimensionality increases. 1-bit RQ serves as a more robust and accurate alternative to [BQ](compression-bq-compression.md) with only a slight performance trade-off. While more performant than PQ in terms of encoding time and distance calculations, 1-bit RQ typically offers slightly lower recall than well-tuned [PQ](compression-pq-compression.md).

### Enable compression for new collection

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

:::code-group{sync="languages"}
```python title="Python" {6}
from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
    name="MyCollection",
    vector_config=Configure.Vectors.text2vec_openai(
        quantizer=Configure.VectorIndex.Quantizer.rq(bits=1)
    ),
    properties=[
        Property(name="title", data_type=DataType.TEXT),
    ],
)
```

```typescript title="JavaScript/TypeScript"
import weaviate, { configure } from 'weaviate-client';
```

```go title="Go" {2-5,11-14}
// Define the configuration for RQ. Setting 'enabled' to true
rq_config := map[string]interface{}{
  "enabled": true,
  "bits":    1,
}

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

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

```java title="Java" {3}
client.collections.create("MyCollection",
    col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
        .quantization(Quantization.rq(q -> q.bits(1)))
    )).properties(Property.text("title")));
```

```csharp title="C#" {11}
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.RQ { Bits = 1 },
            }
        ),
    }
);
```
:::

### Enable compression for existing collection

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

:::code-group{sync="languages"}
```python title="Python"
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.rq(bits=1),
        ),
    )
)
```

```typescript title="JS/TS"
import { reconfigure } from 'weaviate-client';

const collection = client.collections.use("MyCollection")
```

```go title="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 RQ configuration to enable scalar quantization
cfg["rq"] = map[string]interface{}{
  "enabled": true,
  "bits":    1,
}

// 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 rq: %v", err)
}
```

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

```csharp title="C#"
await collection.Config.Update(c =>
{
    var vectorConfig = c.VectorConfig["default"];
    vectorConfig.VectorIndexConfig.UpdateHNSW(h =>
        h.Quantizer = new VectorIndex.Quantizers.RQ { Bits = 1 }
    );
});
```
:::

## RQ parameters

To tune RQ, use these quantization and vector index parameters:

| Parameter               | Type    | Default                                                                  | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| :---------------------- | :------ | :----------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rq`: `bits`            | integer | `8`                                                                      | The number of bits used to quantize each data point. Value can be `8`, `4` or `1`, but not every index type accepts all three. The `hnsw` index type accepts `8`, `4` and `1`. The `flat` index type accepts only `8` and `1`. The `hfresh` index type accepts only `1`. <br><br>This parameter is fixed once RQ is enabled and cannot be changed afterwards. <br> <br>Learn more about [8-bit](../concepts/vector-quantization.md#8-bit-rq), [4-bit](../concepts/vector-quantization.md#4-bit-rq) and [1-bit](../concepts/vector-quantization.md#1-bit-rq) RQ.                                                                                                                                |
| `rq`: `rescoreLimit`    | integer | `20` (`hnsw`, 8-bit and 4-bit)<br>`512` (`hnsw`, 1-bit)<br>`-1` (`flat`) | The minimum number of candidates to fetch before rescoring. Mutable at any time. <br><br>The default depends on the vector index type, and under `hnsw` also on `bits`: `20` for 8-bit and 4-bit RQ, and `512` for 1-bit RQ. Under the `flat` index type the default is `-1`, which lets Weaviate pick the limit. <br><br>The Java client sends this parameter under a field name that Weaviate does not read, so values set from that client are ignored and the server default applies. <br><br>These defaults apply to the `hnsw` and `flat` index types. For the HFresh index, see [HFresh index parameters](../reference-configuration/indexing-vector-index.md#hfresh-index-parameters). |
| `rq` : `cache`          | boolean | `false`                                                                  | Whether to cache the vectors in memory.<br> (only when using the `flat` vector index type)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `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](../indexing/vector-index.md#vector-cache-considerations).                                                                                                                                                                                                                                                                                                                                                                                                                        |

RQ supports the `cosine`, `dot` and `l2-squared` distance metrics. Other distance metrics are not supported.

:::code-group{sync="languages"}
```python title="Python" {6-13}
from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
    name="MyCollection",
    vector_config=Configure.Vectors.text2vec_openai(
        quantizer=Configure.VectorIndex.Quantizer.rq(
            bits=8,  # Optional: Number of bits
            rescore_limit=20,  # Optional: Number of candidates to fetch before rescoring
            cache=True,  # Optional: Enable caching for flat index (enabled by default for for HNSW)
        ),
        vector_index_config=Configure.VectorIndex.flat(
            vector_cache_max_objects=100000,  # Optional: Maximum number of objects in the memory cache
        ),
    ),
    properties=[
        Property(name="title", data_type=DataType.TEXT),
    ],
)
```

```typescript title="JavaScript/TypeScript"
import weaviate, { configure } from 'weaviate-client';
```

```go title="Go" {2-6,13}
// Define a custom configuration for RQ
rq_with_options_config := map[string]interface{}{
  "enabled":      true,
  "bits":         8,  // Optional: Number of bits
  "rescoreLimit": 20, // Optional: Number of candidates to fetch before rescoring
}

// Define the class schema with the custom RQ config and other HNSW settings
class_with_options := &models.Class{
  Class:      className,
  Vectorizer: "text2vec-openai",
  VectorIndexConfig: map[string]interface{}{
    "rq": rq_with_options_config,
  },
}

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

```java title="Java" {3-5}
client.collections.create("MyCollection",
    col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
        .quantization(Quantization.rq(q -> q.bits(8) // Optional: Number of bits
            .rescoreLimit(20) // Optional: Number of candidates to fetch before rescoring
        ))
    )).properties(Property.text("title")));
```

```csharp title="C#" {11-15}
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.RQ
                {
                    Bits = 8, // Optional: Number of bits
                    RescoreLimit = 20, // Optional: Number of candidates to fetch before rescoring
                },
            }
        ),
    }
);
```
:::

<!--
:::callout{intent="note" title="Maximum query performance"}

For maximum query performance with minimal recall impact, consider setting `rescoreLimit` to 0. This disables rescoring and can significantly boost QPS (queries per second) while only causing a very minor drop in recall.

:::
-->

## Additional considerations

### Multiple vector embeddings (named vectors)

Collections can have multiple [named vectors](../reference-configuration/collections.md#multiple-vector-embeddings-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](compression-pq-compression.md), [BQ](compression-bq-compression.md), [RQ](compression-rq-compression.md), [SQ](compression-sq-compression.md), or no compression.

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

:::callout{intent="info" title="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. Just like with single vectors, multi-vectors support [PQ](compression-pq-compression.md), [BQ](compression-bq-compression.md), [RQ](compression-rq-compression.md), [SQ](compression-sq-compression.md), or no compression.

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.

:::callout{intent="note" title="Multi-vector performance"}
RQ supports multi-vector embeddings. Each token vector is rounded up to a multiple of 64 dimensions, which may result in less than the nominal compression ratio for very short vectors. This is a technical limitation that may be addressed in future versions.
:::

## Further resources

- [Starter guides: Compression](../starter-guides/managing-resources-compression.md)
- [Reference: Vector index](../reference-configuration/indexing-vector-index.md)
- [Concepts: Vector quantization](../concepts/vector-quantization.md)
- [Concepts: Vector index](../indexing/vector-index.md)

## Questions and feedback

Have a question or feedback? Here's how to reach us.

::::card-grid
:::card{title="Community Forum" href="https://forum.weaviate.io/c/support" icon="messages-square"}
Ask questions and connect with other developers on our **Community forum**.
:::

:::card{title="Support" href="/guides/support-overview" icon="life-buoy"}
Weaviate Cloud user or customer? Find the right channel on the **Support page**.
:::
::::

## Related pages

- [Agents](./agents-index.md)
- [AI-assisted Weaviate code generation](./ai-assisted-vibe-coding-index.md)
- [APIs](./apis-index.md)
- [Authorization and authentication](./authorization-and-authentication-index.md)
- [Benchmarks](./benchmarks-index.md)
- [Best practices](./best-practices-index.md)
- [Client libraries](./clients-index.md)
- [Client Libraries / SDKs](./client-libraries-index.md)
- [Cloud](./cloud-index.md)
- [Cloud account management](./cloud-account-management-index.md)

# Agent Instructions

This portal answers questions programmatically. To receive a synthesized,
source-cited answer instead of crawling page by page, append the `?ask=`
query parameter to any page URL on this site:

    /guides/quickstart?ask=how+do+I+authenticate

Optional parameters:

- `&goal=<what-you-are-trying-to-do>` steers the answer toward your
  objective (e.g. `&goal=write+a+python+client`).
- `&version=<label>` scopes the answer to a mounted version when the
  portal publishes more than one.

The response is `text/markdown`: the answer followed by a `# Sources` list
of the portal pages it was grounded in. Status codes are the contract:

- `200` — the answer; `402` — the portal owner’s plan or answer credits are
  exhausted (surface this to your operator; do NOT retry); `429` — you are
  rate-limited; back off for the `Retry-After` seconds; `503` — the answer
  lane is temporarily unavailable; fall back to crawling the `.md` pages.

For the full corpus map read `llms.txt` at the site root; for the tool
surface (search + page fetch as MCP tools) see `/mcp`.
