🚀 We Were Tuning the Wrong Things — The Simple Fixes That Made Our Java APIs 10x Faster
Our Java APIs were slow.
Not “slightly slow.”
Painfully slow.
- P95 latency: ~900ms 😵
- CPU spikes under load 🔥
- Random timeouts ⏳
- Dev team blaming the database (of course 😅)
We spent months “optimizing.”
Then a senior engineer joined a call, looked at our setup for 20 minutes, and casually said:
“Why are you tuning symptoms instead of fixing the bottlenecks?”
Two days later…
10x faster.
Here’s what actually changed.
⚠️ Act Now or Miss 70% OFF VPN + 1TB FREE Cloud Storage!
This heavy discount won’t last forever — secure your deal today.
✅ 30-Day Money-Back Guarantee — zero risk.
⚠️ Mistake #1: We Were Returning Huge Payloads
Our API:
@GetMapping("/users")
public List<User> getUsers() {
return userRepository.findAll();
}Looks innocent.
But User had:
- Orders
- Addresses
- Roles
- Audit fields
- Relationships
Hibernate was loading everything.
We were sending megabytes per request.
✅ Fix: Use DTO + Projection
public interface UserSummary {
Long getId();
String getName();
String getEmail();
}
@Query("SELECT u.id AS id, u.name AS name, u.email AS email FROM User u")
List<UserSummary> findUserSummaries();Response size dropped by 80%.
Latency dropped instantly. 🚀
⚠️ Mistake #2: N+1 Query Problem
We had this pattern everywhere:
List<Order> orders = orderRepository.findAll();
for (Order order : orders) {
order.getItems().size();
}Under load, it became:
1 query + 500 extra queries 😳
✅ Fix: Fetch Join
@Query("SELECT o FROM Order o JOIN FETCH o.items")
List<Order> findAllWithItems();Query count went from 501 → 1.
Database CPU dropped by half.
⚠️ Mistake #3: Thread Pool Bottleneck
We were using default Tomcat threads.
Under load, requests were queuing.
✅ Fix: Tune Thread Pool
server:
tomcat:
threads:
max: 200
min-spare: 20Throughput improved immediately.
Sometimes defaults aren’t wrong — just not optimized for your traffic.
⚠️ Mistake #4: Blocking External Calls
We were calling another service synchronously:
String result = restTemplate.getForObject(url, String.class);Each call blocked a thread.
Under load, thread starvation happened.
✅ Fix: Timeout + Pooling
@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(3000);
factory.setReadTimeout(3000);
return new RestTemplate(factory);
}Even better? Move slow calls async.
⚠️ Mistake #5: No Caching
We were hitting DB for data that changed once a day.
✅ Fix: Add Caching
@EnableCaching
@Cacheable("products")
public List<Product> getAllProducts() {
return productRepository.findAll();
}API response time:
Get akash’s stories in your inbox
Join Medium for free to get updates from this writer.
450ms → 40ms ⚡
⚠️ Mistake #6: Debug Logging in Production
Yes… we had this:
logging:
level:
root: DEBUGUnder heavy traffic, logging alone was adding latency.
✅ Fix:
logging:
level:
root: INFOCPU stabilized.
📊 The Result
Before:
- P95 latency: 900ms
- Throughput: 300 req/sec
- CPU: 85%
- DB overloaded
After:
- P95 latency: 90ms 🚀
- Throughput: 2,500+ req/sec
- CPU: 45%
- Stable under load
No massive rewrite.
No microservices migration.
No hardware upgrade.
Just fixing architectural mistakes.
🧠 What the Senior Engineer Actually Did
He didn’t tune JVM flags.
He didn’t add more servers.
He asked:
- Are you sending too much data?
- Are you running too many queries?
- Are you blocking threads?
- Are you measuring properly?
- Are you using defaults blindly?
Performance isn’t magic.
It’s eliminating waste.
🎯 The Real Lesson
We were optimizing at the wrong layer.
We were tuning GC…
While Hibernate was firing 500 queries.
We were tweaking heap size…
While sending 5MB JSON responses.
We were scaling horizontally…
While blocking threads on slow HTTP calls.
🚀 Final Thought
10x performance improvements rarely come from clever tricks.
They come from:
- Fixing data access
- Reducing payload size
- Removing unnecessary work
- Measuring bottlenecks honestly
Sometimes all it takes is a fresh pair of senior eyes.
And a few uncomfortable questions.








