| Crates.io | startled |
| lib.rs | startled |
| version | 0.9.0 |
| created_at | 2025-05-10 06:22:30.374009+00 |
| updated_at | 2025-06-29 02:45:47.345123+00 |
| description | CLI tool for benchmarking Lambda functions |
| homepage | |
| repository | https://github.com/dev7a/serverless-otlp-forwarder/tree/main/cli/startled |
| max_upload_size | |
| id | 1668129 |
| size | 495,729 |
startled CLIKnow your overhead. Fear no extension.
startled (Start Time And Response Timing Latency Evaluation & Diagnostics) is a command-line tool for detailed performance analysis of AWS Lambda functions. It provides comprehensive data on cold starts, warm invocations, memory usage, and critically, the performance impact of Lambda Extensions. This makes it an effective utility for evaluating OpenTelemetry (Otel) solutions, custom layers, and other components that integrate with the Lambda execution environment.
benchmark/testbed/ EnvironmentinitDuration), execution duration, and total cold start time.extensionOverhead value reported in Lambda platform logs, providing insight into the performance characteristics of Lambda Extensions.platform.runtimeDone logs, including responseLatencyMs, responseDurationMs, runtimeOverheadMs, producedBytes, and the runtime's own durationMs (runtimeDoneMetricsDurationMs)./all/summary/) showing performance metrics across different memory configurations (128mb, 256mb, 512mb, 1024mb) with interactive line charts for cross-configuration performance comparisons.#000000) and light (#ffffff) theme backgrounds for professional presentation.screenshots compile-time feature and a headless Chrome environment).startled from source. (Install Rust)Once startled is published to crates.io, you can install it directly using Cargo:
cargo install startled
If you want to build from the latest source code or contribute to development:
Clone the repository:
git clone https://github.com/dev7a/serverless-otlp-forwarder.git
cd serverless-otlp-forwarder
Build and install the startled binary from its subdirectory:
cargo install --path cli/startled
This will compile the startled crate and place the binary in your Cargo bin directory (e.g., ~/.cargo/bin/startled). Ensure this directory is in your system's PATH.
For enhanced client-side duration measurements that minimize network latency from your local machine, startled supports using a proxy Lambda function deployed in the same AWS region as your target functions.
The easiest way to deploy the proxy function is through the AWS Serverless Application Repository:
Deploy via AWS Console:
Deploy via AWS CLI:
# Create the application
aws serverlessrepo create-cloud-formation-template \
--application-id arn:aws:serverlessrepo:us-east-1:961341555982:applications/startled-proxy \
--semantic-version 0.1.1
# Deploy using the returned template URL
aws cloudformation create-stack \
--stack-name startled-proxy \
--template-url "<TEMPLATE_URL_FROM_PREVIOUS_COMMAND>" \
--capabilities CAPABILITY_IAM \
--parameters ParameterKey=FunctionName,ParameterValue=startled-proxy
Deploy via SAM CLI:
# Create a minimal template file
cat > proxy-template.yaml << 'EOF'
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
StartledProxyApp:
Type: AWS::Serverless::Application
Properties:
ApplicationId: arn:aws:serverlessrepo:us-east-1:961341555982:applications/startled-proxy
SemanticVersion: 0.1.1
Parameters:
FunctionName: startled-proxy
EOF
# Deploy with SAM
sam deploy --template-file proxy-template.yaml --stack-name startled-proxy --capabilities CAPABILITY_IAM
The proxy function includes several security parameters you can configure during deployment:
FunctionName: The name for the proxy function (default: startled-proxy)TargetFunctionResource: Controls which functions the proxy can invoke (default: * for all functions)PrincipalOrgID: Restricts function access to specific AWS Organization members (optional)Once deployed, use the proxy function with startled by specifying the --proxy option:
startled function my-lambda-function \
--memory 512 \
--proxy startled-proxy \
--concurrent 10 \
--number 100
The proxy function provides more accurate client-side duration measurements by eliminating variable internet latency between your local machine and AWS. By executing the timing logic within a proxy Lambda located in the same AWS network as the target function, you get more representative measurements of invocation latency.
startled can generate shell completion scripts for Bash, Elvish, Fish, PowerShell, and Zsh.
This allows you to get command-line suggestions by pressing the Tab key.
To generate a script, use the generate-completions subcommand:
startled generate-completions <SHELL>
Replace <SHELL> with your desired shell (e.g., bash, zsh, fish).
The exact installation method varies by shell. Here are some common examples:
Bash:
bash-completion installed (often available via your system's package manager).mkdir -p ~/.local/share/bash-completion/completions
startled generate-completions bash > ~/.local/share/bash-completion/completions/startled
You may need to restart your shell or source your .bashrc for changes to take effect.Zsh:
~/.zsh/completions).
mkdir -p ~/.zsh/completions
fpath in your .zshrc file before compinit is called:
# In ~/.zshrc
fpath=(~/.zsh/completions $fpath)
# ... (ensure compinit is called after this, e.g., autoload -U compinit && compinit)
startled generate-completions zsh > ~/.zsh/completions/_startled
You may need to restart your shell or run compinit again.Fish:
mkdir -p ~/.config/fish/completions
startled generate-completions fish > ~/.config/fish/completions/startled.fish
Fish should pick up the completions automatically on next launch.Refer to your shell's documentation for the most up-to-date and specific instructions.
The CLI is invoked using the following general syntax:
startled <COMMAND> [OPTIONS]
functionBenchmarks a single, specified Lambda function.
Syntax:
startled function <FUNCTION_NAME> [OPTIONS]
Key Options:
<FUNCTION_NAME>: (Required) The name or ARN of the Lambda function to be benchmarked.--memory <MB> (-m <MB>): (Required) Sets the function's memory allocation to <MB> for the benchmark duration.--concurrent <N> (-c <N>): Specifies the number of concurrent invocations (default: 1).--number <N> (-n <N>): Sets the number of repetitions for warm start measurements. Each round consists of --concurrent invocations (default: 1).--payload <JSON_STRING>: Provides a JSON payload string for each invocation. Conflicts with --payload-file.--payload-file <PATH>: Specifies the path to a JSON file containing the payload. Conflicts with --payload.--env <KEY=VALUE> (-e <KEY=VALUE>): Sets an environment variable for the function during the benchmark. This option can be used multiple times.--proxy <PROXY_FUNCTION_NAME_OR_ARN>: Specifies the name or ARN of a proxy Lambda function for client-side duration measurements.--output-dir <PATH> (-d <PATH>): Base directory where raw JSON benchmark results will be saved. A subdirectory named 'function' will be created within this path, and results will be organized as <PATH>/function/{memory_setting}/{function_name}.json (e.g., if <PATH> is /tmp/results, data is saved under /tmp/results/function/...). If memory is not set, {memory_setting} will be "default".Example:
startled function my-lambda-function \
--memory 512 \
--concurrent 10 \
--number 100 \
--payload '{\"request_id\":\"123\"}' \
--env LOG_LEVEL=info \
--proxy arn:aws:lambda:us-east-1:123456789012:function:my-benchmark-proxy \
--output-dir /tmp/startled_results/my-lambda-function
stackBenchmarks Lambda functions defined within a specified AWS CloudFormation stack.
Syntax:
startled stack <STACK_NAME> --select <PATTERN> [OPTIONS]
Key Options:
<STACK_NAME>: (Required) The name of the deployed CloudFormation stack.--select <PATTERN> (-s <PATTERN>): (Required) A simple string pattern for substring matching against function names or ARNs within the stack. This pattern is also used to name a subdirectory for the results unless --select-name is provided. The pattern must be filesystem-safe if used for directory naming (alphanumeric, underscores, hyphens).--select-regex <REGEX>: (Optional) A regular expression to filter functions within the stack. If provided, this regex is used for filtering instead of the --select <PATTERN>. This option does not affect directory naming.--select-name <NAME>: (Optional) Specifies a custom name for the subdirectory where results for this selection group will be stored. If provided, this name overrides the --select <PATTERN> for directory naming purposes. The name must be filesystem-safe (alphanumeric, underscores, hyphens).--memory <MB> (-m <MB>): (Required) Sets memory for all selected functions to <MB> for the benchmark duration.--concurrent <N> (-c <N>): Number of concurrent invocations (default: 1).--number <N> (-n <N>): Number of warm start repetitions (default: 1).--payload <JSON_STRING> / --payload-file <PATH>: Payload for invocations, applied to all selected functions.--env <KEY=VALUE> (-e <KEY=VALUE>): Environment variables for selected functions.--proxy <PROXY_FUNCTION_NAME_OR_ARN>: Proxy Lambda for client-side measurements.--parallel: (Optional) If specified, benchmarks for all selected functions in the stack are run in parallel. This will suppress detailed console output for individual function benchmarks and show an overall progress bar instead. A summary will be printed upon completion.--output-dir <PATH> (-d <PATH>): (Optional) Base directory for JSON results. If provided, a subdirectory named after --select-name (or --select <PATTERN>) will be created within this base directory to store the results. If this option is not specified, no benchmark results will be saved.Example:
# Benchmark functions in 'my-app-stack' containing "api" in their name/ARN,
# saving results under '/tmp/bench_results/api-group/1024mb/...'
startled stack my-app-stack \
--select "api" \
--select-name "api-group" \
--memory 1024 \
--concurrent 10 \
--number 50 \
--output-dir /tmp/bench_results
# Benchmark functions matching a regex, using the --select pattern for directory naming
startled stack my-data-processing-stack \
--select "processor" \
--select-regex ".*ProcessorFunction$" \
--memory 512 \
--output-dir /data/benchmarks
reportGenerates HTML reports from previously collected JSON benchmark results.
Syntax:
startled report --input-dir <PATH> --output-dir <PATH> [OPTIONS]
Key Options:
--input-dir <PATH> (-d <PATH>): (Required) Directory containing the JSON benchmark result files. startled expects a structure like <input_dir>/{group_name}/{subgroup_name}/*.json (e.g., /tmp/startled_results/my-app/prod/1024mb/*.json).--output-dir <PATH> (-o <PATH>): (Required) Directory where the report files will be generated. An index.{suffix} file and associated assets will be created in this directory. The generated reports include charts for platform metrics, Standard Deviation, and comprehensive memory scaling analysis pages.--title <TITLE>: (Optional) Custom title for the report landing page. If not specified, defaults to "Benchmark Reports".--description <DESCRIPTION>: (Optional) Descriptive text to display below the title on the report landing page. Useful for providing context about the benchmark results.--suffix <SUFFIX>: (Optional) File extension for generated files (default: html). When using custom templates, this allows generating Markdown (.md), plain text (.txt), or any other file format.--screenshot <THEME>: (Optional) Generates high-quality PNG screenshots of all charts with dynamic height detection. <THEME> can be Light or Dark. Features automatic content sizing and theme-appropriate backgrounds. This requires the screenshots compile-time feature and a properly configured headless Chrome environment.--readme <MARKDOWN_FILE>: (Optional) Specifies a markdown file whose content will be rendered as HTML and included on the landing page of the report. This allows for adding custom documentation, explanations, or findings to the benchmark report.--template-dir <PATH>: (Optional) Specifies a custom directory containing templates for report generation. This allows for complete customization of the report appearance and behavior. The directory should contain HTML templates (index.html, chart.html, _sidebar.html), CSS (css/style.css), and a single JavaScript file (js/lib.js) that handles all chart rendering functionality.--base-url <URL_PATH>: (Optional) Specifies a base URL path for all generated links in the report. This is useful when hosting the report in a subdirectory of a website (e.g., --base-url "/reports/" for a site hosted at http://example.com/reports/). When specified, all internal links will be prefixed with this path, ensuring proper navigation even when the report is not hosted at the root of a domain.--local-browsing: (Optional) Appends 'index.html' to all internal links in the report. This makes it easier to navigate the report when opening it directly from the file system, without a web server. By default, links are SEO-friendly and do not include 'index.html'.Example:
# Generate standard HTML reports
startled report \
--input-dir /tmp/startled_results/my-application-services \
--output-dir /var/www/benchmarks/my-application-services \
--title "Lambda Performance Analysis" \
--description "Comprehensive comparison of different OpenTelemetry configurations across Node.js, Python, and Rust runtimes" \
--screenshot dark \
--readme benchmark-notes.md \
--template-dir /path/to/custom-templates \
--base-url "/benchmarks/my-application-services" \
--local-browsing
# Generate Markdown reports with custom templates
startled report \
--input-dir /tmp/startled_results/my-application-services \
--output-dir /tmp/markdown-reports \
--title "Lambda Performance Analysis" \
--suffix md \
--template-dir /path/to/markdown-templates
The main HTML report will be accessible at /var/www/benchmarks/my-application-services/index.html and can be hosted at http://example.com/benchmarks/my-application-services/. The Markdown example would generate index.md files instead.
startled follows a structured process for benchmarking and data collection.
platform.report and platform.runtimeDone records in the logs.--memory or --env options are provided, startled first retrieves the target Lambda function's existing configuration. It then applies the specified temporary changes, saving the original configuration for later restoration.--concurrent value). These initial invocations are considered cold starts.startled executes --number number of warm start batches. Each batch comprises --concurrent invocations to the (now likely initialized) Lambda execution environments.startled attempts to restore the Lambda function to its original logging configuration and memory and environment variable settings.startled gathers metrics from both server-side and client-side perspectives:
Server-Side Metrics (from AWS Lambda Logs): These are obtained by parsing AWS Lambda execution logs (LogType::Tail).
platform.report log entries:
initDurationMs): Initialization time for the function environment. Primarily relevant for cold starts. Displayed in HTML reports as "Cold Start - Init Duration".durationMs): Execution time of the function handler. Displayed in HTML reports as "Cold Start - Server Duration" or "Warm Start - Server Duration".billedDurationMs): The duration used by AWS for billing purposes.memorySizeMB): The memory allocated to the function.maxMemoryUsedMB): The maximum memory utilized during an invocation. Displayed in HTML reports as "Memory Usage".extension spans in platform.report): Performance impact of Lambda Extensions. Displayed in HTML reports as "Cold Start - Extension Overhead" or "Warm Start - Extension Overhead".Init Duration + Server Duration for cold starts): Represents the comprehensive duration for a cold start, combining initialization and execution phases. Displayed in HTML reports as "Cold Start - Total Cold Start Duration".platform.runtimeDone log entries (requires Lambda log level set to DEBUG and log format to JSON):
responseLatencyMs): Time from when the function handler returns to when the Lambda platform completes sending the response. Displayed in HTML reports as "Cold Start - Response Latency" or "Warm Start - Response Latency".responseDurationMs): Time taken to transmit the response bytes. Displayed in HTML reports as "Cold Start - Response Duration" or "Warm Start - Response Duration".runtimeOverheadMs): Lambda runtime overhead after the function handler completes. Displayed in HTML reports as "Cold Start - Runtime Overhead" or "Warm Start - Runtime Overhead".producedBytes): The size of the response payload from the function. Displayed in HTML reports as "Resources - Produced Bytes".durationMs from platform.runtimeDone metrics): The runtime's reported execution duration. Displayed in HTML reports as "Cold Start - Runtime Done Duration" or "Warm Start - Runtime Done Duration".Client-Side Metrics: Measured by startled itself.
--proxy option, this duration is measured from within the same AWS region as the target function, significantly reducing the impact of external network latency. Displayed in HTML reports as "Warm Start - Client Duration".Statistical Summary: For the metrics above (durations, memory, produced bytes), startled calculates and displays:
Trace Context Propagation:
startled automatically injects standard trace context headers (traceparent, tracestate for W3C/OpenTelemetry, and X-Amzn-Trace-Id for AWS X-Ray) into the JSON payload sent to the Lambda function (or its proxy). These headers are added under a headers key within the payload.report command reads all .json result files from the specified --input-dir. It expects a hierarchical directory structure (e.g., group_name/subgroup_name/*.json) to organize the reports effectively.startled calculates:
--readme option, the file is parsed and rendered as HTML to be included on the landing page of the report. This allows for adding custom documentation, explanations of the benchmark setup, or summary of findings.startled uses embedded HTML templates, CSS, and JavaScript files for report generation.--template-dir option, the CLI loads templates from this directory instead, allowing for complete customization of the report appearance and behavior.index.html, chart.html, _sidebar.html), CSS (css/style.css), and a single JavaScript file (js/lib.js) that handles both UI functionality and chart generation./all/summary/): Comprehensive analysis showing how each function performs across different memory configurations with interactive line charts revealing performance trends and cost optimization opportunities.index.html file as a central navigation point for the report, with an enhanced dual-section sidebar (SUMMARY/DETAIL) for intuitive navigation between overview pages and specific metric details./group_name/subgroup_name/chart-type/ with an index.html inside each directory.cold-start-init/ instead of cold_start_init.html).function command: If --output-dir is specified, results are saved under <YOUR_OUTPUT_DIR>/function/{memory_setting}/{function_name}.json (e.g., /tmp/results/function/128mb/my-lambda.json). If --output-dir is omitted, no results are saved.stack command: If --output-dir is specified, results are saved to your_output_dir/{select_name_or_pattern}/{memory_setting}/{function_name}.json (or your_output_dir/{select_name_or_pattern}/default/{function_name}.json if memory is not set). If --output-dir is omitted, no results are saved.report command generates a structured set of HTML files within its specified --output-dir. The input directory for the report command should point to the level containing the {select_name_or_pattern} or {memory_setting} (for function command) directories.
/srv/benchmarks/run1/index.html, with sub-pages such as /srv/benchmarks/run1/api-tests/512mb/cold_start_init.html and memory scaling analysis at /srv/benchmarks/run1/api-tests/all/summary/index.html.benchmark/testbed/ EnvironmentThis repository includes a benchmark/testbed/ directory, which provides a pre-configured environment for use with startled.
This testbed contains:
stdout versions.template.yaml) for deploying all test functions and necessary supporting resources, including a mock OTLP receiver and the proxy function.Makefile designed to orchestrate benchmark execution across different runtimes and memory configurations using the startled CLI.Consult benchmark/testbed/README.md for comprehensive instructions on deploying and utilizing this testbed.
Note: Most users should use the startled-proxy SAR application as documented in the "Proxy Function Setup" section above. This section is primarily for developers who need to implement custom proxy functions.
For developers implementing custom proxy functions, the contract is straightforward: the proxy receives a JSON payload with target (function ARN) and payload (data for the target), invokes the target function while measuring duration, and returns both the invocation_time_ms and the target's response.
The cli/startled/testbed/ directory includes a reference implementation (ProxyFunction in template.yaml) that demonstrates this contract.
For those interested in the internals of startled or contributing:
benchmark/src/main.rs (handles command-line argument parsing using clap).benchmark/src/benchmark.rs.benchmark/src/lambda.rs (function invocation, configuration management, log parsing).benchmark/src/report.rs (HTML templating, chart creation).benchmark/src/stats.rs.benchmark/src/types.rs (defines metrics, configurations, report structures).benchmark/src/templates/ (Tera templates, CSS, JavaScript for ECharts).Build the project using standard Cargo commands from the benchmark/ directory:
cd benchmark/
cargo build
# To run tests:
cargo test