How to Improve Java Application Performance

Improve Java performance with a measurable goal, realistic baseline and focused investigation. Find bottlenecks and compare changes without guessing.

best practices

To improve a Java application’s performance, we first need to know which part is too slow and under what conditions. A request may spend most of its time waiting for a database, even when the Java code that processes the result is fast. Changing loops or adding memory will not necessarily fix that wait.

We define a measurable goal, reproduce the workload, find where the application spends time and change one cause at a time. We then repeat the measurement to check whether the change helped. This gives us evidence for an optimization instead of relying on how fast the application feels during a few requests.

Performance improvement cycle from a measurable goal through baseline, investigation, change and repeat measurement

1. Follow a Measurement Process

We can use the process for a slow endpoint, a batch job or a service that becomes overloaded. The tools may differ, but the first question stays the same. What result do we need, and how far is the application from it?

For example, a team might set a target that 95 percent of product search requests finish within 300 milliseconds at 100 requests per second. These numbers are an illustrative target, not a benchmark result or a recommendation for every application.

2. Define What Good Performance Means

“Make it faster” leaves several questions unanswered. We need to identify the operation, the expected traffic and the result we want to achieve.

Measurement What it tells us Example question
Response time How long a request takes How long does a product search take?
Throughput How much work finishes in a period How many exports finish per minute?
Error rate How often work fails Do timeouts increase during busy periods?
Resource use How much CPU, memory or I/O the work needs Does the service meet its target within its resource budget?

We also look beyond averages. The 95th percentile, usually written p95, is a response time that at least 95 percent of the measured requests meet or beat. It shows whether a slower group of requests is hidden by a good average. The p99 value is the response time that at least 99 percent of the measured requests meet or beat.

A performance goal needs an error-rate limit too. A system that rejects half its requests quickly has not necessarily improved.

3. Record a Baseline Under Realistic Load

A baseline is the measurement we compare later changes against. We run a workload that represents the operation we care about, including realistic data sizes and a reasonable mix of requests.

A load generator, such as Apache JMeter, sends the workload and records response times. Application metrics show what happens inside the service while that workload runs. These tools answer different questions, so we often use them together.

We keep the application version, Java Virtual Machine (JVM) settings, database contents and machine resources recorded. The JVM is the runtime that executes Java bytecode. It needs time to compile frequently used code, and caches may need time to fill. We separate this warm-up period from steady measurements unless startup behavior is what we intend to measure.

We should check that the machine generating load is not itself overloaded. Otherwise, a client that cannot send requests fast enough may hide the server’s actual limit.

4. Find Where the Time Goes

A bottleneck is the part that limits the application’s overall progress. It may be busy code, a slow query or a wait for another service.

We begin with broad evidence, such as CPU use, request traces and database timing. A request trace follows an operation through its calls and helps us see which call takes most of the time.

What we observe What to investigate next
High CPU while requests slow down Frequently executed methods, expensive calculations and serialization, which converts objects into a format for storage or transmission
Slow requests with low CPU Database calls, network waits, locks and exhausted connection pools
Frequent garbage collection How quickly objects are created, how long they live and how much heap memory they need
More time waiting as traffic grows Limited worker threads, shared locks and downstream capacity
Slow database operations Query plans, indexes, rows read and repeated queries

Java Flight Recorder records events that help investigate CPU activity, object creation, garbage collection, locks and input/output (I/O), such as file and network operations. We record the application while reproducing the slow workload, then open the recording in Java Mission Control. The linked guide explains what to inspect. A profile contains samples and recorded events, so we interpret it alongside the workload rather than treating one highlighted method as automatic proof of the cause.

If memory keeps growing after work finishes and garbage collection runs, we investigate why objects remain reachable. The Java memory leak walkthrough shows that investigation with JDK commands and a heap dump.

5. Choose a Change That Addresses the Evidence

When the evidence points to database access, we inspect the query before changing unrelated Java code. An index may reduce rows examined. Fetching related data together may remove repeated round trips. A smaller result set may avoid loading data that the caller never uses.

Caching can help when many requests repeat an expensive operation. However, a cache stores a previously computed result, so we need rules for expiration, updates and memory limits. It may also make stale data visible. We decide whether that is acceptable before adding it.

For CPU-heavy code, a better algorithm can help more than a small syntax change. For excessive allocation, we look at why short-lived objects are created and whether the work is necessary. We keep correctness requirements, such as exact decimal arithmetic for money, even if a less accurate type looks faster.

More threads do not always increase throughput. They can increase contention or overload a database. More hardware can help a resource limit, but we still measure whether the application can use the extra capacity.

6. Repeat the Workload and Compare Results

We change one significant cause at a time and run the same workload again. Along with the target measurement, we check errors, resource use and behavior. A simple comparison record keeps the conditions and results together.

Record What to write down
Workload Operation, request rate, data size and test duration
Before and after p95 response time, throughput and error rate for each run
Resources Relevant CPU, heap, garbage collection or database measurements
Change The one change under comparison and any correctness checks

For example, if we add an index, we check whether query time and endpoint response time improve. We also consider its effect on writes and storage. If we add a cache, we check both cache hits and misses, including the first request after expiration.

Small differences may come from normal variation, so we repeat measurements before drawing a conclusion. We keep a change when the evidence supports its benefit and its maintenance cost is acceptable.

Once the immediate goal is met, we retain a repeatable performance check for important operations. This helps us notice future regressions without turning every code change into a broad optimization project.

7. Conclusion

Performance work starts with a goal and a baseline. We investigate the largest relevant delay, change its cause and measure again under comparable conditions. This keeps the work focused on improvements that users or the operating budget can actually benefit from.

Happy Learning!

Leave a Comment

    • Jsp/servlets run on servers (not as standalone java process), so you should not create exe for web applications. Though practically you can zip any kind file inside an exe, but you may not be able to use it.

Comments are closed.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.