StrictModeConfig

@Serializable
data class StrictModeConfig(val enabled: Boolean? = null, val maxQueryLimit: Int? = null, val maxTimeout: Int? = null, val unindexedFilteringRetrieve: Boolean? = null, val unindexedFilteringUpdate: Boolean? = null, val searchMaxHnswEf: Int? = null, val searchAllowExact: Boolean? = null, val upsertMaxBatchSize: Int? = null, val searchMaxBatchSize: Int? = null, val readRateLimit: Int? = null, val writeRateLimit: Int? = null, val maxPointsCount: Long? = null, val filterMaxConditions: Int? = null, val maxDiskUsagePercent: Int? = null, val maxResidentMemoryPercent: Int? = null)

Per-collection limits Qdrant enforces on the requests it accepts.

The point of strict mode is that the refusal happens on the server. A limit a client checks is a limit the next client does not check, and a shared cluster has more than one client. These are the knobs an operator sets so a query that would take the node down is refused rather than served.

qdrant.updateCollection("docs") {
strictMode { enabled = true; maxQueryLimit = 1000; unindexedFilteringRetrieve = false }
}

Two of these describe the cluster's health rather than a policy, and are the reason this type is here rather than only in a future release. maxDiskUsagePercent and maxResidentMemoryPercent make a node refuse writes while still serving reads once it crosses them, which is the degraded state an operator most needs the client to be predictable in: Kdrant raises dev.kdrant.KdrantException.ReadOnly for it, which is retryable, rather than the credential failure a bare 403 would otherwise look like.

Which server versions enforce those two is worth knowing before relying on them. Qdrant 1.18 refuses writes over the ceiling. Qdrant 1.19 deprecated the family in favour of a global quota API and does not, so a collection configured this way on 1.19 accepts the setting and keeps accepting writes. The rate limits below are enforced by both.

Qdrant takes further limits this does not model — the per-vector multivector and sparse sub-configs, and the payload-index count. They are additions to this class rather than a different shape, which is why it is a data class with every field defaulted to the server's own choice.

Constructors

Link copied to clipboard
constructor(enabled: Boolean? = null, maxQueryLimit: Int? = null, maxTimeout: Int? = null, unindexedFilteringRetrieve: Boolean? = null, unindexedFilteringUpdate: Boolean? = null, searchMaxHnswEf: Int? = null, searchAllowExact: Boolean? = null, upsertMaxBatchSize: Int? = null, searchMaxBatchSize: Int? = null, readRateLimit: Int? = null, writeRateLimit: Int? = null, maxPointsCount: Long? = null, filterMaxConditions: Int? = null, maxDiskUsagePercent: Int? = null, maxResidentMemoryPercent: Int? = null)

Properties

Link copied to clipboard
@SerialName(value = "enabled")
val enabled: Boolean?

Whether the limits below are enforced at all.

Link copied to clipboard
@SerialName(value = "filter_max_conditions")
val filterMaxConditions: Int?

Conditions one filter may combine.

Link copied to clipboard
@SerialName(value = "max_disk_usage_percent")
val maxDiskUsagePercent: Int?

Disk usage, as a percentage, past which the node refuses writes and keeps serving reads. This is the read-only state dev.kdrant.KdrantException.ReadOnly names.

Link copied to clipboard
@SerialName(value = "max_points_count")
val maxPointsCount: Long?

Most points the collection may hold.

Link copied to clipboard
@SerialName(value = "max_query_limit")
val maxQueryLimit: Int?

Largest limit an API without its own cap will accept.

Link copied to clipboard
@SerialName(value = "max_resident_memory_percent")
val maxResidentMemoryPercent: Int?

Resident memory, as a percentage, past which memory-consuming writes are refused.

Link copied to clipboard
@SerialName(value = "max_timeout")
val maxTimeout: Int?

Largest timeout, in seconds, a request may ask for.

Link copied to clipboard
@SerialName(value = "read_rate_limit")
val readRateLimit: Int?

Reads per minute per replica; over it, Qdrant answers 429.

Link copied to clipboard
@SerialName(value = "search_allow_exact")
val searchAllowExact: Boolean?

Whether an exact (brute-force) search is allowed.

Link copied to clipboard
@SerialName(value = "search_max_batchsize")
val searchMaxBatchSize: Int?

Most searches one batch may carry.

Link copied to clipboard
@SerialName(value = "search_max_hnsw_ef")
val searchMaxHnswEf: Int?

Largest hnswEf a search may ask for.

Link copied to clipboard
@SerialName(value = "unindexed_filtering_retrieve")
val unindexedFilteringRetrieve: Boolean?

Allow filtering a search on a payload field with no index. false turns a full scan into an error.

Link copied to clipboard
@SerialName(value = "unindexed_filtering_update")
val unindexedFilteringUpdate: Boolean?

Allow filtering an update on a payload field with no index.

Link copied to clipboard
@SerialName(value = "upsert_max_batchsize")
val upsertMaxBatchSize: Int?

Most points one upsert may carry.

Link copied to clipboard
@SerialName(value = "write_rate_limit")
val writeRateLimit: Int?

Writes per minute per replica; over it, Qdrant answers 429.