NoSQL and Other Stores

This section documents Quarkus 3.39.x (current) with 3.33.x LTS as the production recommendation, on the Java 17+ baseline, as published at the official Quarkus guides — which are the reference these pages are written and verified against.

Quarkus 4 raises the baseline to Java 21 (first release candidate planned for end of September 2026, see the Quarkus blog); readers upgrading past 3.39.x/3.33.x LTS should expect that change.

This content was generated with the assistance of AI and should be verified against those official guides before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

This page is a Quarkus-integration survey of non-relational stores: for each store it covers only the Quarkus extension surface — client setup, configuration properties, Dev Services, and Panache-style helpers where one exists — not the underlying technology itself. For the data model, query language, indexing, clustering, and operational concerns of any of these stores, see Database Development and its per-technology reference pages.

MongoDB

Extension setup and configuration

quarkus-mongodb-client adds the MongoDB client and wires it into Quarkus’s configuration and health/metrics infrastructure:

./mvnw quarkus:add-extension -Dextensions=mongodb-client
quarkus.mongodb.connection-string=mongodb://localhost:27017
quarkus.mongodb.database=bookstore

The native Java driver client and POJO codecs

A com.mongodb.client.MongoClient is injectable directly — the extension configures it from the quarkus.mongodb.* properties above, including registering the driver’s PojoCodecProvider so plain Java classes are read from and written to BSON documents automatically, with no hand-written codec or mapping annotation required:

package com.example.book;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@ApplicationScoped
public class BookMongoRepository {

    @Inject
    MongoClient mongoClient;

    public MongoCollection<Book> collection() {
        MongoDatabase database = mongoClient.getDatabase("bookstore");
        return database.getCollection("books", Book.class);
    }

    public void insert(Book book) {
        collection().insertOne(book);
    }
}
package com.example.book;

public class Book {

    public String title;
    public String author;
    public int publicationYear;

    public Book() {
    }

    public Book(String title, String author, int publicationYear) {
        this.title = title;
        this.author = author;
        this.publicationYear = publicationYear;
    }
}

Book needs no annotation at all — the driver’s POJO codec maps its public fields (or getter/setter pairs) to BSON fields by name, and back, on every read and write through collection().

MongoDB with Panache

quarkus-mongodb-panache layers an active-record API onto MongoDB that mirrors the shape of relational Panache (quarkus-hibernate-orm-panache) — see Panache: The Quarkus Data API for the general Panache API shape (list(), find(), persist(), and so on), which is not re-explained here:

package com.example.book;

import io.quarkus.mongodb.panache.PanacheMongoEntity;

public class Book extends PanacheMongoEntity {

    public String title;
    public String author;
    public int publicationYear;
}
package com.example.book;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class BookService {

    public List<Book> byAuthor(String author) {
        return Book.list("author", author);
    }

    public Book create(String title, String author, int publicationYear) {
        Book book = new Book();
        book.title = title;
        book.author = author;
        book.publicationYear = publicationYear;
        book.persist();
        return book;
    }
}

Dev Services for MongoDB

With quarkus-mongodb-client (or quarkus-mongodb-panache) on the classpath and no quarkus.mongodb.connection-string configured, Dev Services automatically starts a MongoDB container for quarkus:dev and ./mvnw test, and points quarkus.mongodb.connection-string at it — no manual container management, and no configuration needed for local development or tests.

Redis

See the Redis Reference for Redis’s own data structures, persistence, and clustering model, beyond the Quarkus client surface covered here.

Extension setup and configuration

./mvnw quarkus:add-extension -Dextensions=redis-client
quarkus.redis.hosts=redis://localhost:6379

The high-level data-structure API: RedisDataSource

io.quarkus.redis.datasource.RedisDataSource exposes one typed, structure-specific command group per Redis data structure — ValueCommands for strings, HashCommands for hashes, ListCommands for lists, and more — so calls stay type-safe instead of working with raw command names and untyped arguments:

package com.example.book;

import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.value.ValueCommands;
import io.quarkus.redis.datasource.hash.HashCommands;
import io.quarkus.redis.datasource.list.ListCommands;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@ApplicationScoped
public class BookCacheService {

    @Inject
    RedisDataSource redisDataSource;

    public void cacheTitle(String isbn, String title) {
        ValueCommands<String, String> values = redisDataSource.value(String.class);
        values.set(isbn, title);
    }

    public String cachedTitle(String isbn) {
        ValueCommands<String, String> values = redisDataSource.value(String.class);
        return values.get(isbn);
    }

    public void cacheDetails(String isbn, String author, String publicationYear) {
        HashCommands<String, String, String> hash = redisDataSource.hash(String.class);
        hash.hset(isbn, "author", author);
        hash.hset(isbn, "publicationYear", publicationYear);
    }

    public void recordRecentlyViewed(String isbn) {
        ListCommands<String, String> list = redisDataSource.list(String.class);
        list.lpush("recently-viewed", isbn);
        list.ltrim("recently-viewed", 0, 19);
    }
}

Low-level commands via RedisCommands

Anything the high-level, structure-specific API does not cover — an uncommon command, or one added to Redis after the high-level API was written — is reachable through the data source’s untyped command execution:

package com.example.book;

import io.quarkus.redis.datasource.RedisDataSource;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@ApplicationScoped
public class BookCacheAdminService {

    @Inject
    RedisDataSource redisDataSource;

    public void expireTitle(String isbn, long seconds) {
        redisDataSource.execute("EXPIRE", isbn, Long.toString(seconds));
    }
}

Pub/sub via PubSubCommands

package com.example.book;

import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.pubsub.PubSubCommands;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@ApplicationScoped
public class BookEventPublisher {

    @Inject
    RedisDataSource redisDataSource;

    public void publishNewBook(String isbn) {
        PubSubCommands<String> pubSub = redisDataSource.pubsub(String.class);
        pubSub.publish("new-books", isbn);
    }

    public void subscribeToNewBooks() {
        PubSubCommands<String> pubSub = redisDataSource.pubsub(String.class);
        pubSub.subscribe("new-books", message -> System.out.println("New book: " + message));
    }
}

Dev Services for Redis

With quarkus-redis-client on the classpath and no quarkus.redis.hosts configured, Dev Services starts a Redis container automatically for quarkus:dev and ./mvnw test.

Elasticsearch, OpenSearch, and Infinispan

Elasticsearch / OpenSearch: low-level REST client

quarkus-elasticsearch-rest-client (or quarkus-elasticsearch-java-client for the newer, typed Java API client) gives direct access to the Elasticsearch/OpenSearch REST API for applications that build and run their own requests rather than keeping an index synchronized with JPA entities:

./mvnw quarkus:add-extension -Dextensions=elasticsearch-rest-client
quarkus.elasticsearch.hosts=localhost:9200

Dev Services starts an Elasticsearch container automatically in dev/test mode when no quarkus.elasticsearch.hosts is configured.

Hibernate Search ORM + Elasticsearch

quarkus-hibernate-search-orm-elasticsearch keeps a full-text index in Elasticsearch/OpenSearch automatically in sync with Hibernate ORM entities: @Indexed marks an entity for indexing, and @FullTextField marks which fields are analyzed and searchable, with no manual reindexing code required for ordinary entity writes:

package com.example.book;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;

@Entity
@Indexed
public class Book {

    @Id
    @GeneratedValue
    public Long id;

    @FullTextField
    public String title;

    @FullTextField
    public String synopsis;
}
package com.example.book;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;

import org.hibernate.search.mapper.orm.session.SearchSession;

@ApplicationScoped
public class BookSearchService {

    @Inject
    SearchSession searchSession;

    @Transactional
    public List<Book> search(String terms) {
        return searchSession.search(Book.class)
                .where(f -> f.match().fields("title", "synopsis").matching(terms))
                .fetchHits(20);
    }
}

Infinispan

quarkus-infinispan-client connects to a remote Infinispan cluster and exposes a RemoteCache<K, V> — Infinispan’s own client cache API shape — for typed put/get operations against a named cache:

./mvnw quarkus:add-extension -Dextensions=infinispan-client
quarkus.infinispan-client.hosts=localhost:11222
quarkus.infinispan-client.username=admin
quarkus.infinispan-client.password=changeme
package com.example.book;

import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@ApplicationScoped
public class BookInfinispanCache {

    @Inject
    RemoteCacheManager remoteCacheManager;

    public Book cachedBook(Long id) {
        RemoteCache<Long, Book> cache = remoteCacheManager.getCache("books");
        return cache.get(id);
    }

    public void cacheBook(Long id, Book book) {
        RemoteCache<Long, Book> cache = remoteCacheManager.getCache("books");
        cache.put(id, book);
    }
}

Near-caching keeps a client-side copy of frequently-read entries so repeated reads avoid a round trip to the cluster; it is enabled per cache on the client configuration:

quarkus.infinispan-client.near-cache-max-entries=1000

Cassandra

The quarkus-cassandra-client extension wraps the DataStax Java driver and configures it from quarkus.cassandra.* properties (quarkus.cassandra.contact-points, quarkus.cassandra.local-datacenter, and so on); Cassandra’s own data-modeling concerns — partition keys, clustering columns, CQL — are not Quarkus-specific and are not repeated here. See Database Development for Cassandra data modeling and query design.

Quarkiverse-hosted stores

Several store integrations that used to ship as part of the core Quarkus platform have since moved to the Quarkiverse organization — a set of community-maintained Quarkus extensions with their own release cadence and support model, separate from first-party extensions published under io.quarkus. Each still works the same way from an application’s point of view (an extension dependency plus application.properties), but upgrading them tracks the Quarkiverse project’s own releases rather than the core Quarkus BOM.

  • Neo4j (io.quarkiverse.neo4j:quarkus-neo4j) — now Quarkiverse-hosted rather than a core Quarkus extension; see Neo4j Reference for the Neo4j reference itself.

  • DynamoDB (io.quarkiverse.amazonservices:quarkus-amazon-dynamodb) — part of the Quarkiverse Amazon Services extensions, not the core platform; see Database Development for key-value/wide-column data modeling guidance.

  • Couchbase (io.quarkiverse.couchbase:quarkus-couchbase) — Quarkiverse-hosted; see Couchbase Reference for the Couchbase reference itself.