How to Configure High-Performance Settings in Bella OpenAPI: JVM Tuning, Connection Pooling, and Threading

Configure high-performance settings in Bella OpenAPI by modifying api/run.sh for JVM heap sizing and G1 garbage collection, and api/server/src/main/resources/application.yml for HikariCP database pools, Tomcat HTTP threads, and Redisson Redis connections.

Bella OpenAPI, maintained by lianjiatech, is a high-throughput Spring Boot gateway designed to process millions of AI-service calls daily. To achieve optimal throughput and minimize latency, you must properly configure high-performance settings across the JVM runtime, database connection pooling, and HTTP server threading.

JVM Configuration in run.sh

The startup script api/run.sh defines critical JVM options for heap management and garbage collection. These settings ensure the service has sufficient memory for request-level objects and caches while maintaining low pause times.


# /api/run.sh

JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m"
JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m"
JAVA_OPTS="$JAVA_OPTS -XX:MaxDirectMemorySize=1024m"
JAVA_OPTS="$JAVA_OPTS -Dlogging.path=${MATRIX_APPLOGS_DIR}"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps \
          -Xloggc:${MATRIX_ACCESSLOGS_DIR}/gc-%t.log"

# G1 GC tuned for low-latency pauses

GC_OPTS="$GC_OPTS -XX:+UseG1GC -XX:G1HeapRegionSize=2m \
          -XX:MaxGCPauseMillis=500 -XX:InitiatingHeapOccupancyPercent=40 \
          -XX:G1ReservePercent=10 -XX:+ParallelRefProcEnabled \
          -XX:+UseFastAccessorMethods -XX:ParallelGCThreads=4 \
          -XX:ConcGCThreads=2 -XX:+ExplicitGCInvokesConcurrent"

The configuration allocates 2 GB of heap memory (-Xmx2048m) and 1 GB of direct memory for off-heap buffers used by Netty and OkHttp. The G1 garbage collector targets maximum pause times of 500 milliseconds, which is critical for maintaining low latency during high-throughput AI service calls.

Database Connection Pooling with HikariCP

Database connectivity is managed through HikariCP, a high-performance JDBC connection pool. Configuration resides in api/server/src/main/resources/application.yml under the spring.datasource.hikari namespace.


# /api/server/src/main/resources/application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/bella_openapi?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: bella_user
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5

Setting maximum-pool-size to 20 connections matches the expected concurrent request load for an 8-core deployment. This prevents connection acquisition bottlenecks when querying MySQL for rate-limiting or metadata lookups. Adjust this value based on your MySQL server's max_connections limit and observed active connection metrics.

HTTP Server Thread Pool Configuration

The embedded Tomcat server handles incoming API requests through a configurable thread pool. Thread limits are defined in application.yml under server.tomcat.threads.


# /api/server/src/main/resources/application.yml

server:
  tomcat:
    threads:
      max: 300
  max-http-header-size: 10240

Configuring 300 maximum threads ensures Tomcat can handle high volumes of simultaneous AI completion requests without thread starvation. Size this pool according to the formula CPU cores × (1 + blocking ratio). For a 16-core machine with I/O-bound operations, 300 threads provides sufficient headroom for burst traffic while preventing excessive context switching.

Redis Connection Pooling with Redisson

Bella OpenAPI uses Redisson for Redis connectivity, supporting distributed caching and rate-limiting via RateLimitInterceptor.java and Lua scripts in api/server/src/main/resources/lua/. The connection pool is configured in application.yml under spring.redis.redisson.config.


# /api/server/src/main/resources/application.yml

spring:
  redis:
    redisson:
      config: |
        singleServerConfig:
          address: "redis://localhost:6379"
          connectionPoolSize: 200
        codec: !<org.redisson.client.codec.StringCodec> {}

Redisson maintains an internal connection pool with a default limit of 100 connections. For high-throughput deployments processing millions of requests, explicitly set connectionPoolSize to 200 to prevent connection exhaustion during peak rate-limiting checks and JetCache L2 cache operations. The StringCodec minimizes serialization overhead for simple key-value operations.

Monitoring and Verification

After applying performance configurations, validate your tuning through Spring Boot Actuator and JVM monitoring tools:

  • JVM GC logs: Check gc-%t.log files in ${MATRIX_ACCESSLOGS_DIR} for pause times exceeding 500ms. Analyze with GCViewer to adjust MaxGCPauseMillis if necessary.
  • HikariCP metrics: Query /actuator/metrics/hikari.pool.active and /actuator/metrics/hikari.pool.idle to detect pool saturation.
  • Tomcat threads: Use jstack <pid> or inspect /actuator/metrics/http.server.requests to verify thread pool utilization under load.
  • Redis latency: Monitor Micrometer's redis.command.latency metric or use redis-cli --latency to verify Redisson pool performance.

Summary

  • JVM tuning: Configure heap, metaspace, and direct memory in api/run.sh with G1GC targeting 500ms pause times.
  • Database pooling: Set HikariCP maximum-pool-size in application.yml to match MySQL capacity and concurrent load.
  • HTTP threading: Size Tomcat's threads.max to CPU cores × (1 + blocking ratio) for optimal request handling.
  • Redis optimization: Increase Redisson connectionPoolSize for high-throughput caching and rate-limiting scenarios.
  • Continuous monitoring: Validate configurations using GC logs, actuator metrics, and thread dumps to prevent bottlenecks.

Frequently Asked Questions

For production deployments handling millions of daily AI-service calls, allocate 2 GB of heap memory using -Xms2048m -Xmx2048m in api/run.sh. Increase to 4 GB (-Xmx4096m) if you enable large in-memory Caffeine caches or experience frequent garbage collection pauses under heavy load.

How do I tune the database connection pool size?

Set spring.datasource.hikari.maximum-pool-size in application.yml to approximately 20 connections for an 8-core server, matching the expected concurrent database access patterns. Monitor the hikari.pool.active metric via Spring Boot Actuator; if connections are consistently exhausted, increase the pool size while ensuring it remains below your MySQL server's max_connections limit.

Can I use a different garbage collector than G1?

While the default api/run.sh configures G1GC (-XX:+UseG1GC) for low-latency pauses under 500ms, you can switch to ZGC or Shenandoah on JDK 17+ by replacing the GC flags in run.sh. However, G1 remains the recommended choice for Bella OpenAPI's workload pattern of short-lived request objects and moderate heap sizes.

How do I monitor connection pool usage in production?

Enable Spring Boot Actuator and query /actuator/metrics/hikari.pool.active to view active database connections and /actuator/metrics/hikari.pool.idle for available connections. For Redis, monitor Micrometer's redis.command.latency metric or use redis-cli --latency to verify Redisson pool performance. Thread pool status can be inspected via jstack <pid> or through custom MBeans exposing Tomcat's active thread count.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →