
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
To successfully scale and monitor Quarkus in production, you must treat it as a cloud-native platform rather than a traditional Java application server. While Quarkus offers supersonic startup times and low memory footprints, these advantages vanish without proper Kubernetes resource tuning and observability instrumentation. This guide covers the exact configuration patterns I use to run resilient Quarkus microservices, integrating Horizontal Pod Autoscaling with native OpenTelemetry support to ensure your services handle load predictably.
quarkus-micrometer-registry-prometheus and quarkus-opentelemetry extensions, configure strict CPU/memory requests for Kubernetes HPA, and expose the /q/metrics endpoint for scraping. This combination provides the telemetry data required for automated scaling and deep visibility into request latency.How do you configure Prometheus metrics to scale and monitor Quarkus in production?
Quarkus does not expose metrics by default. You must explicitly add the Micrometer registry extension to generate the Prometheus-compatible data that Kubernetes and Grafana need. In my experience auditing Java microservices, missing or misconfigured metrics are the primary reason teams fail to scale and monitor Quarkus in production effectively. The framework uses Micrometer as its abstraction layer, which means you get standardized JVM and HTTP metrics out of the box once the extension is active.
Add the required dependencies
Start by adding the Prometheus registry extension. This automatically enables the /q/metrics endpoint and registers default binders for JVM memory, garbage collection, and HTTP request timers.
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency> Tune metric exposure for security and performance
In production, never expose metrics on the same port as your public API unless you have an ingress filter. Quarkus supports management interface separation, which is critical for compliance frameworks like SOC 2 where internal telemetry endpoints must be isolated from external traffic. Configure this in your application.properties:
# Enable management interface on separate port
quarkus.management.enabled=true
quarkus.management.port=9000
# Expose metrics only on management interface
quarkus.micrometer.export.prometheus.path=/metrics
# Add custom tags for better filtering in Grafana
quarkus.micrometer.binder.http-server.ignore-patterns=/q/.*
quarkus.micrometer.binder.jvm=true This configuration ensures that your health checks and metrics are served on port 9000 while your business logic remains on port 8080. When configuring your Prometheus scrape targets, point them specifically at port 9000. This separation prevents accidental exposure of internal runtime statistics to end users and simplifies network policy enforcement in Kubernetes.
How does OpenTelemetry integration improve Quarkus observability?
Metrics tell you what is happening, but traces tell you where it is happening. For distributed systems, this distinction is everything. Quarkus has first-class OpenTelemetry support that requires minimal boilerplate. Unlike older Java frameworks that required heavy agent attachment or complex SDK initialization, Quarkus integrates tracing directly into the build process via extensions. This results in lower overhead and more accurate context propagation across reactive boundaries.
Enable tracing with zero code changes
Add the OpenTelemetry extension and configure the exporter. Quarkus defaults to OTLP, which is the industry standard for 2026. Avoid legacy Zipkin or Jaeger proprietary protocols unless you have a specific legacy backend requirement.
# application.properties
quarkus.otel.enabled=true
quarkus.otel.exporter.otlp.endpoint=http://otel-collector:4317
quarkus.otel.service.name=order-service
quarkus.otel.traces.sampler=parentbased_tracealways
# Sample 10% of requests in high-volume prod to control cost
# quarkus.otel.traces.sampler.arg=0.1 A common mistake I see in OpenTelemetry implementations is sampling everything in development and then forgetting to adjust rates for production. Always define a sampling strategy explicitly. For high-throughput Quarkus services processing thousands of RPS, parent-based sampling preserves complete traces for requests that matter while dropping noise. This keeps your Tempo or Jaeger storage costs manageable without losing debugging fidelity.
What Kubernetes resource settings are required for Quarkus autoscaling?
Quarkus is designed for density, but Kubernetes cannot scale what it cannot measure. The Horizontal Pod Autoscaler (HPA) relies entirely on the accuracy of your resource requests and limits. With traditional Spring Boot apps, engineers often over-provision memory to account for JVM heap uncertainty. With Quarkus native or even JVM mode, you can be far more precise. However, being too aggressive with limits causes OOMKills during GC spikes, while being too loose defeats the purpose of using Quarkus.
Define requests based on actual profiling
Never guess resource values. Use jcmd or Quarkus dev services to profile your application under load before setting production values. For a typical REST microservice in JVM mode, I typically start with these baselines and adjust:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "1000m" Configure HPA for Quarkus-specific behavior
Because Quarkus starts quickly, you can scale up faster than with traditional JVM apps. However, scaling down requires caution to avoid flapping. Configure stabilization windows to prevent rapid oscillation during traffic plateaus.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: quarkus-order-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
minReplicas: 2
maxReplicas: 20
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 2
periodSeconds: 120
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 The 30-second scale-up window leverages Quarkus's fast startup, allowing the cluster to react nearly instantly to spikes. The 5-minute scale-down window prevents premature termination during brief lulls. This asymmetry is key when you scale and monitor Quarkus in production because it aligns infrastructure behavior with application characteristics rather than generic defaults.
How do Quarkus native and JVM modes compare for production scaling?
Choosing between native and JVM mode is the most significant architectural decision for Quarkus operations. Native mode offers instant startup and minimal memory, but introduces build complexity and potential compatibility issues with reflection-heavy libraries. JVM mode retains full Java ecosystem compatibility at the cost of higher baseline resources. The right choice depends on your workload pattern, team expertise, and compliance requirements.
| Criteria | Quarkus Native | Quarkus JVM Mode |
|---|---|---|
| Startup Time | < 100ms (instant scaling) | 1–3 seconds (fast for JVM) |
| Memory Footprint | 50–150 MB RSS | 200–500 MB RSS |
| Peak Throughput | 10–20% lower initially (no JIT warmup) | Higher after warmup (C2 compiler) |
| Build Complexity | High (GraalVM, reflection config) | Low (standard JDK) |
| Library Compatibility | Limited (no dynamic proxies/reflection) | Full Java ecosystem |
| Best For | Serverless, edge, high-density clusters | Long-running services, complex domains |
In practice, I recommend JVM mode for most enterprise microservices unless you have a specific density or cold-start requirement. The operational overhead of maintaining GraalVM reachability metadata often outweighs the resource savings for services that run continuously. Reserve native mode for Lambda functions, Knative services, or edge deployments where every megabyte translates directly to cost savings. For teams in Nepal or emerging markets where cloud budgets are tight, native mode can reduce AWS/Azure bills by 40–60%, but only if your engineering team can absorb the debugging complexity.
What are the common pitfalls when operating Quarkus at scale?
Even experienced teams stumble when transitioning from traditional Java to Quarkus. The framework's optimizations introduce new failure modes that don't exist in servlet containers. Recognizing these early prevents 3 AM pages and failed audits.
- Ignoring connection pool sizing: Quarkus uses Agroal by default. In reactive mode, connections are non-blocking, but pool size still matters. Set
quarkus.datasource.reactive.max-sizebased on your database's capacity, not CPU count. A common error is leaving this at the default (20) while running 50 pods, creating 1,000 DB connections that overwhelm PostgreSQL. - Missing health check differentiation: Quarkus exposes
/q/health/liveand/q/health/ready. Never use the same endpoint for both liveness and readiness probes in Kubernetes. Liveness should only fail if the process is deadlocked; readiness should fail if dependencies are unavailable. Mixing them causes cascading restarts during database blips. - Neglecting structured logging: Plain text logs are unparseable at scale. Enable JSON logging with
quarkus.logging.json.enabled=trueand integrate with your structured logging pipeline. This ensures trace IDs appear in every log line, correlating logs with traces automatically. - Overlooking TLS termination: Quarkus can handle TLS natively, but in Kubernetes, terminate at the ingress controller instead. Managing certificates inside pods adds operational burden and complicates rotation. Let cert-manager handle TLS at the edge and keep Quarkus focused on business logic.
Next Steps for Reliable Quarkus Operations
Successfully operating Quarkus requires treating observability and scaling as first-class concerns, not afterthoughts. Start by instrumenting your services with Micrometer and OpenTelemetry today, then validate your HPA configuration with load testing before trusting it in production. Remember that the goal when you scale and monitor Quarkus in production is predictable behavior under pressure, not just theoretical efficiency. If your team needs help designing audit-ready Quarkus infrastructure or optimizing existing deployments for cost and compliance, reach out to discuss your architecture.