agentsclimarketplace

Aws perf load testing

Skill whitewhiteqq/aws-test-plugin/skills/aws-perf-load-testing

Generate performance benchmarks and load tests for AWS Python services. Performance tests measure Lambda latency, memory usage, cold start time, and batch throughput using pytest-benchmark and tracemalloc. Load tests use Locust to simulate concurrent users against API Gateway endpoints. Reads handler code to build realistic event payloads and endpoint lists. Use when asked to write performance tests, benchmark, profile memory, measure latency, load test, stress test, soak test, or capacity test for any AWS Python project.From its SKILL.md

Install
npx -y skills add whitewhiteqq/aws-test-plugin --skill aws-perf-load-testing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.2 KB, as published. Nobody here has run it

AWS Performance & Load Testing Skill

Generate benchmarks and load tests by reading handler code and API specs.

Performance Tests (pytest-benchmark + tracemalloc)

Phase 1: Build Realistic Events

Read the handler code to understand:

  • What event shape does it expect? (API GW proxy, S3, SQS, direct)
  • What are the hot paths? (most common code branches)
  • What external calls does it make? (need to mock for benchmarks)

Phase 2: Generate Benchmark Tests

See references/benchmark-patterns.md for full patterns.

"""Performance benchmarks for {handler_name}."""
import json
import pytest
from unittest.mock import patch, MagicMock

pytestmark = pytest.mark.performance


@pytest.fixture
def mock_context():
    ctx = MagicMock()
    ctx.function_name = "test-function"
    ctx.memory_limit_in_mb = 256
    ctx.get_remaining_time_in_millis.return_value = 30000
    return ctx


class TestHandlerLatency:
    """Benchmark handler execution time."""

    def test_get_request_latency(self, mock_context, benchmark):
        # Mock external dependencies so we measure handler logic only
        with patch("handler.main.boto3") as mock_boto:
            mock_boto.client.return_value.get_object.return_value = {
                "Body": MagicMock(read=lambda: b'{"data": "value"}')
            }

            from handler.main import lambda_handler
            event = {
                "httpMethod": "GET",
                "pathParameters": {"id": "bench-123"},
                "headers": {"x-api-key": "test"},
            }

            result = benchmark(lambda_handler, event, mock_context)
            assert result["statusCode"] == 200

    def test_post_request_latency(self, mock_context, benchmark):
        with patch("handler.main.boto3") as mock_boto:
            mock_boto.client.return_value.put_item.return_value = {}

            from handler.main import lambda_handler
            event = {
                "httpMethod": "POST",
                "body": json.dumps({"name": "Benchmark"}),
                "headers": {"x-api-key": "test"},
            }

            result = benchmark(lambda_handler, event, mock_context)
            assert result["statusCode"] in (200, 201)


class TestMemoryUsage:
    """Profile handler memory consumption."""

    def test_memory_within_limit(self, mock_context):
        import tracemalloc
        tracemalloc.start()

        with patch("handler.main.boto3"):
            from handler.main import lambda_handler
            event = {"httpMethod": "GET", "pathParameters": {"id": "mem-test"}}
            lambda_handler(event, mock_context)

        current, peak = tracemalloc.get_traced_memory()
        tracemalloc.stop()

        peak_mb = peak / 1024 / 1024
        limit_mb = mock_context.memory_limit_in_mb
        assert peak_mb < limit_mb * 0.8, (
            f"Peak {peak_mb:.1f}MB is >80% of {limit_mb}MB limit"
        )

Performance Thresholds

Suggested starting points — adapt to your service's SLAs and requirements:

MetricLambdaBatchAPI GW E2E
p95 latency< 500msN/A< 3s
p99 latency< 1sN/A< 5s
Error rate< 0.1%0%< 1%
Memory peak< 80% of limit< 2GBN/A
Cold start< 3sN/AN/A

Load Tests (Locust)

Phase 1: Build Endpoint Map

Read the API spec (OpenAPI/Swagger) or discover endpoints from handler routes:

MethodPathWeightCategory
GET/resource/{id}5read
POST/resource1write
POST/resource/search3read

Phase 2: Generate Locust Users

See references/locust-patterns.md for full patterns.

"""Load test for {service_name} API."""
from locust import HttpUser, task, between, tag

class ApiUser(HttpUser):
    wait_time = between(1, 3)

    def on_start(self):
        self.client.headers.update({
            "Content-Type": "application/json",
            # Add auth headers from spec
        })

    @tag("read")
    @task(5)  # weight = 5 (most common)
    def get_resource(self):
        self.client.get(
            "/resource/LOAD-TEST-id",
            name="/resource/{id}",
        )

    @tag("write")
    @task(1)  # weight = 1 (least common)
    def create_resource(self):
        self.client.post(
            "/resource",
            json={"name": "LOAD-TEST-item"},
            name="/resource",
        )

Load Test Commands

# Quick smoke (10 users, 1 minute)
locust -f tests/load/locustfile.py --host=$API_BASE_URL \
  --users=10 --spawn-rate=2 --run-time=1m --headless --csv=tests/reports/smoke

# Standard load (50 users, 5 minutes)
locust -f tests/load/locustfile.py --host=$API_BASE_URL \
  --users=50 --spawn-rate=5 --run-time=5m --headless \
  --csv=tests/reports/load --html=tests/reports/load.html

# Stress (ramp to 200 users, 10 minutes)
locust -f tests/load/locustfile.py --host=$API_BASE_URL \
  --users=200 --spawn-rate=10 --run-time=10m --headless --csv=tests/reports/stress

# Soak (steady 30 users, 1 hour)
locust -f tests/load/locustfile.py --host=$API_BASE_URL \
  --users=30 --spawn-rate=30 --run-time=1h --headless --csv=tests/reports/soak

Load Test Output

Locust generates:

  • *_stats.csv — per-endpoint avg/min/max/p50/p95/p99
  • *_failures.csv — failed request details
  • *_stats_history.csv — time-series data for graphing
  • *.html — interactive dashboard

Safety Constraints

  • Never run load tests against production without explicit confirmation
  • All test data uses LOAD-TEST- prefix
  • Load tests must have --run-time set (no unbounded runs)
  • Monitor CloudWatch during load tests for throttling

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.