How to Calculate Apdex Score from Latency Data in Python
Generate simulated latency samples and compute the Apdex score to gauge user satisfaction with an application's performance.
Python code
17 linesimport random
import statistics
def generate_latencies(count=100, base=100, stddev=30):
return [max(0, random.gauss(base, stddev)) for _ in range(count)]
def apdex(latencies, threshold=200):
satisfied = sum(1 for lat in latencies if lat < threshold)
tolerating = sum(1 for lat in latencies if lat >= threshold and lat < threshold * 4)
return (satisfied + tolerating / 2) / len(latencies) if latencies else 0
if __name__ == "__main__":
random.seed(42)
lat = generate_latencies()
print(f"Latencies: {lat[:5]}...")
print(f"Apdex score: {apdex(lat):.3f}")
print(f"Avg latency: {statistics.mean(lat):.1f}ms")
Output
Latencies: [426.8685625423253, 76.15577676701064, 107.99627901091701, 165.59748845021215, 113.35493176170674]...
Apdex score: 0.975
Avg latency: 99.7ms
How it works
The Apdex formula maps each latency to one of three buckets: satisfied (< threshold), tolerating (>= threshold but < 4x threshold), and frustrated (all others). The final score is (satisfied + tolerating/2) / total, giving 1.0 when all requests meet the goal. Using a seeded random generator makes the output reproducible, which is useful for unit tests. The max(0, ...) guard avoids negative latency samples from the Gaussian distribution.
Common mistakes
- Forgetting to seed the random generator, causing non-reproducible results
- Using >= vs > inconsistently in bucket boundaries, skewing the score
- Dividing by zero when the latency list is empty
- Using threshold * 4 correctly — it must be 4x, not 2x, the threshold
Variations
- Use numpy to vectorize the bucket counting for large datasets
- Compute Apdex from real latency logs instead of simulated data
Real-world use cases
- Monitoring API response times in a microservices dashboard to alert on poor user experience.
- Evaluating the impact of a new caching layer by comparing Apdex scores pre- and post-deployment.
- Setting SLOs (service level objectives) for latency-based performance targets in production.
Sponsored
More from Observability & SRE
- Adding a Correlation ID to Log Context in Python medium
- Calculate Error Rate from Log Stream in Python easy
- Check if a Timestamp Falls in a Daily Maintenance Window in Python easy
- Export Metrics with OTLP Mock in Python medium
- Generate Mock CPU and Memory Metrics in Python easy
- Generate Prometheus Text Exposition Format in Python easy
Keep learning
Related tutorials and quizzes for this topic.