Foundations of Serverless Applications and Microservices

Chapter 12
Performance, Scalability, and Cost Optimization

Diploma in Cloud Computing
Foundations of Serverless Applications and Microservices   •   Diploma

Performance, Scalability, and Cost Optimization

Introduction

Serverless applications and microservices can scale rapidly, but scalability does not automatically guarantee good performance or low cost. A function that completes quickly may still be expensive if it is invoked millions of times. A service may accept high traffic but fail because of database connection limits, queue backlogs, throttling, or downstream latency. Professional cloud engineers therefore evaluate performance, scalability, reliability, and cost together.

This chapter presents a practical framework for measuring workloads, identifying bottlenecks, designing for concurrency, applying caching, understanding capacity limits, selecting meaningful latency measures, comparing pricing models, calculating total cost of ownership, and applying FinOps and sustainability principles.

Learning Objectives

By the end of this chapter, you should be able to:

  • distinguish load testing, stress testing, profiling, and benchmarking;
  • analyse concurrency, throughput, latency, capacity, and saturation;
  • identify bottlenecks in serverless and microservice architectures;
  • select suitable caching strategies and understand their limitations;
  • estimate serverless and container-based costs;
  • evaluate total cost of ownership rather than price alone;
  • apply FinOps practices to cloud workloads;
  • relate performance decisions to energy use, sustainability, governance, and risk.

1. A Performance Model for Distributed Applications

Performance is multidimensional. The most important measures are:

MeasureMeaningTypical unit
Response timeTime from request submission to completed responsemilliseconds or seconds
ThroughputCompleted work per unit of timerequests/s, transactions/s
ConcurrencyWork being processed at the same timerequests or active tasks
UtilisationProportion of a resource being usedpercentage
Error rateProportion of unsuccessful requestspercentage
AvailabilityProportion of time a service is usablepercentage
Cost efficiencyCost for a unit of business valuecurrency/request or currency/order

A useful relationship between throughput, concurrency, and response time is Little’s Law:

L = λW

Here, L is the average number of items in the system, λ is the average arrival or completion rate, and W is the average time an item spends in the system. Units must be consistent. For example, if λ is 100 requests/s and W is 0.2 s, average concurrency is 20 requests. Little’s Law applies to a stable system over a suitable observation period; it does not by itself prove that a system can sustain a particular load.

Throughput can be expressed as:

Throughput = Completed ext{ work} ÷ Observation ext{ time}

For request systems, this is usually requests per second. Higher throughput is not necessarily better if it is achieved with unacceptable latency or errors.

Latency distributions

Average latency can conceal serious user experience problems. A system may have a 100 ms average while a small but important proportion of requests takes several seconds. Engineers therefore examine percentiles:

  • p50: median latency;
  • p90: latency at or below which 90% of requests complete;
  • p95: latency at or below which 95% complete;
  • p99: latency at or below which 99% complete.

Percentiles should be calculated from individual observations or correctly merged histograms. Averaging separately calculated p99 values is generally invalid. Measurements should also distinguish client, network, gateway, application, database, and downstream-service time.

A simple latency budget decomposes end-to-end time:

Ttotal = Tnetwork + Tqueue + Tcompute + Tdatabase + Tdownstream + Tserialization

The terms represent network, queueing, computation, database, downstream-service, and serialization time. This is an operational model rather than a universal physical identity: overlapping operations, retries, and asynchronous work must be represented carefully. The equation is most useful when components are measured consistently.

2. Load Testing and Profiling

Load-testing methods

Load testing evaluates behaviour under an expected workload. The test should represent realistic request rates, payload sizes, user behaviour, data distribution, authentication, and dependency responses.

Stress testing increases demand beyond the expected level to discover failure points and recovery behaviour.

Spike testing introduces a sudden increase or decrease in demand. It is particularly relevant to event-driven systems and auto-scaling policies.

Soak testing runs a sustained workload for a long period to identify memory leaks, connection exhaustion, queue growth, thermal effects, and cost accumulation.

Capacity testing determines the maximum sustainable workload while agreed service-level objectives remain satisfied.

A professional test plan defines:

  1. the workload model and traffic distribution;
  2. the environment and configuration;
  3. success criteria, such as p95 latency and error rate;
  4. data preparation and dependency simulation;
  5. warm-up and cool-down periods;
  6. observability requirements;
  7. rollback and safety controls;
  8. cost and quota limits.

Testing production systems requires authorization, rate limits, data protection, and safeguards against accidental denial of service. Synthetic or anonymised data should be used where possible.

Profiling and tracing

Load testing shows what happens under demand; profiling helps explain why. CPU profiling identifies expensive functions, while memory profiling identifies allocation growth, leaks, and excessive object retention. I/O profiling reveals slow disk, network, or database operations.

Distributed tracing follows a request across gateways, functions, services, queues, and databases. A trace should include correlation identifiers, timestamps, service names, status, and selected attributes. Sensitive data, credentials, and personal information must not be placed in traces.

A sound investigation uses three evidence sources:

  • metrics, which show aggregate behaviour;
  • logs, which provide detailed events;
  • traces, which show causal request paths.

A common error is to optimise code before proving that code is the bottleneck. For example, reducing function execution time by 20% has little value if 80% of total latency is caused by a database call.

3. Concurrency, Queues, and Capacity Limits

Concurrency is the number of operations active at a moment in time. In serverless platforms, concurrency may be limited by account quotas, function reservations, regional limits, or downstream capacity. In microservices, it may be limited by thread pools, worker processes, connection pools, CPU, memory, or message-consumer capacity.

If demand exceeds available concurrency, requests may queue, be throttled, rejected, or time out. Queueing can create a feedback loop: longer waiting increases concurrency, which consumes more resources and causes further delay.

A rough concurrency estimate is:

C ≈ λ × W

where C is average concurrency, λ is arrival rate in requests/s, and W is average service time in seconds. This estimate assumes a reasonably stable workload and does not account for bursts, retries, or variance. Capacity planning must include a safety margin and must examine peak rather than only average demand.

For a service with 250 requests/s and average processing time of 0.08 s:

C ≈ 250 × 0.08 = 20

The service needs approximately 20 active execution slots during the measured average period. If bursts produce 1,000 requests/s, concurrency would temporarily approach 80 at the same processing time. A design that supports only 20 concurrent executions may therefore queue or throttle during bursts.

Downstream bottlenecks

Scaling a front-end function from 10 to 1,000 instances can overload a database that supports only 100 connections. This is the thundering herd or fan-out problem. Controls include:

  • connection pooling and reuse;
  • reserved concurrency;
  • bounded worker pools;
  • queues and asynchronous processing;
  • bulkheads that isolate failures;
  • circuit breakers;
  • backpressure and load shedding;
  • batch reads and writes;
  • database replicas or partitioning where appropriate.

Retries require special care. Exponential backoff with jitter reduces synchronized retry storms, but retries should be bounded and used only for transient failures. Operations should be idempotent so that repeated messages do not create duplicate business effects.

4. Caching and Data Access

Caching stores reusable results closer to consumers or compute components. A cache can reduce latency, database load, and cost, but it introduces consistency, invalidation, memory, and security concerns.

Common cache locations include:

  • browser or client cache;
  • content delivery network cache;
  • API gateway cache;
  • distributed in-memory cache;
  • function-local or process-local cache;
  • database query or materialised-result cache.

A simple cache hit ratio is:

Hit ext{ ratio} = Cache ext{ hits} ÷ (Cache ext{ hits} + Cache ext{ misses})

If a cache records 9,000 hits and 1,000 misses, the hit ratio is 0.9, or 90%. This metric is meaningful only when the observation period, key population, and request types are specified.

A time-to-live (TTL) defines how long an item may remain cached. Short TTLs improve freshness but reduce hit ratio; long TTLs improve reuse but increase staleness risk. Invalidation may be time-based, event-driven, version-based, or explicit.

Caching is inappropriate when:

  • information is highly confidential and access controls are weak;
  • data changes too frequently to benefit from reuse;
  • stale values could cause legal, safety, or financial harm;
  • cache keys omit tenant or authorisation context;
  • invalidation is not operationally reliable.

Cache stampede prevention includes request coalescing, probabilistic early refresh, staggered expiration, and serving a controlled stale value where business rules permit it.

5. Scaling Strategies

Vertical and horizontal scaling

Vertical scaling increases the resources assigned to one instance, such as memory or CPU. It is simple but limited by maximum instance size and can create a single large failure domain.

Horizontal scaling adds instances. It improves resilience and capacity but requires stateless design, load balancing, coordination, and attention to shared resources. Serverless platforms commonly provide horizontal scaling automatically, but automatic scaling does not eliminate quotas or downstream limits.

Synchronous and asynchronous work

Synchronous calls are suitable when the caller needs an immediate result and the operation fits within latency objectives. Asynchronous queues are useful for email, report generation, image processing, analytics, and other work that need not block the user.

Asynchronous designs improve burst absorption but introduce eventual consistency, duplicate delivery, ordering issues, dead-letter handling, and monitoring requirements. A queue is not a substitute for capacity planning: an unbounded queue can merely hide overload.

Cold starts and warm execution

Serverless functions may experience cold starts when a new execution environment is created. Cold-start time depends on runtime, package size, initialisation work, networking, and dependencies. Mitigations include smaller deployment packages, lazy initialisation, connection reuse, suitable runtimes, provisioned capacity where justified, and separating infrequently used features.

These techniques involve trade-offs. Keeping environments warm may improve latency but increase cost and energy consumption. The correct decision depends on the value of the latency improvement.

6. Pricing Models and Cost Estimation

Cloud pricing commonly combines:

  • request or invocation charges;
  • compute duration and allocated memory or CPU;
  • storage capacity and operations;
  • data transfer;
  • database throughput, capacity, or provisioned instances;
  • queues, events, logs, metrics, and tracing;
  • reserved or committed-use discounts;
  • support, security, and governance services.

A generic serverless compute estimate is:

Costcompute = N × (D ÷ U) × R

N is the number of invocations, D is billed duration per invocation, U is the provider’s billing time unit, and R is the price per billing unit. The estimate assumes the selected memory/CPU tier and excludes free tiers, request charges, provisioned capacity, retries, and other services.

For example, suppose 2,000,000 invocations each have a billed duration of 120 ms, billing is in 1 ms units, and the price is $0.0000000167 per MB-ms at a 512 MB allocation. The memory-duration quantity is:

2,000,000 × 120 × 512 = 122,880,000,000 ext{ MB-ms}

The compute charge is approximately:

122,880,000,000 × 0.0000000167 ≈ $2,052.10

This is an illustrative calculation, not a provider quotation. Actual prices, minimum durations, free allowances, architecture premiums, request charges, and regional rates must be checked in the current provider price list. The example also demonstrates why unverified pricing assumptions should not be used for production budgets.

For container or virtual-machine workloads, a simplified estimate is:

Costtotal = Costcompute + Coststorage + Costnetwork + Costplatform + Costoperations

The cost of idle capacity is important. A continuously running instance may be inexpensive per hour but wasteful for highly variable traffic. Conversely, serverless execution may become more expensive for constant, high utilisation. Architecture selection should therefore compare workload shape, not slogans.

7. Total Cost of Ownership and FinOps

Total cost of ownership includes more than provider invoices. Relevant categories include:

  • infrastructure and managed-service charges;
  • software licences;
  • engineering and operations labour;
  • monitoring and incident response;
  • security and compliance;
  • migration and refactoring;
  • training and support;
  • downtime, latency penalties, and lost transactions;
  • exit, portability, and data-transfer costs.

A useful unit-cost metric connects technical spending with business value:

Unit ext{ cost} = Total ext{ cost} ÷ Business ext{ units delivered}

Business units might be orders, active users, reports, claims, or successfully completed payments. Cost per request alone can encourage harmful optimisation if requests do not represent equal value.

FinOps is an organisational practice that makes cloud spending visible, accountable, and actionable. Its main principles include:

  1. Visibility: allocate costs using accounts, projects, tags, labels, and shared-cost rules.
  2. Accountability: assign ownership to teams and services.
  3. Planning: forecast demand and budgets using historical and expected workloads.
  4. Optimisation: remove waste, right-size resources, improve utilisation, and negotiate commitments where demand is predictable.
  5. Governance: use budgets, alerts, policies, quotas, and approval processes.
  6. Continuous improvement: review cost and performance together rather than treating cost as a one-time project.

Cost allocation must protect privacy and avoid using financial data to punish teams for necessary reliability or security spending. A service with a higher cost may be justified if it reduces fraud, outages, or regulatory exposure.

8. Sustainability and Responsible Optimisation

Performance and cost optimisation can reduce environmental impact by avoiding unnecessary computation, storage, network transfer, and idle capacity. Useful measures include right-sizing, efficient algorithms, batching, data compression, lifecycle policies, carbon-aware scheduling where feasible, and reducing duplicated data.

However, sustainability should not be reduced to a simplistic “fewer servers” rule. A fast workload may use more power momentarily but complete sooner; a slow workload may consume resources for longer. Engineers should consider total energy, embodied hardware impacts, service lifetime, data-centre efficiency, and user-device effects. Environmental claims should be based on credible provider disclosures or measured estimates rather than unsupported precision.

Responsible optimisation also includes accessibility, data protection, resilience, and fairness. Aggressive caching must not expose one user’s data to another. Load shedding must prioritise safety-critical or legally required transactions appropriately. Automated scaling and AI-assisted optimisation should be observable, bounded by policy, and subject to human review when decisions affect customers or regulated processes.

9. Applied Case: Illustrative Online Retail Checkout

Background

An online retailer uses an API gateway, serverless checkout functions, a managed relational database, a payment provider, and a queue for order fulfilment. During normal operation, traffic is 120 requests/s. During promotions, it rises to 600 requests/s. The target is p95 checkout latency below 800 ms and an error rate below 1%.

Problem

During a promotion, p95 latency rises to 2.4 s and payment timeouts increase. Function concurrency expands automatically, but database connections become exhausted. Retries from clients and payment calls further increase traffic. The company also observes unexpectedly high logging and data-transfer costs.

Analysis

Tracing shows that the checkout function spends little time computing. Most delay is caused by database connection waits and payment-provider calls. Load testing reproduces the problem at approximately 450 requests/s. A concurrency estimate at 600 requests/s and 0.25 s average service time is:

C ≈ 600 × 0.25 = 150

The database, however, safely supports only 80 concurrent application connections. Thus, scaling functions to 150 active executions cannot produce proportional throughput.

Approach

The team applies the following changes:

  • limits function concurrency to protect the database;
  • introduces a connection-aware proxy and reuses connections;
  • separates payment initiation from fulfilment using a queue;
  • makes order creation idempotent using a client request identifier;
  • adds bounded retries with exponential backoff and jitter;
  • caches product catalogue data with a short, controlled TTL;
  • reduces verbose payload logging and removes sensitive fields;
  • adds dashboards for p50, p95, p99, queue age, database utilisation, retries, and cost per order;
  • performs a promotion-scale soak test before the next event.

Outcome

In the next test, p95 checkout latency falls below the target for the tested traffic level, database utilisation remains within its safe range, and duplicate orders disappear. The queue absorbs fulfilment bursts, although the team adds an explicit maximum queue-age objective so that asynchronous processing does not become invisible delay. Logging costs fall after sampling and retention policies are introduced.

Learning points

The case demonstrates that automatic front-end scaling cannot overcome a constrained dependency. A performance objective must include latency, errors, queue age, and business completion. Cost controls should be designed with observability and reliability rather than applied as indiscriminate reductions.

10. Practical Optimisation Workflow

A repeatable workflow is more reliable than isolated tuning:

  1. Define service-level objectives and business outcomes.
  2. Establish a baseline under representative traffic.
  3. Instrument metrics, logs, traces, and cost allocation.
  4. Identify the dominant bottleneck using evidence.
  5. Form a hypothesis and change one major variable at a time.
  6. Test normal, peak, spike, failure, and recovery conditions.
  7. Compare p95/p99 latency, throughput, errors, resource utilisation, and unit cost.
  8. Check security, privacy, accessibility, and sustainability effects.
  9. Document the decision, assumptions, limits, and rollback plan.
  10. Review continuously as traffic, prices, code, and dependencies change.

Challenges and Limitations

Performance measurements are affected by test realism, network variability, cold starts, sampling, clock synchronisation, provider quotas, and shared infrastructure. Synthetic tests may omit real data skew or user behaviour. Percentiles can be misleading with very small samples. Cost estimates become inaccurate when free tiers, retries, storage growth, transfers, support, and operational labour are excluded.

There is also no universal optimum. Reducing latency may require provisioned capacity, which increases cost. Strong consistency may increase coordination overhead. A highly portable architecture may require more operational work than a provider-specific managed service. Engineering decisions should therefore make trade-offs explicit and align them with business and regulatory requirements.

Contemporary Developments

Current practice increasingly combines OpenTelemetry-compatible observability, continuous profiling, infrastructure-as-code policy checks, automated cost anomaly detection, and workload-aware scaling. AI assistants can help classify traces, identify unusual cost patterns, or recommend rightsizing, but recommendations require validation because models may misunderstand workload seasonality, contractual constraints, or security requirements. Explainability, access control, audit trails, and human approval remain essential for consequential changes.

Chapter Summary

Performance engineering for serverless applications and microservices requires joint analysis of latency, throughput, concurrency, errors, capacity, and cost. Load, stress, spike, soak, and capacity tests answer different questions, while metrics, logs, profiling, and distributed tracing provide complementary evidence. Little’s Law offers a useful relationship between throughput, response time, and concurrency, but burst behaviour and dependency limits must also be tested.

Caching can reduce latency and cost when freshness, authorisation, and invalidation are correctly managed. Horizontal scaling, queues, backpressure, bounded retries, and idempotency help systems handle variable demand, but scaling one tier can overload another. Cost analysis must include compute, requests, storage, transfer, observability, labour, risk, and business value. FinOps establishes shared visibility and accountability, while sustainability and responsible governance ensure that optimisation does not compromise privacy, resilience, accessibility, or compliance.

Key Terms

Performance: The effectiveness and responsiveness of a system under a defined workload.

Latency: The time required to complete an operation or return a response.

Throughput: The amount of completed work per unit of time.

Concurrency: The number of operations active at the same time.

Percentile: A value below which a specified percentage of observations fall.

Load testing: Testing with an expected or planned workload.

Stress testing: Testing beyond expected capacity to observe failure behaviour.

Soak testing: Sustained testing over an extended period.

Profiling: Measurement of resource use within application execution.

Distributed tracing: Following a request across multiple components.

Capacity: The maximum sustainable workload under stated objectives.

Backpressure: A mechanism that slows producers when consumers cannot keep up.

Cold start: Initialisation delay when a new serverless execution environment is created.

Cache hit ratio: The proportion of cache-eligible requests served from the cache.

Time-to-live: The period for which cached data remains valid.

Total cost of ownership: Direct and indirect costs over the life of a solution.

FinOps: A practice for managing cloud costs through visibility, accountability, and optimisation.

Unit cost: Cost divided by a defined business unit delivered.

Idempotency: The property that repeated execution produces the same intended business result.

Sustainability: Designing and operating systems with reduced environmental and social impact.

Review Questions

Short Answer Questions

  1. What is the difference between p95 latency and average latency?
  2. Define concurrency and explain why it matters in serverless systems.
  3. What is the purpose of a cache TTL?
  4. Name three categories of cloud cost besides compute.
  5. Why are idempotent operations important when queues and retries are used?

Long Answer Questions

  1. Explain how load testing, profiling, logging, metrics, and distributed tracing work together in performance analysis.
  2. Discuss the advantages and limitations of horizontal scaling in a microservices architecture.
  3. Explain how a database can become a bottleneck when serverless functions scale automatically.
  4. Compare synchronous and asynchronous processing, including their effects on latency, reliability, and cost.
  5. Explain the role of FinOps in achieving cost accountability without undermining reliability and security.

Analytical / Application Questions

  1. A service receives 400 requests/s and has an average response time of 150 ms. Estimate average concurrency using Little’s Law. State the assumptions behind your calculation.
  2. Design a load-testing plan for a serverless application that experiences unpredictable promotional spikes. Specify workload types, metrics, safety controls, and success criteria.
  3. A team proposes increasing function concurrency to solve high latency, although database connections are already exhausted. Analyse the proposal and recommend a safer architecture and measurement plan.

Multiple Choice Questions with Answers

Question 1

A service receives 200 requests per second and has an average response time of 0.1 seconds. Using Little’s Law, what is the approximate average concurrency?

A. 2

B. 20

C. 200

D. 2,000

Correct Answer: B. 20

Question 2

Which measure identifies the latency at or below which 95% of observations complete?

A. Mean

B. p50

C. p95

D. Maximum

Correct Answer: C. p95

Question 3

What is the main danger of scaling serverless functions without controlling a database dependency?

A. The functions become stateless

B. The database may be overloaded by connections

C. Caching becomes impossible

D. Requests stop generating logs

Correct Answer: B. The database may be overloaded by connections

Question 4

Which test is designed to identify memory leaks and long-term resource exhaustion?

A. Spike test

B. Soak test

C. Unit test

D. Smoke test

Correct Answer: B. Soak test

Question 5

A cache has 9,000 hits and 1,000 misses. What is its hit ratio?

A. 9%

B. 10%

C. 90%

D. 99%

Correct Answer: C. 90%

Question 6

Which practice most directly helps prevent duplicate business effects from message retries?

A. Increasing log verbosity

B. Using idempotent operations

C. Removing queue visibility timeouts

D. Disabling monitoring

Correct Answer: B. Using idempotent operations

Question 7

Which item is normally included in total cost of ownership but may be omitted from a provider invoice?

A. Engineering and operations labour

B. Function invocation count

C. Object storage capacity

D. Data-transfer charges

Correct Answer: A. Engineering and operations labour

Question 8

What is the primary purpose of backpressure?

A. To accelerate producers regardless of consumer capacity

B. To slow producers when consumers are overloaded

C. To eliminate all latency

D. To guarantee cache consistency

Correct Answer: B. To slow producers when consumers are overloaded

Question 9

Which FinOps principle assigns spending responsibility to teams or services?

A. Accountability

B. Compression

C. Serialisation

D. Replication

Correct Answer: A. Accountability

Question 10

Which statement about average latency is most accurate?

A. It always reveals the worst user experience

B. It is equivalent to p99 latency

C. It can hide slow tail requests

D. It cannot be measured in distributed systems

Correct Answer: C. It can hide slow tail requests

Foundations of Serverless Applications and Microservices
Chapter 12 of 15