Configure Tomcat 11 database connection pooling with HikariCP and JNDI optimization for high-performance applications

Intermediate 25 min Apr 28, 2026 95 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up efficient database connection pooling in Apache Tomcat 11 using HikariCP through JNDI configuration. Optimize connection parameters, implement proper resource management, and configure monitoring for production database workloads.

Prerequisites

  • Root or sudo access
  • Basic knowledge of Java web applications
  • Database server (MySQL, PostgreSQL, etc.)
  • At least 4GB RAM available

What this solves

Database connection pooling prevents your Tomcat applications from creating new database connections for every request, which quickly exhausts database resources and degrades performance. HikariCP provides the fastest and most reliable connection pooling implementation for Java applications, while JNDI configuration allows you to manage database connections at the container level rather than embedding them in your application code.

Step-by-step installation

Update system packages and install OpenJDK

Start by ensuring your system is up to date and install OpenJDK 17, which is the recommended Java version for Tomcat 11.

sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-17-jdk wget curl unzip
sudo dnf update -y
sudo dnf install -y java-17-openjdk-devel wget curl unzip

Create Tomcat user and directories

Create a dedicated user for running Tomcat and set up the directory structure with proper ownership.

sudo useradd -r -s /bin/false -d /opt/tomcat tomcat
sudo mkdir -p /opt/tomcat
sudo mkdir -p /opt/tomcat/lib

Download and install Apache Tomcat 11

Download the latest Tomcat 11 release and extract it to the installation directory.

cd /tmp
wget https://downloads.apache.org/tomcat/tomcat-11/v11.0.1/bin/apache-tomcat-11.0.1.tar.gz
sudo tar -xzf apache-tomcat-11.0.1.tar.gz -C /opt/tomcat --strip-components=1
sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod +x /opt/tomcat/bin/*.sh

Download HikariCP library

Download the HikariCP JAR file and place it in Tomcat's lib directory so it's available for connection pooling.

cd /tmp
wget https://repo1.maven.org/maven2/com/zaxxer/HikariCP/5.1.0/HikariCP-5.1.0.jar
sudo cp HikariCP-5.1.0.jar /opt/tomcat/lib/
sudo chown tomcat:tomcat /opt/tomcat/lib/HikariCP-5.1.0.jar

Download database driver

Download the appropriate JDBC driver for your database. This example uses MySQL, but you can substitute with PostgreSQL or other database drivers.

wget https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.2.0/mysql-connector-j-8.2.0.jar
sudo cp mysql-connector-j-8.2.0.jar /opt/tomcat/lib/
sudo chown tomcat:tomcat /opt/tomcat/lib/mysql-connector-j-8.2.0.jar

Create systemd service file

Set up Tomcat as a system service with proper Java memory settings and system integration.

[Unit]
Description=Apache Tomcat 11
After=network.target

[Service]
Type=forking
User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom -Djava.awt.headless=true"
Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms2048M -Xmx4096M -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh

RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

Configure context.xml for JNDI connection pooling

Configure the global JNDI resource for database connection pooling using HikariCP. This makes the connection pool available to all applications.



    WEB-INF/web.xml
    WEB-INF/tomcat-web.xml
    ${catalina.base}/conf/web.xml
    
    
    

Configure server.xml for optimized performance

Update the server.xml with optimized connector settings for high-performance database applications.



  
  
  
  
  

  
    
  

  
    

    
      
        
      

      
        
      
    
  

Set proper file permissions

Ensure all Tomcat files have the correct ownership and permissions for security and functionality.

sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod -R 755 /opt/tomcat
sudo chmod 600 /opt/tomcat/conf/context.xml
sudo chmod 600 /opt/tomcat/conf/server.xml

Enable and start Tomcat service

Enable the Tomcat service to start automatically on boot and start it now.

sudo systemctl daemon-reload
sudo systemctl enable tomcat
sudo systemctl start tomcat

Database-specific optimization settings

Configure MySQL optimizations

For MySQL databases, add these specific parameters to enhance performance and reliability with connection pooling.

Configure PostgreSQL optimizations

For PostgreSQL databases, use these optimized parameters that work well with HikariCP.

Performance monitoring and troubleshooting

Enable HikariCP monitoring

Configure HikariCP to expose JMX metrics for monitoring connection pool health and performance.

Configure JMX monitoring

Enable JMX remote monitoring by adding these Java options to your systemd service file.

Environment="CATALINA_OPTS=-Xms2048M -Xmx4096M -server -XX:+UseParallelGC -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

Create sample web application

Create a simple test application to verify your connection pool is working correctly.



    
    Database Test App
    
    
        Database Connection
        jdbc/MyAppDB
        javax.sql.DataSource
        Container
    
    

Create test servlet

Create a simple servlet that tests database connectivity through the JNDI connection pool.

<%@ page import="java.sql.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="javax.naming.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Database Connection Test


HikariCP Connection Pool Test

<% Connection conn = null; Statement stmt = null; try { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MyAppDB"); conn = ds.getConnection(); stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT 1 as test"); if (rs.next()) { out.println("

Database connection successful!

"); out.println("

Test query result: " + rs.getInt("test") + "

"); } rs.close(); } catch (Exception e) { out.println("

Database connection failed: " + e.getMessage() + "

"); } finally { if (stmt != null) try { stmt.close(); } catch (SQLException e) {} if (conn != null) try { conn.close(); } catch (SQLException e) {} } %>

Set test application permissions

Ensure the test application has proper ownership and can be deployed by Tomcat.

sudo mkdir -p /opt/tomcat/webapps/dbtest/WEB-INF
sudo chown -R tomcat:tomcat /opt/tomcat/webapps/dbtest
sudo systemctl restart tomcat

Verify your setup

Check that Tomcat is running and the connection pool is configured correctly.

sudo systemctl status tomcat
curl -I http://localhost:8080
ss -tlnp | grep 8080
tail -f /opt/tomcat/logs/catalina.out

Visit your test application to verify database connectivity:

curl http://localhost:8080/dbtest/

Monitor connection pool metrics through JMX:

jconsole localhost:8999

Common issues

SymptomCauseFix
Connection pool not foundJNDI resource name mismatchCheck resource name in context.xml matches web.xml lookup
Too many connections errorPool size exceeds database limitsReduce maximumPoolSize or increase database max_connections
Connection timeout errorsNetwork latency or database overloadIncrease connectionTimeout and check database performance
Memory leaks in logsConnections not properly closedEnable leakDetectionThreshold and fix application code
ClassNotFoundException for HikariCPJAR file missing from lib directoryVerify HikariCP JAR is in /opt/tomcat/lib/
Database driver not foundJDBC driver missing or wrong versionDownload correct driver version for your database
Never use chmod 777. It gives every user on the system full access to your files. Instead, fix ownership with chown and use minimal permissions like 755 for directories and 644 for files.

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle infrastructure performance optimization for businesses that depend on uptime. From initial setup to ongoing operations.