Developer Guide: Quarkus Nanoservices with CockroachDB Using Reactive Panache
Absolutely! Here’s a final, comprehensive developer write-up incorporating everything we’ve agreed on — small reactive pools per nanoservice, named datasources, safe parallel access, and CockroachDB configuration. This is ready for your team to use.
Overview
Your Quarkus application is composed of ~20 nanoservices (Verticles) running inside the same JVM process. Each nanoservice behaves like a microservice with its own business logic and database access layer.
Goals:
Each nanoservice performs its own DB queries to CockroachDB.
Maintain logical isolation per nanoservice while running in the same JVM.
Manage database connections efficiently to avoid overload.
Use reactive programming (Panache Reactive) to maximize throughput.
Ensure safe parallel access by multiple nanoservices.
Key Architecture Decision
Each nanoservice will use a named reactive datasource with a very small connection pool.
This gives:
Isolation: Each nanoservice has its own pool, independent of others.
Tunable pools: Small pool sizes (e.g., 5 connections) reduce total connections while supporting high concurrency.
Future-proofing: Easy to move a nanoservice to a different database, schema, or credentials if needed.
Total connections = sum of all nanoservice pools (e.g., 20 nanoservices × 5 connections = 100 connections).
Each pool is reactive, so even a small number of connections can handle many concurrent requests.
Dependencies to Add
Add the following dependencies in your Maven pom.xml:
<!-- Reactive Panache for Hibernate -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>
<!-- Reactive PostgreSQL client (compatible with CockroachDB) -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
Configuration (application.properties)
Create a named datasource for each nanoservice. Keep the pool small to reduce total connections.
# Nanoservice 1
quarkus.datasource.ns1.db-kind=postgresql
quarkus.datasource.ns1.reactive.url=postgresql://user:password@cockroachdb-host:26257/dbname
quarkus.datasource.ns1.reactive.max-size=5
# Nanoservice 2
quarkus.datasource.ns2.db-kind=postgresql
quarkus.datasource.ns2.reactive.url=postgresql://user:password@cockroachdb-host:26257/dbname
quarkus.datasource.ns2.reactive.max-size=5
# Repeat for all nanoservices
Optional tuning parameters:
quarkus.datasource.ns1.reactive.initial-size=2
quarkus.datasource.ns1.reactive.idle-removal-interval=PT10M
quarkus.datasource.ns1.reactive.max-lifetime=PT30M
Usage in Nanoservices
Each nanoservice injects its own reactive repository or session using the named datasource:
@ApplicationScoped
public class Nanoservice1Repository {
@Inject
@DataSource("ns1")
ReactiveSession session;
public Uni<List<Product>> findAll() {
return session.createQuery("from Product", Product.class).getResultList();
}
public Uni<Product> findById(Long id) {
return session.find(Product.class, id);
}
}
Safe parallel access
Reactive Panache repositories and sessions are thread-safe.
R2DBC driver is non-blocking and supports multiplexing many queries over a small pool.
Multiple nanoservices can execute queries concurrently on the same JVM without locks or contention.
Queries are independent asynchronous operations; no global locks are held.
Connection pooling ensures queries wait briefly if all connections are busy, without blocking threads.
Best Practices
Pool sizing:
Start with very small pools (5–10 connections) per nanoservice.
Adjust only if load increases or queries are long-running.
Monitoring:
Use CockroachDB Admin UI or SQL to monitor sessions:
SHOW SESSIONS;Watch total connections to ensure you don’t exceed database limits.
Isolation:
Each nanoservice uses its own
@DataSourcefor full logical isolation.Misbehaving or long-running queries in one service will not impact others.
Reactive programming:
Always use
UniorMultifrom reactive Panache.Avoid blocking calls; leverage non-blocking DB access for high throughput.
Future expansion:
- Named datasources make it easy to point nanoservices to different DBs, schemas, or credentials in the future.
Summary Table
| Topic | Recommendation |
| DB Driver | Use quarkus-reactive-pg-client (PostgreSQL compatible) |
| Connection Pooling | Named reactive datasource per nanoservice, small pool (5–10 connections) |
| Pool Size | 5–10 connections per nanoservice, adjust if needed |
| Reactive Framework | quarkus-hibernate-reactive-panache |
| DB Access Code | Inject reactive session or Panache repository with @DataSource("name") |
| Parallel Access | Thread-safe; non-blocking queries; no locks |
| Monitoring | CockroachDB Admin UI or SHOW SESSIONS |
| Future-proofing | Named datasources allow independent DB access per nanoservice |
✅ Developer Notes
Do not open a connection per request; always rely on reactive pooling.
Keep nanoservice logic and DB access isolated via named datasources.
Use reactive queries for all DB access to maximize concurrency.
Monitor pool usage and total DB connections to prevent overload.
This approach balances isolation, safety, scalability, and simplicity.
This is the final recommended setup for your 20 nanoservices running in a single JVM with CockroachDB, giving you efficient, safe, and future-proof DB access.