Skip to content

swanandvk/benchmark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

K6 Benchmark — Expense Manager API

Performance benchmark suite for comparing the Java (Spring Boot) and Go (net/http) implementations of the Expense Manager API.

🤖 Generated with Claude Opus 4.6 (Thinking) via Antigravity — Google DeepMind's advanced agentic coding assistant.


Table of Contents


Overview

This benchmark uses k6 to load-test the Expense Manager REST API. It exercises the full CRUD lifecycle (Create → Read → Update → Delete) along with category filtering and summary endpoints, across three progressively intense scenarios: smoke, load, and stress.


Prerequisites

Tool Install Command Purpose
k6 brew install k6 Load testing framework
jq (optional) brew install jq Pretty-print JSON results
curl Comes with macOS/Linux Health-check services

Ensure at least one of the target services is running:

Service Default URL How to Start
Java http://localhost:8080 cd ../expense-manager-java && mvn spring-boot:run
Go http://localhost:8081 cd ../expense-manager-go && go run .

Project Structure

k6-benchmark/
├── README.md            # This file
├── benchmark.js         # k6 test script (scenarios, checks, custom metrics)
└── run_benchmark.sh     # Convenience shell wrapper

Quick Start

# 1. Start the target service(s)
cd ../expense-manager-java && mvn spring-boot:run   # terminal 1
cd ../expense-manager-go   && go run .              # terminal 2

# 2. Run benchmarks
cd k6-benchmark
chmod +x run_benchmark.sh
./run_benchmark.sh        # benchmarks both services

Running Benchmarks

Using the shell wrapper (recommended)

# Benchmark both Java and Go services
./run_benchmark.sh

# Benchmark Java only
./run_benchmark.sh java

# Benchmark Go only
./run_benchmark.sh go

The wrapper script will:

  1. Verify that k6 is installed
  2. Health-check the target service(s)
  3. Run the benchmark
  4. Save results to results_java.json and/or results_go.json

Using k6 directly

# Against the Java service
k6 run -e SERVICE=java -e JAVA_URL=http://localhost:8080 benchmark.js

# Against the Go service
k6 run -e SERVICE=go -e GO_URL=http://localhost:8081 benchmark.js

Custom service URLs

If your services run on non-default ports or hosts:

JAVA_URL=http://myhost:9090 GO_URL=http://myhost:9091 ./run_benchmark.sh

Or with k6 directly:

k6 run -e SERVICE=java -e JAVA_URL=http://myhost:9090 benchmark.js

Test Scenarios

The benchmark runs three scenarios sequentially:

Scenario Type VUs Duration Start Time Purpose
Smoke Constant VUs 1 10s 0s Quick sanity check — does the API work?
Load Ramping VUs 0 → 20 → 20 → 0 55s 15s Sustained moderate load
Stress Ramping VUs 0 → 50 → 100 → 0 70s 70s Push limits under heavy concurrency

What each VU iteration does

Each virtual user iteration performs the following API operations:

  1. Create an expense (POST /api/expenses)
  2. List all expenses (GET /api/expenses)
  3. Filter by category (GET /api/expenses?category=...)
  4. Get by ID (GET /api/expenses/{id})
  5. Update the expense (PUT /api/expenses/{id})
  6. Delete the expense (DELETE /api/expenses/{id})
  7. Verify deletion returns 404 (GET /api/expenses/{id})
  8. Get summary (GET /api/expenses/summary)

Custom Metrics

Beyond k6's built-in metrics, the benchmark tracks:

Metric Type Description
create_latency Trend Time to create an expense
get_all_latency Trend Time to list / filter expenses
get_by_id_latency Trend Time to fetch a single expense
update_latency Trend Time to update an expense
delete_latency Trend Time to delete an expense
summary_latency Trend Time to fetch the summary endpoint
total_requests Counter Total API requests made
errors Rate Percentage of failed checks

Thresholds

The benchmark will report a failure if any of these thresholds are breached:

Metric Threshold
http_req_duration p(95) < 500 ms
http_req_duration p(99) < 1000 ms
errors rate < 10 %
create_latency p(95) < 300 ms
get_all_latency p(95) < 200 ms
get_by_id_latency p(95) < 150 ms
update_latency p(95) < 300 ms
delete_latency p(95) < 200 ms
summary_latency p(95) < 200 ms

Configuration

All configuration is done via environment variables:

Variable Default Description
SERVICE java Which service to target (java or go)
JAVA_URL http://localhost:8080 Base URL for the Java service
GO_URL http://localhost:8081 Base URL for the Go service

Viewing Results

Console output

k6 prints a rich summary to the terminal after each run, including all custom metrics and threshold pass/fail status.

JSON results

Detailed results are saved as JSON files in the working directory:

# Pretty-print Java results
jq . results_java.json

# Pretty-print Go results
jq . results_go.json

# Side-by-side comparison
jq . results_java.json results_go.json

Result file structure

{
  "service": "java",
  "baseUrl": "http://localhost:8080",
  "timestamp": "2026-06-01T12:00:00.000Z",
  "metrics": {
    "http_req_duration": { "avg": 12.5, "p90": 25.0, "p95": 30.0, "p99": 50.0, "max": 100.0 },
    "create_latency":    { "avg": 15.0, "p95": 35.0 },
    "get_all_latency":   { "avg": 8.0,  "p95": 18.0 },
    "get_by_id_latency": { "avg": 5.0,  "p95": 12.0 },
    "update_latency":    { "avg": 14.0, "p95": 32.0 },
    "delete_latency":    { "avg": 6.0,  "p95": 15.0 },
    "summary_latency":   { "avg": 7.0,  "p95": 16.0 },
    "total_requests": 5000,
    "error_rate": 0.001,
    "http_reqs": 5000,
    "http_req_rate": 120.5
  }
}

License

This project is provided as-is for benchmarking and educational purposes.


Benchmark Results Comparison (Java vs Go)

Results generated on macOS, using local k6 load test (Smoke + Load + Stress scenarios).

Metric Java Go Winner
HTTP Req Duration (avg) 2.31 ms 2.16 ms Go
HTTP Req Duration (p95) 5.80 ms 6.42 ms Java
Create Latency (avg) 2.35 ms 2.11 ms Go
Create Latency (p95) 5.68 ms 6.22 ms Java
Get All Latency (avg) 2.61 ms 2.57 ms Go
Get All Latency (p95) 6.47 ms 7.55 ms Java
Get By ID Latency (avg) 2.23 ms 1.99 ms Go
Get By ID Latency (p95) 5.60 ms 5.79 ms Java
Update Latency (avg) 2.30 ms 2.11 ms Go
Update Latency (p95) 5.61 ms 6.39 ms Java
Delete Latency (avg) 2.14 ms 2.08 ms Go
Delete Latency (p95) 5.43 ms 6.04 ms Java
Summary Latency (avg) 2.08 ms 1.96 ms Go
Summary Latency (p95) 5.29 ms 5.75 ms Java
Total Requests 42,312 42,288 Tie
Throughput (Req/sec) ~300.36 ~300.01 Tie

Observation: Go exhibits slightly lower average latency across most endpoints, suggesting lower overhead for typical requests. However, Java exhibits a tighter latency distribution, beating Go at the 95th percentile (p95), which suggests more consistent tail-latency under the load tested.

Maximum Capacity (Breakpoint Test)

To find the true breaking point of both services, an aggressive Breakpoint Test was run, ramping up to 1,500 concurrent Virtual Users.

Metric Java (Spring Boot) Go (Gin Framework) Winner
HTTP Req Duration (avg) ~36.11 ms ~7.36 ms Go
HTTP Req Duration (p95) ~153.63 ms ~38.62 ms Go
Create Latency (avg) ~49.72 ms ~7.00 ms Go
Create Latency (p95) ~213.48 ms ~38.05 ms Go
Get All Latency (avg) ~44.97 ms ~10.30 ms Go
Get All Latency (p95) ~197.28 ms ~52.00 ms Go
Get By ID Latency (avg) ~31.85 ms ~6.19 ms Go
Get By ID Latency (p95) ~120.31 ms ~33.74 ms Go
Update Latency (avg) ~30.04 ms ~6.37 ms Go
Update Latency (p95) ~112.46 ms ~33.18 ms Go
Delete Latency (avg) ~28.36 ms ~6.41 ms Go
Delete Latency (p95) ~108.37 ms ~34.93 ms Go
Summary Latency (avg) ~30.57 ms ~6.10 ms Go
Summary Latency (p95) ~113.30 ms ~32.66 ms Go
Total Requests Processed 81,169 130,003 Go
Error Rate 0% 0% Tie
Max Throughput (Req/sec) ~1,014.21 ~1,623.11 Go
Max RPM (Req/min) ~60,853 RPM ~97,386 RPM Go

Conclusion: When refactored to use the production-ready gin-gonic/gin framework instead of the standard library's raw net/http mux, Go demonstrates vastly superior performance and extreme resilience. It serves nearly 100,000 requests per minute out of the box in a highly constrained Docker environment (250MB Memory, 1.0 CPU), significantly outperforming Java in both raw throughput and tail latency under extreme load.

About

Compare different frameworks , languages, libraries

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors