Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant

If you build on the JVM and want to use Qdrant, the official client is io.qdrant:client — and it’s built for Java. Every call returns a ListenableFuture, requests are assembled with protobuf builders, and it drags a gRPC/Netty stack onto your classpath…


This content originally appeared on DEV Community and was authored by AS

If you build on the JVM and want to use Qdrant, the official client is io.qdrant:client — and it's built for Java. Every call returns a ListenableFuture, requests are assembled with protobuf builders, and it drags a gRPC/Netty stack onto your classpath. From Kotlin, that means fighting the language:

// official Java client, from Kotlin
val future: ListenableFuture<UpdateResult> = client.upsertAsync("articles", points)
val result = future.get() // block, or bolt on a future→coroutine bridge yourself

You reach for coroutines, you get futures. You want a DSL, you get protobuf builders.

Meet Kdrant

Kdrant is the client you'd actually want to write Kotlin against:

  • Coroutine-first — every operation is a suspend function, with cooperative cancellation and timeouts
  • Type-safe DSLs for collections, points, payloads, and filters
  • Small footprint — a pure-Kotlin REST engine on Ktor + kotlinx-serialization; no gRPC, Netty, or protobuf
  • Typed errors — a sealed KdrantException you can handle exhaustively

It's stable (1.1.0, SemVer) and published to Maven Central under io.github.nacode-studios.

Quick start

Requires JDK 17+. One dependency:

dependencies {
    implementation("io.github.nacode-studios:kdrant-transport-rest:1.1.0")
}

Spin up Qdrant locally:

docker run -p 6333:6333 qdrant/qdrant

Connect, create a collection, upsert, search:

val qdrant = Kdrant(host = "localhost", port = 6333) {
    apiKey = System.getenv("QDRANT_API_KEY") // omit for a local, unauthenticated node
    requestTimeout = 5.seconds
}

qdrant.use { client ->
    client.createCollection("articles") {
        vector { size = 1_536; distance = Distance.COSINE }
    }

    client.upsert("articles", wait = true) {
        point(id = 1) {
            vector(embedding) // your List<Float> from any embedding model
            payload("title" to "Introduction", "lang" to "en", "year" to 2026)
        }
    }

    val hits = client.search("articles") {
        query(queryVector)
        limit = 5
        filter { must { "lang" eq "en" } }
    }
}

Kdrant stores and searches vectors you already have — it does not generate embeddings.

A filter DSL that reads like Kotlin

Qdrant's full filtering model, expressed declaratively:

val query = filter {
    must {
        "lang" eq "en"
        "year" gte 2024
        "price" between 10.0..99.0
    }
    should {
        matchAny("tag", "featured", "promo")
        geoRadius("location", GeoPoint(lon = 13.40, lat = 52.52), radius = 5_000.0)
    }
    mustNot { "archived" eq true }
}

Decode results straight into your types

@Serializable data class Article(val title: String, val lang: String)

val articles: List<Hit<Article>> = qdrant.searchAs<Article>("articles") {
    query(queryVector); limit = 5
}
val first: Article? = articles.firstOrNull()?.payload

Hybrid search (dense + sparse)

The modern /points/query engine is fully supported. Fuse several prefetch sources with Reciprocal Rank Fusion for true dense + keyword hybrid search:

val hits = qdrant.search("articles") {
    prefetch { query(denseVector); using = "text"; limit = 50 }
    prefetch { querySparse(indices, values); using = "keywords"; limit = 50 }
    rrf()   // or dbsf()
    limit = 10
}

recommend / discover / context, grouped and batch search, multi-vectors, and a Flow-based scroll are all there too.

Building RAG? It plugs in.

Kdrant ships first-class integrations so you don't wire it by hand:

  • Spring Boot starter — an auto-configured QdrantClient bean
  • Spring AI — implements VectorStore
  • LangChain4j — implements EmbeddingStore

There's a runnable example-rag service (ingest → embed → store → retrieve) with a docker-compose for Qdrant, so you can see it end to end.

The honest tradeoff

For raw throughput and streaming, gRPC/HTTP2 still wins — reach for the official client when that is your bottleneck. Kdrant trades that for idiomatic Kotlin and a much smaller footprint:

Kdrant Official io.qdrant:client
Wire protocol REST over Ktor CIO gRPC (HTTP/2)
Heavy deps none — pure Kotlin shaded Netty, protobuf, gRPC, Guava
Added footprint ~3–5 MB ~15–20 MB
API style suspend + Flow, DSL ListenableFuture, protobuf builders
GraalVM native friendly needs gRPC/Netty/protobuf config

For typical RAG and embedding-search workloads, that's a trade I'll take.

Try it

Feedback is very welcome — especially on API ergonomics. If there's something you'd want from a Kotlin-native Qdrant client, open an issue and let's talk.


This content originally appeared on DEV Community and was authored by AS


Print Share Comment Cite Upload Translate Updates
APA

AS | Sciencx (2026-07-21T22:36:55+00:00) Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant. Retrieved from https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/

MLA
" » Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant." AS | Sciencx - Tuesday July 21, 2026, https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/
HARVARD
AS | Sciencx Tuesday July 21, 2026 » Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant., viewed ,<https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/>
VANCOUVER
AS | Sciencx - » Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/
CHICAGO
" » Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant." AS | Sciencx - Accessed . https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/
IEEE
" » Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant." AS | Sciencx [Online]. Available: https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/. [Accessed: ]
rf:citation
» Kdrant: an idiomatic, coroutine-first Kotlin client for Qdrant | AS | Sciencx | https://www.scien.cx/2026/07/21/kdrant-an-idiomatic-coroutine-first-kotlin-client-for-qdrant/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.