ArchitectMind
  1. Home
  2. Tutorials
  3. Book 8 · Architecture Quality Attributes
  4. Volume II
  5. Latency Components
Book 8 · Volume II — Performance & Capacity · Topic 1.2

Latency Components

Network · CPU · database · serialization · queueing

11 min readStage 3 · Systems10 interview questions
Chapter
Chapter 1 — Performance Fundamentals
Prerequisites
Topic 1.1
You will be able to
Break end-to-end latency into network, CPU, database, serialization and queueing components, measure each with the right tool, estimate them with rules of thumb, find the dominant component, and pick the tactic that addresses it
Covers
Network · CPU · Database · Serialization · Queueing
On this page
  1. 1. Concept / Definition
  2. 2. Why It Exists
  3. 3. Core Concepts
  4. 4. How It Works Internally — Decomposing with Traces
  5. 4A. Deep Dive — Service Time vs Waiting Time
  6. 5. APIs / Features / Syntax
  7. 6. Practical Examples
  8. 7. Common Problems & Mistakes
  9. 8. Performance & Production Considerations
  10. 9. Architecture & Design Considerations
  11. 10. Interview Questions & Answers

1Concept / Definition

End-to-end latency is the sum of time spent in five kinds of activity on the critical path. Optimising without decomposing is guesswork.

Where the time goes — latency components
Figure 1 — Where the time goes — latency components
ComponentWhat consumes timeTypical range (per hop)
NetworkPropagation, RTTs, TLS handshakes, bandwidth0.3 ms (same AZ) … 80 ms (4G)
CPUBusiness logic, framework overhead, GC, crypto0.1 … 200 ms
DatabaseParsing, planning, I/O, locks, round trips1 … 100+ ms
SerializationEncoding/decoding JSON, protobuf, compression10 µs … 5 ms
QueueingWaiting for threads, connections, locks, partitions0 … unbounded
Table 1 — Five components

2Why It Exists

A request crosses many components, each with its own cost and failure modes. Without decomposition teams rewrite code (CPU) when the time is in a sequential network chain, or scale pods when the time is in a database lock.

Components on the request path
Figure 2 — Components on the request path
SymptomLikely component
High latency, low CPUNetwork, database, queueing
Latency proportional to payload sizeSerialization, bandwidth
Latency spikes every few secondsGC (CPU), queueing
Latency grows with loadQueueing
Latency high only for some usersNetwork (geography, mobile)
Table 2 — Symptoms point to components

3Core Concepts

3.1 Network

Latency numbers worth knowing
Figure 3 — Latency numbers worth knowing
Network costMitigation
Round trips (RTT) per callFewer, coarser calls; batch; co-locate
TCP + TLS handshakesKeep-alive, connection pools, HTTP/2, TLS 1.3 resumption
Cross-AZ hops (~1 ms)Zone-aware routing for chatty paths
Cross-region (tens of ms)Serve from nearest region; avoid synchronous cross-region calls
Bandwidth / payloadCompression, pagination, smaller DTOs
Table 3 — Network tactics

3.2 CPU

CPU consumerHow to see itTactic
Business logicJFR / async-profiler flame graphsBetter algorithms, precompute
Framework overheadProfiles (reflection, proxies)Leaner paths, AOT/CDS
Garbage collectionGC logs, jvm.gc.pauseLess allocation, ZGC, right-sized heap
Crypto (TLS, JWT)ProfilesSession resumption, cache JWKS
LoggingProfilesAsync appenders, lower verbosity
Table 4 — CPU components

3.3 Database

Inside a database call
Figure 4 — Inside a database call
DB latency partMeasureTactic
Pool waithikaricp.connections.pending, acquire timePool sizing, shorter transactions
Round tripsQueries per requestBatching, JOINs, fewer calls
Execution / I/OPerformance Insights, EXPLAIN ANALYZEIndexes, covering indexes
LocksLock waits, deadlocksShorter transactions, optimistic locking
Result sizeRows/bytes returnedProjections, pagination
Table 5 — Database components (Chapter 5 goes deeper)

3.4 Serialization

Serialization cost — 20 KB cart payload
Figure 5 — Serialization cost — 20 KB cart payload
TacticEffect
Smaller DTOs (only needed fields)Less encode/decode and transfer
Records + Jackson modules / BlackbirdFaster JSON
Protobuf/Avro for internal calls3–4× faster, smaller
Compression for large payloadsLess transfer, more CPU
Avoid double serializatione.g., JSON string inside JSON
Table 6 — Serialization tactics

3.5 Queueing

Queueing delay grows non-linearly
Figure 6 — Queueing delay grows non-linearly
QueueWhereSymptom
Request threadsServlet/Netty executorsTime before handler starts
Connection poolsHikari, HTTP clientsAcquire time
LocksDB rows, synchronizedLock wait
MessagingKafka partitions, SQSConsumer lag
OS/networkAccept backlog, NICRare, under extreme load
Table 7 — Where requests queue

4How It Works Internally — Decomposing with Traces

StepToolOutput
1OpenTelemetry Java agent on all servicesSpans per hop
2Group spans by type (HTTP client, DB, messaging)Time per component
3Identify critical path (sequential spans)What actually matters
4Add JFR profile for CPU-heavy spansHot methods
5Compare with pool/queue metricsWait vs work
6Build latency budget tableOwner per component
Table 8 — Decomposition method
Span (checkout p95)DurationComponentOn critical path?
HTTP server span690 msTotal—
gRPC pricing110 msNetwork + CPUYes (parallel with inventory 90 ms)
JDBC (6 statements)140 msDatabaseYes
HTTP gateway230 msNetwork + dependencyYes
JSON encode/decode45 msSerializationYes
Waiting for pool/thread95 msQueueingYes
Logic70 msCPUYes
Table 9 — Trace-based breakdown

4ADeep Dive — Service Time vs Waiting Time

Every component has service time (doing work) and waiting time (queued). Waiting depends on utilisation: W_queue ≈ S × ρ/(1−ρ) for a simple queue. That means you can reduce latency without making anything faster — by lowering utilisation (more capacity) or smoothing bursts.

UtilisationService 100 ms → total latency
50%≈ 200 ms
70%≈ 330 ms
90%≈ 1,000 ms
Table 10 — Same code, different latency

5APIs / Features / Syntax

BASH
# Profile a running checkout pod for 60 s (JDK Flight Recorder, Java 25)
jcmd 1 JFR.start name=perf duration=60s settings=profile filename=/tmp/checkout.jfr
jfr print --events jdk.ExecutionSample /tmp/checkout.jfr | head -50
jfr summary /tmp/checkout.jfr            # GC pauses, allocation, lock contention
YAML
# Spring Boot 4: HikariCP and HTTP client metrics expose queueing components
spring.datasource.hikari:
  maximum-pool-size: 30
  register-mbeans: true              # hikaricp.connections.pending / acquire
management.observations.http.client.requests.name: http.client.requests
JAVA
// Protobuf for internal gRPC calls instead of JSON (serialization component)
PriceQuote quote = pricingStub.withDeadlineAfter(150, TimeUnit.MILLISECONDS)
        .quote(QuoteRequest.newBuilder().addAllSkus(cart.skus()).build());
ComponentPrimary tool
NetworkTraces, VPC flow logs, RUM
CPUJFR, async-profiler
DatabasePerformance Insights, pg_stat_statements, EXPLAIN
SerializationJFR allocation + CPU samples, JMH
QueueingPool metrics, executor metrics, consumer lag
Table 11 — Tools per component

6Practical Examples

6.1 ShopNow checkout: largest slice first

ComponentBeforeChangeAfter
Dependency wait (gateway)230 msConnection pool 20 → 40, keep-alive160 ms
Queueing95 msPool tuning, 70% CPU target20 ms
Database140 ms6 → 2 round trips (batching)95 ms
Serialization45 msSmaller DTO, protobuf to pricing20 ms
Table 12 — Result: p95 690 → 480 ms

6.2 GC spikes

Checkout p99 spiked every 20 s. GC logs showed 180 ms G1 pauses from 2.4 MB allocation per request. Reducing allocation (reusing buffers, records instead of maps) and switching to generational ZGC cut pauses to < 1 ms.

6.3 Cross-AZ chattiness

A pricing call made 14 cache lookups to a Valkey node in another AZ (~1 ms each). Batching into one MGET removed 13 ms from p50.

6.4 Worked example — network arithmetic

PatternRTTsLatency at 1 ms RTT
10 sequential calls1010 ms + work
10 parallel calls1 (max)~1 ms + slowest work
1 batched call1~1 ms + batch work
Table 13 — Round trips dominate at scale

6.5 Worked example — payload diet

ChangePayloadp95 transfer on 4G
Full product entity900 KB1.4 s
DTO with needed fields180 KB300 ms
+ brotli40 KB70 ms
Table 14 — Serialization + network

6.6 Worked example — component table for an interview

ComponentHow I'd find itTactic
NetworkTrace spans per hopFewer hops, parallel, keep-alive
CPUFlame graphAlgorithm, allocation
DBPerformance InsightsIndex, batch
SerializationProfile encode/decodeSmaller DTO, binary format
QueueingPool pending metricsHeadroom, pool sizing
Table 15 — Structured answer
Component → main tactics
Figure 7 — Component → main tactics

6.7 Worked example — estimating latency before building

Design: product page APIEstimate
Client ↔ CloudFront (Mumbai, 4G)60 ms RTT
CloudFront → ALB (cache miss)5 ms
Service CPU (JSON 30 KB)12 ms
Valkey lookup (same AZ, 1 call)1 ms
Aurora reader (cache miss, indexed)4 ms
Serialization2 ms
Server latency≈ 20 ms (hit) / 25 ms (miss)
Response time (4G, warm connection)≈ 90–120 ms
Table 16 — Back-of-envelope before writing code

6.8 Worked example — lock queueing on a hot row

ObservationValue
Inventory update p991.8 s at flash sale
DB CPU35% (not busy)
Lock wait (Performance Insights)92% of DB time
FixReserve via conditional UPDATE per SKU + sharded counters for the hottest SKU
Resultp99 45 ms
Table 17 — Queueing hidden as "database latency"

6.9 Worked example — the same request in three regions

Client locationRTT to ap-south-1Response time p95
Mumbai12 ms240 ms
Kolkata35 ms300 ms
Singapore customers60 ms420 ms
Table 18 — Distance is a latency component you cannot optimise away — only move closer

7Common Problems & Mistakes

MistakeFix
Optimising CPU when network dominatesTrace first
Ignoring waiting timePool/queue metrics
Chatty services across AZsBatch, co-locate
Large payloads to mobileDTOs, compression
GC ignoredAllocation profiling, modern collectors
Treating DB as one numberBreak into pool, RTT, execution, locks
Table 19 — Mistakes and fixes

8Performance & Production Considerations

ConsiderationPractice
Continuous profilingLow-overhead JFR in production
Trace samplingTail-based sampling keeps slow traces
Component dashboardsDB time, dependency time, queue time per service
Regression detectionJMH for serialization hot paths
Table 20 — Operating component visibility

Component visibility has to be permanent, because latency regressions usually arrive with a dependency upgrade, data growth or a traffic shift rather than with an obvious code change. Run JFR continuously in production with the default settings, which cost around 1% overhead, so a profile already exists when p99 moves. Use tail-based sampling in the OpenTelemetry Collector so the slowest and failed traces are always kept, rather than a random 1% that rarely contains the outliers you need. Each service dashboard should split time into database, dependency, queue and own-CPU time, so a shift between components is visible at a glance. Finally, guard serialization and other hot paths with JMH benchmarks in CI, and run a load test against the latency budget before every peak event.

9Architecture & Design Considerations

GuidelineDetail
Minimise sequential network hopsCoarser APIs, parallel fan-out
Keep data close to computeCaches, same-AZ reads
Choose efficient internal formatsgRPC/protobuf between services
Design for low utilisation of shared resourcesQueueing is the silent component
Table 21 — Design guidance

10Interview Questions & Answers

Q1BasicConcept

Name the five latency components.

The five components are network, CPU, database, serialization and queueing. Network time covers propagation, round trips, TCP and TLS handshakes and bandwidth. CPU time is business logic, framework overhead, garbage collection and crypto. Database time includes pool wait, query parsing and planning, execution and I/O, lock waits and result transfer. Serialization is encoding and decoding JSON or protobuf, plus compression. Queueing is time spent waiting for threads, connections, locks or partitions. End-to-end latency is the sum of these along the critical path, so the useful skill is not naming them but measuring which one dominates a specific request before changing anything.

Q2BasicConcept

What is an RTT?

RTT, or round-trip time, is the time for a message to travel from one endpoint to a peer and for the reply to come back, excluding processing on the far side. It is the basic unit of network cost because protocols need several of them: a new TCP connection costs one RTT, a full TLS 1.2 handshake two more and TLS 1.3 one, before the first request byte is sent. Typical values are around 0.3 ms within an AZ, about 1 ms across AZs, tens of milliseconds across regions and 60 to 80 ms on 4G. Ten sequential calls at 1 ms RTT cost 10 ms before any work happens.

Q3IntermediateScenario

How do you find which component dominates?

Trace first. Instrument every service with the OpenTelemetry Java agent so each hop produces spans, then group span time by type: HTTP and gRPC clients for network and dependencies, JDBC for the database, messaging spans and the gaps between spans. Identify the critical path, because parallel calls only count for the slowest branch. For CPU-heavy spans, capture a JFR or async-profiler profile to see hot methods and GC. Then compare with pool and executor metrics, such as hikaricp.connections.pending, to separate waiting from working. The result is a latency budget table with an owner per component, and you attack the largest critical-path slice first.

Q4IntermediateTricky

How can latency rise without code changes?

Through queueing. Waiting time depends on utilisation, not on how fast the code is: for a simple queue, waiting is roughly service time multiplied by ρ/(1−ρ). A 100 ms operation responds in about 200 ms at 50% utilisation, 330 ms at 70% and around a second at 90%, with identical code. So more traffic, a smaller connection pool, a noisy neighbour stealing CPU, a slower dependency holding threads longer, or a hot row creating lock waits can all raise latency without a deployment. Other causes include data growth changing query plans and cache hit ratios falling. Pool, executor and lock-wait metrics reveal this hidden component.

Q5Senior EngineerDesign

How do you reduce network latency between services?

Remove round trips first, because they dominate. Replace chatty call sequences with coarser APIs or batch requests, for example one Valkey MGET instead of fourteen GETs, and run independent calls in parallel so you pay only for the slowest. Reuse connections with keep-alive and pooling, prefer HTTP/2 or gRPC multiplexing, and use TLS 1.3 with session resumption to avoid repeated handshakes. Keep chatty paths in the same AZ with zone-aware routing, since each cross-AZ hop adds around a millisecond, and never put synchronous cross-region calls on a user request path. Finally, shrink payloads with smaller DTOs and compression where bandwidth matters.

Q6Senior EngineerInternals

How does GC affect latency?

Garbage collection consumes CPU and, in its pause phases, stops application threads, so any request in flight during a pause waits for it. The effect lands mostly in the tail: average latency barely moves, but p99 and p99.9 spike whenever a pause coincides with requests. Allocation rate is the main driver, because more allocation means more frequent collections. ShopNow's checkout allocated 2.4 MB per request and saw 180 ms G1 pauses every 20 seconds. Reducing allocation and moving to generational ZGC, the only ZGC mode in Java 25, cut pauses below a millisecond. Monitor jvm.gc.pause and allocation rate, and size heaps and container memory together.

Q7Technical ArchitectTrade-off

Why use protobuf internally?

Protobuf, usually with gRPC, encodes and decodes several times faster than JSON and produces much smaller messages, which cuts both serialization CPU and network transfer on high-volume internal paths. It also gives a typed schema with clear rules for backward-compatible evolution, which suits contracts between teams. The costs are real: messages are not human-readable, debugging needs tooling, browsers and many partners expect JSON, and schema files must be shared and versioned. That is why the usual split is protobuf between services, where volume and latency matter, and JSON at the edge for public APIs. Measure first, because on low-volume calls the gain may be negligible.

Q8Technical ArchitectInternals

What parts make up database latency?

Database latency is several components, not one number. First is pool wait, the time to borrow a connection, visible as HikariCP acquire time and pending threads. Then come the network round trip to the database, parse and plan time, and execution, which includes CPU, buffer cache misses and storage I/O. Lock waits follow, often the hidden part under contention, and finally transferring and mapping the result set. Each needs a different fix: pool sizing, batching to cut round trips, indexes, shorter transactions or optimistic locking, and projections or pagination. Aurora Performance Insights and pg_stat_statements show where database time actually goes, for example lock waits rather than CPU.

Q9Solution ArchitectBehavioural

How would you present a latency analysis?

Present it as a decision, not a data dump. Start with the business symptom, for example checkout p95 at 690 ms against an 800 ms target for the next sale. Show one component table built from traces: each critical-path slice with its duration, owner and evidence, so nobody argues from opinion. Highlight the critical path and the largest slices, then propose the top two or three changes with the expected saving, effort and risk of each. For ShopNow that was pool tuning and batching, taking p95 from 690 to 480 ms. Finish with how you will verify the result, through load tests and dashboards, and who owns each action.

Q10Solution ArchitectDesign

What architectural choices reduce latency components structurally?

The structural choices remove latency rather than tune it. Cut synchronous hops by giving services coarser APIs, letting them own the data they need, or composing in a BFF with parallel fan-out. Keep data close to compute with caches, same-AZ reads and CDN edges, and serve users from a nearby region, because distance cannot be optimised away. Move side effects such as emails, analytics and notifications off the request path using events or an outbox. Use efficient internal formats such as protobuf. Finally, design shared resources for headroom, keeping utilisation of pools, partitions and hot rows low, because queueing grows non-linearly near saturation.

Newsletter

Get new tutorials every week

New ArchitectMind tutorials and interview questions, once a week. No spam, unsubscribe anytime.

Almost done! Check your inbox and click the confirmation link to complete your subscription.
Keep going in Book 8

Architecture Quality Attributes

Volume I · Topic 1.1

Quality Attributes

Quality Attributes & Architectural Thinking

Volume I · Topic 1.2

Why Quality Attributes Matter

Quality Attributes & Architectural Thinking

Volume I · Topic 1.3

Quality Attribute Categories

Quality Attributes & Architectural Thinking

Volume II · Topic 1.1

Performance

Performance & Capacity

Volume II · Topic 1.3

Tail Latency

Performance & Capacity

Volume III · Topic 1.1

Scalability

Scalability & Elasticity

Volume III · Topic 1.2

Vertical Scaling

Scalability & Elasticity

Volume III · Topic 1.3

Horizontal Scaling

Scalability & Elasticity

Volume IV · Topic 1.1

Availability Fundamentals

Availability, Reliability & Resilience

Volume IV · Topic 1.2

Availability Calculation

Availability, Reliability & Resilience

Volume IV · Topic 1.3

Nines of Availability

Availability, Reliability & Resilience

Volume V · Topic 1.1

Security Requirements

Security, Privacy & Compliance

Volume V · Topic 1.2

Security Architecture

Security, Privacy & Compliance

Volume V · Topic 1.3

Threat Modeling

Security, Privacy & Compliance

Volume VI · Topic 1.1

Maintainability

Maintainability, Modifiability & Testability

Volume VI · Topic 1.2

Technical Debt

Maintainability, Modifiability & Testability

Volume VI · Topic 1.3

Code Quality

Maintainability, Modifiability & Testability

Volume VII · Topic 1.1

What Is Operability?

Operability, Observability & Deployability

Volume VII · Topic 1.2

Operational Readiness

Operability, Observability & Deployability

Volume VII · Topic 1.3

Production Readiness Checklist

Operability, Observability & Deployability

Volume VIII · Topic 1.1

Why Evaluate Architecture?

Quality Attribute Trade-offs & Architecture Evaluation

Volume VIII · Topic 1.2

Architecture Evaluation Methods

Quality Attribute Trade-offs & Architecture Evaluation

Volume VIII · Topic 1.3

ATAM

Quality Attribute Trade-offs & Architecture Evaluation