API – response time

Here are fast, reliable ways to measure client-side API response time (and break it down) — from your laptop or from an EKS pod.

1) One-shot timing (curl)

This prints DNS, TCP, TLS, TTFB, and Total in one go:

curl -s -o /dev/null -w '
{ "http_code":%{http_code},
  "remote_ip":"%{remote_ip}",
  "dns":%{time_namelookup},
  "tcp":%{time_connect},
  "tls":%{time_appconnect},
  "ttfb":%{time_starttransfer},
  "total":%{time_total},
  "size":%{size_download},
  "speed":%{speed_download}
}
' https://api.example.com/path

Fields

  • dns: DNS lookup
  • tcp: TCP connect
  • tls: TLS handshake (0 if HTTP)
  • ttfb: time to first byte (request→first response byte)
  • total: full download time

2) From EKS (ephemeral pod)

Run N samples and capture a CSV:

kubectl run curl --rm -it --image=curlimages/curl:8.8.0 -- \
sh -c 'for i in $(seq 1 50); do \
  curl -s -o /dev/null -w "%{time_namelookup},%{time_connect},%{time_appconnect},%{time_starttransfer},%{time_total}\n" \
  https://api.example.com/health; \
done' > timings.csv

Open timings.csv and look at columns: dns,tcp,tls,ttfb,total. Large ttfb means slow upstream/app; big tls means handshake issues; big gap total - ttfb means payload/download time.

3) Separate proxy vs upstream (Kong in the path)

Kong adds latency headers you can read on the client:

curl -i https://api.example.com/path | sed -n 's/^\(x-kong-.*latency\): \(.*\)$/\1: \2/p'
# x-kong-proxy-latency: <ms>   (Kong → upstream start)
# x-kong-upstream-latency: <ms> (Upstream processing)

These help you see if delay is at the gateway or in the service.

4) Quick load/percentiles (pick one)

  • hey hey -z 30s -c 20 https://api.example.com/path
  • vegeta echo "GET https://api.example.com/path" | vegeta attack -rate=20 -duration=30s | vegeta report
  • k6 (scriptable) // save as test.js import http from 'k6/http'; import { check } from 'k6'; export const options = { vus: 20, duration: '30s', thresholds: { http_req_duration: ['p(95)<300'] } }; export default () => { const r = http.get('https://api.example.com/path'); check(r, { '200': (res)=>res.status===200 }); }; Run: k6 run test.js

5) App-level timers (optional)

Add a Server-Timing header from the API to expose your own phase timings (DB, cache, etc.). Then the client can read those headers to correlate.

6) Common gotchas

  • Proxies can add latency; test both with and without proxy (NO_PROXY / --proxy).
  • Auth: measure with real headers/tokens; 401/403 will skew.
  • SNI/Host: if hitting by IP, use --resolve host:443:IP -H "Host: host" so cert/routing is correct.
  • Warmup: discard first few samples (JIT, caches, TLS session reuse).

If you want, share a few curl -w outputs from local vs EKS and I’ll pinpoint where the time is going (DNS/TLS/TTFB/payload).

Kong / our app is build using Java Spring Boot

Yes — when integrating certificates into Spring Boot, especially for mTLS, HTTPS, or secure inter-service communication, there are several important certificate handling considerations you should account for:


✅ 1. Keystore / Truststore Formats

StorePurposeCommon Format
KeystoreHolds your application’s private key + certJKS, PKCS12 (.p12 / .pfx)
TruststoreHolds trusted CA certs to verify clients or serversJKS, PKCS12

🟡 JKS is Java-native, but PKCS12 is preferred for modern apps (more portable + supports OpenSSL).

🔧 Example Spring Boot Config:

server.ssl.key-store=classpath:server.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.trust-store=classpath:truststore.p12
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=PKCS12


✅ 2. Certificate Chain Requirements

Spring Boot expects:

  • Full certificate chain in the keystore if issued by an intermediate CA
  • Trusted root CA in the truststore (for mTLS)

🔸 Failure to include the full chain often results in handshake errors or “unable to find valid certification path” errors.


✅ 3. Protocol Configuration (TLS)

Spring Boot (via embedded Tomcat) uses TLS 1.2+ by default.

To restrict or specify:

server.ssl.enabled-protocols=TLSv1.2,TLSv1.3

🔐 Disable TLS 1.0/1.1 — they are deprecated and insecure.


✅ 4. Cipher Suites

Spring Boot (via Tomcat) negotiates secure ciphers by default.
You can explicitly define them:

server.ssl.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,...

Use modern ciphers like ECDHE + AES_GCM.
Avoid RC4, 3DES, NULL, or EXPORT ciphers.


✅ 5. Mutual TLS (mTLS)

To require client certs:

server.ssl.client-auth=need

Modes:

  • none: default (no client cert)
  • want: optional client cert
  • need: mandatory client cert (for mTLS)

✅ 6. Generating Keystore & Truststore

Convert PEM to PKCS12:

openssl pkcs12 -export \
  -in client.crt \
  -inkey client.key \
  -certfile ca.crt \
  -out client-keystore.p12 \
  -name client

Then import trusted CA into truststore (if using JKS):

keytool -import -alias myca -file ca.crt -keystore truststore.jks


✅ 7. Spring Boot with Reverse Proxies (e.g., Kong, F5)

If TLS termination is done by Kong/F5 and Spring Boot sits behind it:

  • Use X-Forwarded headers: server.forward-headers-strategy=framework
  • Do not terminate TLS inside Spring unless you need end-to-end TLS.

✅ Summary: What to Account For

AreaKey Considerations
🔐 FormatUse PKCS12 for best compatibility
🧾 TrustTruststore must contain root CA or intermediate
🔄 ChainInclude full cert chain in keystore
🌐 ProtocolEnable TLSv1.2+ only
🔐 CiphersUse strong, modern suites
🔁 mTLSSet client-auth=need + configure truststore
🔀 ProxyHandle X-Forwarded-* if behind Kong/F5

Would you like:

  • A working Spring Boot + mTLS project example?
  • An OpenSSL script to prepare the .p12 files?
  • A Kong + Spring Boot mTLS walkthrough?

Let me know your setup.