|
| 1 | +# Service benchmarks |
| 2 | + |
| 3 | +This module is used for benchmarking the performance of generated clients against AWS services. The top 7 services (by |
| 4 | +traffic coming from the AWS SDK for Kotlin) are tested and metrics are captured with summaries distilled after the runs |
| 5 | +are complete |
| 6 | + |
| 7 | +## Instructions |
| 8 | + |
| 9 | +To run the benchmarks: |
| 10 | +* `./gradlew :tests:benchmarks:service-benchmarks:bootstrapAll` |
| 11 | + This ensures that all the required service clients are bootstrapped and ready to be built. **You only need to do this |
| 12 | + once** in your workspace unless you clean up generated services or make a change to codegen. |
| 13 | +* `./gradlew build` |
| 14 | + This builds the whole SDK. |
| 15 | +* `./gradlew :tests:benchmarks:service-benchmarks:run` |
| 16 | + This runs the benchmark suite and prints the results to the console formatted as a Markdown table. |
| 17 | + |
| 18 | +## Baseline as of 8/8/2023 |
| 19 | + |
| 20 | +The following benchmark run serves as a baseline for future runs: |
| 21 | + |
| 22 | +### Environment |
| 23 | + |
| 24 | +| Hardware type | Operating system | SDK version | |
| 25 | +|----------------|------------------|-----------------| |
| 26 | +| EC2 m5.4xlarge | Amazon Linux 2 | 0.30.0-SNAPSHOT | |
| 27 | + |
| 28 | +### Results |
| 29 | + |
| 30 | +| | Overhead (ms) | n | min | avg | med | p90 | p99 | max | |
| 31 | +| :--- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | |
| 32 | +| **S3** | | | | | | | | | |
| 33 | +| —HeadObject | | 1715 | 0.334 | 0.561 | 0.379 | 0.521 | 3.149 | 20.071 | |
| 34 | +| —PutObject | | 739 | 0.306 | 0.492 | 0.337 | 0.389 | 7.958 | 16.556 | |
| 35 | +| **SNS** | | | | | | | | | |
| 36 | +| —GetTopicAttributes | | 3041 | 0.235 | 0.494 | 0.354 | 0.461 | 2.964 | 17.129 | |
| 37 | +| —Publish | | 1001 | 0.199 | 0.394 | 0.224 | 0.420 | 1.262 | 16.160 | |
| 38 | +| **STS** | | | | | | | | | |
| 39 | +| —AssumeRole | | 1081 | 0.273 | 0.419 | 0.349 | 0.485 | 0.622 | 14.781 | |
| 40 | +| —GetCallerIdentity | | 4705 | 0.157 | 0.242 | 0.184 | 0.217 | 0.414 | 13.459 | |
| 41 | +| **CloudWatch** | | | | | | | | | |
| 42 | +| —GetMetricData | | 1500 | 0.174 | 1.352 | 0.219 | 3.239 | 13.830 | 15.193 | |
| 43 | +| —PutMetricData | | 2452 | 0.133 | 1.194 | 0.144 | 1.911 | 13.007 | 14.862 | |
| 44 | +| **CloudWatch Events** | | | | | | | | | |
| 45 | +| —DescribeEventBus | | 1500 | 0.156 | 0.290 | 0.187 | 0.238 | 0.530 | 18.934 | |
| 46 | +| —PutEvents | | 4577 | 0.152 | 0.293 | 0.176 | 0.378 | 3.921 | 10.022 | |
| 47 | +| **DynamoDB** | | | | | | | | | |
| 48 | +| —GetItem | | 4223 | 0.135 | 0.154 | 0.148 | 0.164 | 0.216 | 2.415 | |
| 49 | +| —PutItem | | 3059 | 0.130 | 0.154 | 0.145 | 0.178 | 0.193 | 1.771 | |
| 50 | +| **Pinpoint** | | | | | | | | | |
| 51 | +| —GetEndpoint | | 555 | 0.220 | 0.401 | 0.406 | 0.452 | 0.506 | 6.606 | |
| 52 | +| —PutEvents | | 415 | 0.242 | 0.400 | 0.420 | 0.466 | 0.619 | 2.762 | |
| 53 | + |
| 54 | +## Methodology |
| 55 | + |
| 56 | +This section describes how the benchmarks actually work at a high level: |
| 57 | + |
| 58 | +### Selection criteria |
| 59 | + |
| 60 | +These benchmarks select a handful of services to test against. The selection criterion is the top 7 services by traffic |
| 61 | +coming from the AWS SDK for Kotlin (i.e., not from other SDKs, console, etc.). As of 7/28, those top 7 services are S3, |
| 62 | +SNS, STS, CloudWatch, CloudWatch Events, DynamoDB, and Pinpoint (in descending order). |
| 63 | + |
| 64 | +For each service, two APIs are selected roughly corresponding to a read and a write operation (e.g., S3::HeadObject is |
| 65 | +a read operation and S3::PutObject is a write operation). Efforts are made to ensure that the APIs selected are the top |
| 66 | +operations by traffic but alternate APIs may be selected in the case of low throttling limits, high setup complexity, |
| 67 | +etc. |
| 68 | + |
| 69 | +### Workflow |
| 70 | + |
| 71 | +Benchmarks are run sequentially in a single thread. This is the high-level workflow for the benchmarks: |
| 72 | + |
| 73 | +* For each benchmark service: |
| 74 | + * Instantiate a client with a [special telemetry provider](#telemetry-provider) |
| 75 | + * Run any necessary service-specific setup procedures (e.g., create/configure prerequisite resources) |
| 76 | + * For each benchmark operation: |
| 77 | + * Run any necessary operation-specific setup procedures (e.g., create/configure prerequisite resources) |
| 78 | + * Warmup the API call |
| 79 | + * Measure the API call |
| 80 | + * Aggregate operation metrics |
| 81 | + * Run any necessary operation-specific cleanup procedures (e.g., delete resources created in the setup step) |
| 82 | + * Run any necessary service-specific cleanup procedures (e.g., delete resources created in the setup step) |
| 83 | + * Print overall metrics summary |
| 84 | + |
| 85 | +### Telemetry provider |
| 86 | + |
| 87 | +A custom [benchmark-specific telemetry provider][1] is used to instrument each service client. This provider solely |
| 88 | +handles metrics (i.e., no logging, tracing, etc.). It captures specific histogram metrics from an allowlist (currently |
| 89 | +only `smithy.client.attempt_overhead_duration`) and aggregates them for the duration of an operation run (not including |
| 90 | +the warmup phase). After the run is complete, the metrics are aggregated and various statistics are calculated (e.g., |
| 91 | +minimum, average, median, etc.). |
| 92 | + |
| 93 | +[1]: common/src/aws/sdk/kotlin/benchmarks/service/telemetry/BenchmarkTelemetryProvider.kt |
0 commit comments