Quarkus Qdrant

A Quarkus extension for Qdrant, the open-source vector database. It gives you a QdrantClient to store, search, and manage vectors using the Qdrant REST API.

At a Glance

@Inject
QdrantClient qdrant;

// Create a collection
qdrant.createCollection("docs").vectorSize(384).distance("Cosine").execute();

// Index a point
qdrant.upsert("docs").point(new PointStruct(id, vector, payload)).execute();

// Search
List<ScoredPoint> results = qdrant.search("docs").vector(queryVec).limit(10).execute();

That’s it. No gRPC stubs, no channel management, no heavy dependencies.

Compatibility

This extension is tested against Qdrant 1.18.x. It should work with newer versions as well, since the REST client tolerates unknown fields from the API. If you encounter an issue with a newer Qdrant release, please report it.

Why Quarkus Qdrant?

REST instead of gRPC

The official Qdrant Java client uses gRPC, which brings a heavy dependency chain. This extension uses the Qdrant REST API through the Quarkus REST client instead. Fewer dependencies, faster builds, and native image support without extra configuration.

A real Quarkus extension

This is not a wrapper around an upstream library. It follows the Quarkus extension model: CDI injection, build-time optimization, health checks, and configuration via application.properties. It also allows extensions like quarkus-langchain4j to depend on a proper Quarkus extension rather than pulling in the gRPC client directly.

Fluent API

Every operation uses a builder pattern: qdrant.search("collection").vector(vec).limit(10).execute(). Readable and hard to misuse.

Dev Services

In dev and test mode, a Qdrant container starts automatically. No local install needed.

Dev Services

In dev and test mode, the extension starts a Qdrant container automatically. No configuration needed.

You can pre-create collections at startup:

quarkus.qdrant.devservices.collections.documents.vector-size=384
quarkus.qdrant.devservices.collections.documents.distance=Cosine
quarkus.qdrant.devservices.collections.products.vector-size=128
quarkus.qdrant.devservices.collections.products.distance=Euclid

You can fix the port if you need a stable URL:

quarkus.qdrant.devservices.port=6333

Dev Services is disabled automatically when quarkus.qdrant.host is explicitly set.

Configuring for production

Point to your Qdrant instance:

quarkus.qdrant.host=qdrant.example.com
quarkus.qdrant.port=6333

With API key and TLS:

quarkus.qdrant.host=qdrant.example.com
quarkus.qdrant.port=6333
quarkus.qdrant.api-key=your-api-key
quarkus.qdrant.use-tls=true

Named clients

The extension supports both a default client and named clients. Named clients are necessary when you need to connect to multiple Qdrant instances.

Default client

The default client uses bare properties:

quarkus.qdrant.host=qdrant.example.com
quarkus.qdrant.port=6333

Inject it with no qualifier:

@Inject
QdrantClient qdrant;

Configuring named clients

Named clients use a quoted key in the configuration:

quarkus.qdrant."secondary".host=qdrant-secondary.example.com
quarkus.qdrant."secondary".port=6333
quarkus.qdrant."secondary".api-key=your-api-key
quarkus.qdrant."secondary".use-tls=true

Injecting named clients

Use the @QdrantClientName qualifier:

@Inject
@QdrantClientName("secondary")
QdrantClient secondaryClient;

Each named client is an independent QdrantClient instance with its own connection configuration.

Health check

If you have the quarkus-smallrye-health extension, a readiness check is registered automatically. The health check covers all configured clients (default and named) and reports per-client status.

To disable it:

quarkus.qdrant.health.enabled=false

QdrantClient API reference

Operation Example

Create a collection

qdrant.createCollection("name").vectorSize(384).distance("Cosine").execute()

Upsert a single point

qdrant.upsert("name").point(point).execute()

Upsert multiple points

qdrant.upsert("name").points(pointList).execute()

Search

qdrant.search("name").vector(vec).limit(10).execute()

Delete by IDs

qdrant.delete("name").byIds(idList).execute()

Delete by filter

qdrant.delete("name").byFilter(filterMap).execute()

List collections

qdrant.listCollections()

Delete a collection

qdrant.deleteCollection("name")

What’s Next