Skip to content

Performance Engineering


Performance Metrics

Key Performance Metrics

Why Percentiles Matter

Percentiles vs Average


Performance Laws

Little's Law

Little's Law

Amdahl's Law

Amdahl's Law

Universal Scalability Law

Universal Scalability Law


Profiling

Types of Profilers

Profiler Types

Flame Graphs

Flame Graph


Load Testing

Load Testing Types

Load Testing Types

Load Test Example (k6)

// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '2m', target: 100 },   // Ramp up
    { duration: '5m', target: 100 },   // Steady state
    { duration: '2m', target: 200 },   // Stress
    { duration: '5m', target: 200 },   // Steady stress
    { duration: '2m', target: 0 },     // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<200'],   // 95% < 200ms
    http_req_failed: ['rate<0.01'],     // Error rate < 1%
  },
};

export default function () {
  const res = http.get('https://api.example.com/orders');

  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });

  sleep(1);
}

// Run: k6 run load-test.js

Optimization Techniques

Common Bottlenecks

Common Performance Bottlenecks

Optimization Strategies

// 1. Caching
@Cacheable(value = "products", key = "#id")
public Product getProduct(Long id) {
    return productRepository.findById(id);
}

// 2. Connection Pooling
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);

// 3. Async Processing
@Async
public CompletableFuture<Report> generateReport(Long id) {
    return CompletableFuture.completedFuture(reportService.generate(id));
}

// 4. Batching
@Modifying
@Query("UPDATE Order o SET o.status = :status WHERE o.id IN :ids")
int updateStatusBatch(@Param("ids") List<Long> ids, @Param("status") Status status);

// 5. Pagination
public Page<Order> getOrders(int page, int size) {
    return orderRepository.findAll(PageRequest.of(page, size));
}

// 6. Index Optimization
@Table(indexes = {
    @Index(name = "idx_order_customer", columnList = "customer_id"),
    @Index(name = "idx_order_status_date", columnList = "status, created_at")
})
public class Order { }

JVM Performance

GC Tuning

GC Selection Guide


Capacity Planning

Capacity Planning


Common Interview Questions

  1. Why use percentiles instead of average?
  2. Average hides outliers
  3. P99 shows worst-case user experience
  4. Tail latency matters for user satisfaction

  5. What is Amdahl's Law?

  6. Limits speedup from parallelization
  7. Serial portion limits max improvement
  8. 10% serial = max 10x speedup

  9. How to identify performance bottlenecks?

  10. Profile CPU, memory, I/O
  11. Check resource utilization
  12. Analyze flame graphs
  13. Use APM tools

  14. Load test types?

  15. Smoke: Verify works
  16. Load: Expected traffic
  17. Stress: Find breaking point
  18. Soak: Long duration

  19. How to improve latency?

  20. Caching
  21. Connection pooling
  22. Async processing
  23. Database optimization
  24. CDN for static content

  • *