Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

LocalStack Administrator & Developer Guide

Generated May 2026 from localstack/localstack at 8b9a79f

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

LocalStack is an AWS cloud service emulator built as a Python application that runs inside a Docker container. It provides a single gateway endpoint (default port 4566) that accepts AWS API requests via any standard SDK, CLI, or IaC tool, routes them to service-specific provider implementations, and returns AWS-compatible responses — all without connecting to real AWS infrastructure.

The system is designed around three core architectural principles: a plugin-based service model that loads services on demand, a gateway with a handler chain pattern for request processing, and a runtime lifecycle with hook points for extensibility.

Architecture Diagram

                    ┌─────────────────────────────────────────┐
                    │           Docker Container              │
                    │                                         │
  AWS SDK/CLI  ─────┤──► Gateway (:4566)                      │
  Terraform         │     │                                   │
  CDK               │     ├── Request Handlers (20+)          │
  Pulumi            │     │   ├── AccountID Extraction        │
                    │     │   ├── Service Router               │
                    │     │   └── Integration Handlers         │
                    │     │                                   │
                    │     ├── Service Plugin Manager           │
                    │     │   ├── S3 Provider                  │
                    │     │   ├── Lambda Provider              │
                    │     │   ├── DynamoDB Provider             │
                    │     │   ├── SQS Provider                 │
                    │     │   └── ... (30+ services)           │
                    │     │                                   │
                    │     ├── Exception Handlers (4)           │
                    │     ├── Response Handlers (8)            │
                    │     └── Finalizers (2)                   │
                    │                                         │
                    │  ┌── DNS Server (:53) ──────────────┐   │
                    │  │   Resolves *.amazonaws.com → GW  │   │
                    │  └──────────────────────────────────┘   │
                    │                                         │
                    │  ┌── Init Scripts ──────────────────┐   │
                    │  │   boot.d → start.d → ready.d     │   │
                    │  │   shutdown.d (on exit)            │   │
                    │  └──────────────────────────────────┘   │
                    │                                         │
                    │  /var/lib/localstack/                    │
                    │    ├── cache/    (downloaded deps)       │
                    │    ├── data/     (persistence snapshots) │
                    │    ├── tmp/      (transient state)       │
                    │    └── logs/     (service logs)          │
                    └─────────────────────────────────────────┘

Component Inventory

Component Path Role
Gateway Server localstack/aws/app.py LocalstackAwsGateway — HTTP entry point, handler chain orchestration
Runtime localstack/runtime/main.py, runtime.py LocalstackRuntime — lifecycle management, startup, shutdown
Service Plugin Manager localstack/services/plugins.py Lazy-loading service providers via plux plugin framework
DNS Server localstack/dns/server.py Built-in DNS for AWS domain resolution
Init Script Manager localstack/runtime/init.py InitScriptManager — discovers and runs lifecycle scripts
Configuration localstack/config.py 153 environment variables, platform detection, directory management
Edge/Service Router localstack/services/edge.py Gateway listener startup, privileged port handling
Extensions API localstack/extensions/api.py Plugin lifecycle hooks for custom extensions
CLI / LPM localstack/cli/lpm.py LocalStack Package Manager CLI commands
Scaffold localstack/aws/scaffold.py ASF API stub generator and upgrader
Health Endpoint localstack/services/edge.py HealthResource — /health and /_localstack/health
Moto Integration localstack/services/moto.py Delegation to moto library for service emulation

Technology Stack

Layer Technology
Language Python 3.10+
Web Server Twisted (default), Hypercorn (alternative)
HTTP Framework Werkzeug/WSGI-based request routing
Plugin System plux (entry-point based plugin discovery)
Service Emulation Moto (community), custom ASF providers
Container Runtime Docker (for Lambda, sub-services)
DNS Custom UDP/TCP DNS protocol implementation
Persistence Snapshot-based serialization to filesystem

Note

The gateway server type is configurable via GATEWAY_SERVER. The default twisted server provides stable HTTP/1.1 handling. The hypercorn alternative supports HTTP/2 but has known stability issues with Lambda creation (GitHub issue #13020) and connection reuse (GitHub issue #13039).

Request Processing Flow

  1. Client sends request to http://localhost:4566 with AWS SigV4 headers
  2. Gateway receives via Twisted/Hypercorn server
  3. Request handler chain processes sequentially:
    • Account ID extraction from access key (AKIA/ASIA/LKIA/LSIA prefix decoding)
    • Service identification from request headers/path
    • Request parsing and validation
    • Route matching to service provider
  4. Service plugin loaded on demand (lazy initialization via plux)
  5. Provider processes request (moto delegation or custom ASF implementation)
  6. Response handler chain transforms the response
  7. Exception handlers catch and format errors as AWS-compatible XML/JSON
  8. Finalizers complete the request lifecycle

2. System Requirements

Minimum Hardware

Resource Minimum Recommended Notes
CPU 2 cores 4+ cores Lambda and parallel service loading benefit from more cores
RAM 2 GB 4-8 GB JVM-based services (OpenSearch, DynamoDB, Kinesis) each add 256 MB-1 GB
Disk 1 GB 10+ GB Persistence, Lambda layers, and cached downloads consume space
Network Localhost only Bridge network Required for inter-container communication

Software Dependencies

Dependency Minimum Version Purpose
Docker 20.10+ Container runtime
Python 3.8+ CLI and runtime
Docker Compose 2.0+ Multi-service deployment (optional)

Platform Support

Platform Status Notes
Linux (x86_64) Full support Primary development platform
Linux (ARM64) Full support Native ARM images available
macOS (Intel) Full support Via Docker Desktop
macOS (Apple Silicon) Full support Via Docker Desktop with Rosetta or native ARM
Windows (WSL2) Full support Docker Desktop with WSL2 backend required
Windows (Hyper-V) Limited Networking issues with DNS server

Important

Platform detection is handled by localstack/config.py which checks in_docker(), is_linux(), is_macos(), is_windows(), and is_wsl(). The WINDOWS_DOCKER_MOUNT_PREFIX variable (default: /host_mnt) handles Windows path translation for Docker volume mounts.


3. Configuration Reference

LocalStack exposes 153 environment variables for configuration. All are set via environment variables — there is no configuration file format. Variables are read at startup from localstack/config.py and localstack/constants.py.

Configuration Loading Order

  1. Defaults defined in config.py
  2. Profile file ~/.localstack/{CONFIG_PROFILE}.env loaded via dotenv
  3. Shell environment variables (highest priority)

Core Configuration

Variable Type Default Description Required
CONFIG_PROFILE string (unset) Name of profile to load from ~/.localstack/ No
CONFIG_DIR string (unset) Override configuration directory path No
RUNTIME_COMPONENTS string (unset) Component plugins to load at startup No
SERVICES string (all) Comma-separated list of services to enable No
MAIN_CONTAINER_NAME string localstack-main Docker container name No
FILESYSTEM_ROOT string (auto) Root filesystem path No

Gateway Configuration

Variable Type Default Description
GATEWAY_LISTEN string 0.0.0.0:4566 Listen address(es), supports IPv4 and IPv6. Multiple addresses separated by commas
GATEWAY_SERVER string twisted Gateway server implementation (twisted or alternatives)
GATEWAY_WORKER_COUNT int 1000 Maximum concurrent worker connections
LOCALSTACK_HOST string (auto) Hostname used in service response URLs

Warning

Setting LOCALSTACK_HOST incorrectly can break internal healthchecks (GitHub issue #13883). The value must be resolvable from within the container. For external access, configure your client's endpoint URL separately.

Persistence & Snapshot Configuration

Variable Type Default Description
PERSISTENCE bool 0 Enable state persistence
DATA_DIR string (unset) Data directory for persistence (setting this also enables persistence)
SNAPSHOT_LOAD_STRATEGY string (unset) on_startup, on_request, manual
SNAPSHOT_SAVE_STRATEGY string (unset) on_request, scheduled, manual
SNAPSHOT_FLUSH_INTERVAL int 15 Seconds between scheduled snapshot flushes
LOCALSTACK_VOLUME_DIR string (unset) Override volume directory path
STATE_SERIALIZATION_BACKEND string (unset) Serialization backend for state persistence

Docker Configuration

Variable Type Default Description
DOCKER_SOCK string (auto) Path to Docker socket
DOCKER_CMD string (auto) Docker command to use
DOCKER_FLAGS string (unset) Additional flags for all Docker commands
DOCKER_BRIDGE_IP string (auto) Docker bridge network IP address
DOCKER_GLOBAL_IMAGE_PREFIX string (unset) Prefix for all Docker image names (for private registries)
DOCKER_SDK_DEFAULT_TIMEOUT_SECONDS int (default) Timeout for Docker SDK operations
DOCKER_SDK_DEFAULT_RETRIES int (default) Retry count for Docker SDK operations
CONTAINER_RUNTIME string (auto) Container runtime (docker/podman)
IMAGE_NAME string (auto) LocalStack Docker image name
PORTS_CHECK_DOCKER_IMAGE string (unset) Image used for port availability checks
MAIN_DOCKER_NETWORK string (unset) Docker network for LocalStack containers

DNS Configuration

Variable Type Default Description
DNS_ADDRESS string (auto) DNS server bind address
DNS_PORT int 53 DNS server port
DNS_SERVER string (unset) Upstream DNS server
DNS_RESOLVE_IP string (unset) IP to resolve AWS domains to
DNS_NAME_PATTERNS_TO_RESOLVE_UPSTREAM string (unset) Patterns for upstream DNS resolution
DNS_LOCAL_NAME_PATTERNS string (unset) Patterns for local DNS resolution
DNS_VERIFICATION_DOMAIN string (unset) Domain for DNS verification

Lambda Configuration

Variable Type Default Description
LAMBDA_KEEPALIVE_MS int 600000 Container keepalive time (ms)
LAMBDA_RUNTIME_EXECUTOR string (default) Execution backend
LAMBDA_DOCKER_NETWORK string (unset) Docker network for Lambda containers
LAMBDA_DOCKER_DNS string (unset) DNS server for Lambda containers
LAMBDA_DOCKER_FLAGS string (unset) Additional Docker flags for Lambda containers
LAMBDA_REMOVE_CONTAINERS string (default) Remove containers after execution
LAMBDA_RUNTIME_IMAGE_MAPPING JSON string (unset) Custom runtime-to-image mapping
LAMBDA_RUNTIME_VALIDATION string (unset) Runtime validation mode
LAMBDA_RUNTIME_ENVIRONMENT_TIMEOUT int (default) Environment initialization timeout
LAMBDA_DEBUG_MODE bool (unset) Enable debugging support
LAMBDA_DEBUG_MODE_CONFIG_PATH string (unset) Path to debug mode configuration file
LAMBDA_JAVA_OPTS string (unset) JVM options for Java Lambda runtimes
LAMBDA_TRUNCATE_STDOUT int (default) Max stdout bytes to capture
LAMBDA_RETRY_BASE_DELAY int (default) Base delay for Lambda retry backoff
HOSTNAME_FROM_LAMBDA string (unset) Hostname Lambdas use to reach LocalStack
BUCKET_MARKER_LOCAL string (unset) S3 bucket marker for local development

Lambda Limits

Variable Type Default Description
LAMBDA_LIMITS_CONCURRENT_EXECUTIONS int 1000 Max concurrent executions
LAMBDA_LIMITS_MINIMUM_UNRESERVED_CONCURRENCY int 100 Minimum unreserved concurrency
LAMBDA_LIMITS_TOTAL_CODE_SIZE int 80530636800 Total code storage limit (bytes)
LAMBDA_LIMITS_CODE_SIZE_ZIPPED int 52428800 Max zipped code size (50 MB)
LAMBDA_LIMITS_CODE_SIZE_UNZIPPED int 262144000 Max unzipped code size (250 MB)
LAMBDA_LIMITS_CREATE_FUNCTION_REQUEST_SIZE int 70167211 Max create-function request size
LAMBDA_LIMITS_MAX_FUNCTION_ENVVAR_SIZE_BYTES int (AWS default) Max environment variable size
LAMBDA_LIMITS_MAX_FUNCTION_PAYLOAD_SIZE_BYTES int (AWS default) Max invocation payload size

Lambda Init Binary Configuration

Variable Type Default Description
LAMBDA_INIT_RELEASE_VERSION string (unset) Lambda init binary version
LAMBDA_INIT_BIN_PATH string (unset) Path to Lambda init binary
LAMBDA_INIT_BOOTSTRAP_PATH string (unset) Path to Lambda bootstrap script
LAMBDA_INIT_DELVE_PATH string (unset) Path to Delve debugger binary
LAMBDA_INIT_DELVE_PORT int (unset) Delve debugger port
LAMBDA_INIT_POST_INVOKE_WAIT_MS int (unset) Post-invocation wait time (ms)
LAMBDA_INIT_USER string (unset) User for Lambda init process

Lambda Event Source Mapping

Variable Type Default Description
LAMBDA_EVENT_SOURCE_MAPPING_POLL_INTERVAL_SEC int (default) Polling interval for event source mappings
LAMBDA_EVENT_SOURCE_MAPPING_MAX_BACKOFF_ON_ERROR_SEC int (default) Max backoff after error
LAMBDA_EVENT_SOURCE_MAPPING_MAX_BACKOFF_ON_EMPTY_POLL_SEC int (default) Max backoff on empty poll

DynamoDB Configuration

Variable Type Default Description
DYNAMODB_SHARE_DB bool (unset) Share single DB across all tables
DYNAMODB_LOCAL_PORT int (unset) Custom DynamoDB Local port
DYNAMODB_HEAP_SIZE string (unset) JVM heap size for DynamoDB Local
DYNAMODB_ERROR_PROBABILITY float (unset) Probability of random errors (0.0-1.0)
DYNAMODB_READ_ERROR_PROBABILITY float (unset) Probability of read errors
DYNAMODB_WRITE_ERROR_PROBABILITY float (unset) Probability of write errors

Tip

Error probability settings are useful for chaos testing. Set DYNAMODB_ERROR_PROBABILITY=0.05 to simulate a 5% failure rate in development environments.

Kinesis Configuration

Variable Type Default Description
KINESIS_SHARD_LIMIT int (AWS default) Maximum shards per stream
KINESIS_ON_DEMAND_STREAM_COUNT_LIMIT int (AWS default) Max on-demand streams
KINESIS_LATENCY int (unset) Simulated put latency (ms)
KINESIS_MOCK_PERSIST_INTERVAL int (unset) Persistence interval (ms)
KINESIS_MOCK_LOG_LEVEL string (unset) Mock engine log level
KINESIS_MOCK_PROVIDER_ENGINE string (default) Mock provider engine
KINESIS_MOCK_MAXIMUM_HEAP_SIZE string (unset) JVM max heap for Kinesis mock
KINESIS_MOCK_INITIAL_HEAP_SIZE string (unset) JVM initial heap for Kinesis mock
KINESIS_ERROR_PROBABILITY float (unset) Random error probability

CORS Configuration

Variable Type Default Description
DISABLE_CORS_HEADERS bool (unset) Disable CORS headers entirely
DISABLE_CORS_CHECKS bool (unset) Disable CORS validation
EXTRA_CORS_ALLOWED_HEADERS string (unset) Additional allowed CORS headers
EXTRA_CORS_EXPOSE_HEADERS string (unset) Additional exposed CORS headers
EXTRA_CORS_ALLOWED_ORIGINS string (unset) Additional allowed CORS origins

Network & Proxy Configuration

Variable Type Default Description
OUTBOUND_HTTP_PROXY string (unset) HTTP proxy for outbound requests
OUTBOUND_HTTPS_PROXY string (unset) HTTPS proxy for outbound requests
NO_PROXY / no_proxy string (unset) Addresses that bypass proxy
CUSTOM_SSL_CERT_PATH string (unset) Path to custom SSL certificate
REQUESTS_CA_BUNDLE string (unset) CA bundle for outbound HTTPS
SKIP_INFRA_DOWNLOADS bool (unset) Skip runtime dependency downloads
EXTERNAL_SERVICE_PORTS_START int (default) Start of external service port range
EXTERNAL_SERVICE_PORTS_END int (default) End of external service port range
SERVICE_INSTANCES_PORTS_START int (default) Start of service instance port range
SERVICE_INSTANCES_PORTS_END int (default) End of service instance port range

Logging & Debug Configuration

Variable Type Default Description
DEBUG bool 0 Enable debug mode
LS_LOG string (unset) Log level override (trace, debug, info, warning, error)
LOG_LEVEL_OVERRIDES string (unset) Per-module log level overrides
DEVELOP bool (unset) Enable development mode
DEVELOP_PORT int (unset) Remote debugger port for development

Note

LOG_LEVEL_OVERRIDES accepts a JSON string mapping logger names to levels, e.g., {"botocore":"WARNING","urllib3":"WARNING"}. This reduces log noise from verbose libraries.

Service-Specific Configuration

Variable Type Default Description
SQS_ENDPOINT_STRATEGY string (default) SQS URL generation strategy
SQS_CLOUDWATCH_METRICS_REPORT_INTERVAL int (unset) CloudWatch metrics reporting interval
OPENSEARCH_CUSTOM_BACKEND string (unset) Custom OpenSearch backend URL
OPENSEARCH_ENDPOINT_STRATEGY string (default) OpenSearch endpoint strategy
SFN_MOCK_CONFIG string (unset) Step Functions mock configuration file path
SNS_SES_SENDER_ADDRESS string (unset) SES sender address for SNS email notifications
SNS_CERT_URL_HOST string (unset) SNS certificate URL host
CFN_PER_RESOURCE_TIMEOUT int (default) CloudFormation per-resource timeout (seconds)
CFN_NO_WAIT_ITERATIONS int (unset) CloudFormation polling iterations
CFN_STRING_REPLACEMENT_DENY_LIST string (unset) Strings to exclude from CFN template replacements
BOTO_WAITER_DELAY int (default) Boto3 waiter polling delay
BOTO_WAITER_MAX_ATTEMPTS int (default) Boto3 waiter max attempts
INTERNAL_RESOURCE_ACCOUNT string (unset) Internal resource account ID

Provider Override Configuration

Variable Type Description
PROVIDER_OVERRIDE_APIGATEWAY string Override API Gateway provider implementation
PROVIDER_OVERRIDE_DYNAMODB string Override DynamoDB provider
PROVIDER_OVERRIDE_DYNAMODBSTREAMS string Override DynamoDB Streams provider
PROVIDER_OVERRIDE_SNS string Override SNS provider
PROVIDER_OVERRIDE_EVENTS string Override EventBridge provider (deprecated)

Build & Version Information

Variable Type Description
LOCALSTACK_BUILD_GIT_HASH string Git hash of the build
LOCALSTACK_BUILD_DATE string Build date
LOCALSTACK_BUILD_VERSION string Build version string
LOCALSTACK_AUTH_TOKEN string Pro authentication token
LOCALSTACK_API_KEY string Legacy API key (deprecated)

Annotated Production Configuration

# Production-grade Docker Compose for CI/CD
docker run --rm -d \
  --name localstack-ci \
  -p 4566:4566 \
  -p 4510-4559:4510-4559 \
  -e SERVICES=s3,sqs,sns,lambda,dynamodb,cloudformation,iam \
  -e GATEWAY_SERVER=twisted \
  -e GATEWAY_WORKER_COUNT=1000 \
  -e LAMBDA_KEEPALIVE_MS=300000 \
  -e LAMBDA_DOCKER_NETWORK=ci-network \
  -e LAMBDA_REMOVE_CONTAINERS=1 \
  -e PERSISTENCE=0 \
  -e DNS_ADDRESS=0.0.0.0 \
  -e SKIP_INFRA_DOWNLOADS=0 \
  -e DEBUG=0 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ./init:/etc/localstack/init \
  localstack/localstack

4. Deployment & Scaling

Docker Deployment

Standalone Container

docker run --rm -d \
  --name localstack \
  -p 4566:4566 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ./data:/var/lib/localstack \
  localstack/localstack

Docker Compose

version: "3.8"
services:
  localstack:
    image: localstack/localstack
    container_name: localstack
    ports:
      - "4566:4566"
      - "4510-4559:4510-4559"
    environment:
      SERVICES: s3,sqs,sns,lambda,dynamodb
      GATEWAY_WORKER_COUNT: 1000
      LAMBDA_DOCKER_NETWORK: ${COMPOSE_PROJECT_NAME}_default
      PERSISTENCE: 1
    volumes:
      - localstack-data:/var/lib/localstack
      - /var/run/docker.sock:/var/run/docker.sock
      - ./init:/etc/localstack/init
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:4566/_localstack/health"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  localstack-data:

Tip

Set LAMBDA_DOCKER_NETWORK to ${COMPOSE_PROJECT_NAME}_default so Lambda containers automatically join the compose network and can reach other services.

Kubernetes Deployment

LocalStack includes development tooling for Kubernetes via k3d and Helm:

# Development setup (from localstack/dev/kubernetes/)
python -m localstack.dev.kubernetes

Warning

The Kubernetes tooling in this repository is for development and testing of LocalStack itself, not for deploying LocalStack as a service in Kubernetes. For production K8s deployment, use the official Helm chart.

CI/CD Integration

GitHub Actions

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      localstack:
        image: localstack/localstack
        ports:
          - 4566:4566
        env:
          SERVICES: s3,sqs,lambda,dynamodb
    steps:
      - uses: actions/checkout@v4
      - run: |
          pip install awscli-local
          awslocal s3 mb s3://test-bucket
          # Run your tests

GitLab CI

test:
  services:
    - name: localstack/localstack
      alias: localstack
  variables:
    AWS_ENDPOINT_URL: http://localstack:4566
  script:
    - pip install awscli-local
    - awslocal s3 mb s3://test-bucket

Volume Mount Architecture

LocalStack uses a standardized directory structure inside the container:

Directory Purpose Persistence
/usr/lib/localstack Static libraries (installed packages) Ephemeral
/var/lib/localstack/cache Downloaded runtime dependencies Can be persisted
/var/lib/localstack/data State snapshots Persist for data retention
/var/lib/localstack/tmp Temporary files Ephemeral
/var/lib/localstack/logs Service logs Ephemeral
/etc/localstack/init Init hook scripts Bind-mount from host

The Directories class in config.py manages these paths with properties: static_libs, var_libs, cache, tmp, mounted_tmp, functions, data, config, init, logs.


5. Operations

Health Monitoring

The health endpoint provides service status:

# Basic health check
curl http://localhost:4566/_localstack/health

# Also available at legacy path
curl http://localhost:4566/health
{
  "services": {
    "s3": "available",
    "sqs": "available",
    "lambda": "running",
    "dynamodb": "available"
  },
  "features": {}
}

Service states:

State Meaning
available Service is loaded and ready
running Service is actively processing
disabled Service is explicitly disabled
(absent) Service not yet loaded (lazy loading)

Note

The health endpoint supports POST requests with action field for service control: restart to restart a service, kill to stop one.

Service Management via Health Endpoint

# Restart a specific service
curl -X POST http://localhost:4566/health \
  -H "Content-Type: application/json" \
  -d '{"action": "restart", "services": ["s3"]}'

# Kill a service
curl -X POST http://localhost:4566/health \
  -H "Content-Type: application/json" \
  -d '{"action": "kill", "services": ["lambda"]}'

Container Lifecycle Management

# Start in background
localstack start -d

# Check status
localstack status

# View logs
docker logs -f localstack-main

# Stop gracefully
localstack stop

# Force stop
docker rm -f localstack-main

Init Hook Lifecycle

Init hooks execute at specific points in the LocalStack lifecycle:

Directory When Use Case
boot.d/ Before services start System configuration, environment setup
start.d/ During service initialization Early resource creation
ready.d/ After all services are ready Resource provisioning, test data
shutdown.d/ On container shutdown Cleanup, state export

Scripts are discovered by InitScriptManager and executed by ShellScriptRunner (.sh) or PythonScriptRunner (.py).

Important

Init scripts that exit with a non-zero code raise an OSError with the message Script {path} returned a non-zero exit code {exit_code}. This does not halt LocalStack startup but is logged as an error.

Snapshot Operations

# Manual snapshot save (via internal API)
curl -X POST http://localhost:4566/_localstack/state/save

# Manual snapshot load
curl -X POST http://localhost:4566/_localstack/state/load

# Reset all state
curl -X POST http://localhost:4566/_localstack/state/reset

Log Management

Configure logging granularity:

# Global log level
LS_LOG=debug

# Per-module overrides (JSON string)
LOG_LEVEL_OVERRIDES='{"botocore":"WARNING","urllib3":"WARNING","docker":"INFO"}'

Tip

In production CI runs, set LS_LOG=warning and selectively enable debug for specific modules via LOG_LEVEL_OVERRIDES to reduce log volume while retaining diagnostic capability.


6. Performance

Gateway Server Tuning

Parameter Default Tuning Guidance
GATEWAY_SERVER twisted Use twisted for stability; alternatives may offer HTTP/2 but with stability tradeoffs
GATEWAY_WORKER_COUNT 1000 Increase for high-concurrency test suites; decrease on memory-constrained runners

Lambda Performance

Parameter Impact Recommendation
LAMBDA_KEEPALIVE_MS 600000 (10 min) Increase for test suites with frequent same-function invocations; decrease for memory-constrained environments
LAMBDA_REMOVE_CONTAINERS Default Set to 1 in CI to prevent container accumulation
LAMBDA_DOCKER_NETWORK Network routing Use host network for lowest latency

JVM Service Tuning

Services backed by JVM processes (DynamoDB Local, Kinesis mock, OpenSearch) accept heap configuration:

# DynamoDB
DYNAMODB_HEAP_SIZE=512m

# Kinesis
KINESIS_MOCK_INITIAL_HEAP_SIZE=256m
KINESIS_MOCK_MAXIMUM_HEAP_SIZE=512m

Note

Each JVM-backed service starts a separate Java process. On a 4 GB container, running DynamoDB + Kinesis + OpenSearch simultaneously can consume 1.5-2 GB of heap alone. Size your container accordingly.

Service Loading Strategy

LocalStack uses lazy loading: services initialize on first API request, not at startup. This means:

  • First request to a service incurs initialization latency (1-10 seconds depending on service)
  • Subsequent requests are fast
  • Use init hooks in ready.d/ to pre-warm services by making initial API calls

Port Range Management

The PortRange class manages dynamic port allocation for sub-services:

  • EXTERNAL_SERVICE_PORTS_START / EXTERNAL_SERVICE_PORTS_END: External-facing ports (default: 4510-4559)
  • SERVICE_INSTANCES_PORTS_START / SERVICE_INSTANCES_PORTS_END: Internal service instance ports

If you see PortNotAvailableException, expand the port range or reduce concurrent service instances.


7. Security

Authentication Model

LocalStack accepts any AWS credentials by default. There is no authentication enforcement in the Community Edition. The access key ID is used for account identification (multi-account isolation), not for access control.

Access key prefixes determine account routing:

Prefix Source
AKIA Standard IAM access key
ASIA STS temporary credentials
LKIA LocalStack-specific permanent key
LSIA LocalStack-specific temporary key

Caution

LocalStack does not enforce IAM policies by default in the Community Edition. Do not rely on LocalStack for security testing of IAM permissions. Production IAM policy validation requires testing against real AWS.

Network Security

  • Default bind: 0.0.0.0:4566 — accessible from all network interfaces
  • DNS server: Binds to port 53 (privileged port, requires root or capabilities)
  • Docker socket: Required for Lambda — grants full Docker API access
  • Inter-container traffic: Lambda containers communicate via Docker networking

Hardening recommendations:

  1. Bind to localhost only: GATEWAY_LISTEN=127.0.0.1:4566
  2. Use Docker user namespaces to limit socket access
  3. Run in an isolated Docker network: --network isolated-net
  4. Never expose LocalStack to the public internet

SSL/TLS

Custom SSL certificates can be provided via CUSTOM_SSL_CERT_PATH. The CA bundle for outbound HTTPS requests is configurable via REQUESTS_CA_BUNDLE.

Privileged Port Handling

When GATEWAY_LISTEN specifies a port below 1024, LocalStack attempts to start a TCP proxy via sudo. If running in a non-TTY environment, this fails with cannot get sudo password from non-tty input. Solutions:

  • Use ports above 1024 (default 4566)
  • Run the container as root
  • Use --cap-add NET_BIND_SERVICE

Secrets in Environment

No sensitive secrets are required for the Community Edition. Pro features require:

  • LOCALSTACK_AUTH_TOKEN — authentication token for Pro services
  • LOCALSTACK_API_KEY — legacy API key (deprecated)
  • GITHUB_API_TOKEN — optional, for higher GitHub API rate limits

Warning

Never expose LOCALSTACK_AUTH_TOKEN in public CI logs. Use secret variables in your CI/CD system.


8. Developer Internals

Repository Structure

localstack-core/localstack/
├── aws/
│   ├── app.py              # LocalstackAwsGateway — main entry point
│   ├── scaffold.py         # ASF API stub generator
│   ├── client.py           # Internal AWS client
│   ├── connect.py          # AWS connection management
│   ├── mocking.py          # Response shape generation
│   └── handlers/           # Gateway request/response handlers
│       └── service_plugin.py  # Service lazy-loading handler
├── cli/
│   └── lpm.py              # LocalStack Package Manager CLI
├── config.py               # All 153 config variables
├── constants.py            # Constants (API_ENDPOINT, etc.)
├── deprecations.py         # Deprecation warnings
├── dns/
│   └── server.py           # Built-in DNS server
├── extensions/
│   └── api.py              # Extension lifecycle API
├── logging/
│   └── setup.py            # Logging configuration
├── runtime/
│   ├── main.py             # Runtime entry point
│   ├── runtime.py          # LocalstackRuntime class
│   ├── init.py             # InitScriptManager
│   ├── components.py       # Gateway server factory
│   ├── current.py          # Runtime singleton
│   └── legacy.py           # Legacy supervisor support
├── services/
│   ├── edge.py             # Gateway listener, HealthResource
│   ├── plugins.py          # Service plugin manager
│   ├── stores.py           # Multi-account/region store
│   ├── moto.py             # Moto integration layer
│   └── apigateway/         # API Gateway provider (example)
│       └── next_gen/
│           └── execute_api/
│               └── handlers/  # Request/response handlers
└── utils/
    ├── archives.py         # Archive download/extraction
    ├── batching.py         # Batcher/AsyncBatcher
    ├── bootstrap.py        # Container bootstrap utilities
    ├── checksum.py         # Download checksum verification
    ├── collections.py      # Dict navigation utilities
    ├── container_networking.py  # Container network resolution
    ├── diagnose.py         # Diagnostic information
    ├── docker_utils.py     # Docker volume/mount utilities
    ├── files.py            # File system utilities
    ├── functions.py        # Function utilities (recursion guard)
    ├── http.py             # HTTP download utilities
    ├── iputils.py          # IP address utilities
    ├── net.py              # Port management (PortRange)
    ├── objects.py          # Object utilities
    ├── patch.py            # Monkey-patching framework
    ├── platform.py         # OS detection
    ├── scheduler.py        # Task scheduling (Deadline)
    ├── serving.py          # Server lifecycle management
    ├── testutil.py         # Test utilities
    ├── time.py             # Timestamp parsing
    └── venv.py             # Virtual environment management

Architecture Deep Dive

Gateway Handler Chain

The LocalstackAwsGateway in aws/app.py orchestrates request processing through a chain of handlers:

Request Handlers (20+):

  • Account ID extraction from SigV4 headers
  • Service identification and routing
  • Request parsing and validation
  • API key validation (for API Gateway)
  • Integration request transformation

Exception Handlers (4):

  • AWS error response formatting
  • Internal server error handling
  • Unsupported media type errors
  • Authentication errors

Response Handlers (8):

  • CORS header injection
  • Response transformation
  • Content type negotiation

Finalizers (2):

  • Metrics collection
  • Connection cleanup

Service Plugin System

Services are loaded via the plux plugin framework using Python entry points. The ServicePluginManager in services/plugins.py handles:

  1. Discovery: Scans entry points in the localstack.services namespace
  2. Lazy loading: Services initialize only on first API request
  3. State tracking: Services transition through states: disabled → starting → available → running → stopping
  4. Error handling: Failed services raise ServiceStateException
# Service lifecycle
ServiceDisabled → ServiceStarting → ServiceAvailable → ServiceRunning
                                                     → ServiceStopping

Multi-Account/Region Store

The stores.py module provides AccountRegionBundle for service state isolation:

  • Each service maintains state per (account_id, region) tuple
  • Account IDs validated as 12-digit strings
  • Region names validated against known AWS regions
  • Cross-account and cross-region attributes supported via CrossAccountAttribute and CrossRegionAttribute

Moto Integration

Many services delegate to the moto library via services/moto.py:

  • Request routing maps to moto backends
  • CommonServiceException wraps moto errors as AWS-compatible responses
  • Custom providers can override moto behavior per service

Code Patterns & Conventions

Monkey-Patching Framework

utils/patch.py provides a structured patching system:

from localstack.utils.patch import patch

@patch(target=SomeClass.some_method)
def custom_behavior(fn, self, *args, **kwargs):
    # pre-processing
    result = fn(self, *args, **kwargs)
    # post-processing
    return result

Restrictions: cannot patch classes implementing __getattr__.

Batcher Utilities

utils/batching.py provides Batcher and AsyncBatcher for collecting items and processing in batches. Raises ValueError if items are added after the batcher is stopped.

Safe Dict Navigation

utils/collections.py provides safe navigation into nested dicts using JSON Path-like syntax ($.key.subkey). Root node must start with $.

Port Management

utils/net.py provides PortRange for managing dynamic port allocation with reservation tracking. Raises PortNotAvailableException when no ports are available.

Testing Strategy

The codebase uses a comprehensive testing framework:

Test Types

Type Location Purpose
Unit tests tests/unit/ Isolated component testing
Integration tests tests/aws/ Full AWS API emulation testing
Parity tests tests/aws/ (snapshot) Compare LocalStack vs real AWS responses

Testing Rules (from CONTRIBUTING.md)

  1. R01: Tests must be reproducible and deterministic
  2. R02: Each test must clean up after itself
  3. R03: Tests should not depend on execution order
  4. R04: Use pytest fixtures for resource setup
  5. R05-R14: Additional rules covering naming conventions, assertions, timeouts, and resource management

Parity/Snapshot Testing

The parity testing framework captures responses from both LocalStack and real AWS, then compares them via snapshot files. This ensures behavioral compatibility:

@markers.aws.validated
def test_s3_put_get(self, aws_client, s3_bucket):
    aws_client.s3.put_object(Bucket=s3_bucket, Key="test", Body=b"data")
    result = aws_client.s3.get_object(Bucket=s3_bucket, Key="test")
    snapshot.match("get_object", result)

Running Tests

# Unit tests
pytest tests/unit/

# Integration tests (requires running LocalStack)
pytest tests/aws/services/s3/

# With verbose output
pytest -v tests/unit/utils/

Extension API

The extensions system in extensions/api.py provides lifecycle hooks for custom plugins:

from localstack.extensions.api import Extension

class MyExtension(Extension):
    name = "my-extension"

    def on_extension_load(self):
        """Called when the extension is loaded."""
        pass

    def on_platform_start(self):
        """Called when LocalStack platform starts."""
        pass

    def update_gateway_routes(self, router):
        """Add custom routes to the gateway."""
        pass

    def update_request_handlers(self, handlers):
        """Add custom request handlers."""
        pass

    def update_response_handlers(self, handlers):
        """Add custom response handlers."""
        pass

    def on_platform_ready(self):
        """Called when all services are ready."""
        pass

    def on_platform_shutdown(self):
        """Called on shutdown."""
        pass

Scaffold Tool

The scaffold tool generates AWS Service Framework (ASF) API stubs from AWS service models:

# Generate stubs for a new service
localstack scaffold generate ec2 --doc --save --path ./localstack-core/localstack/aws/api

# Upgrade existing stubs to match latest service model
localstack scaffold upgrade --doc --path ./localstack-core/localstack/aws/api
Flag Default Description
--doc/--no-doc --no-doc Generate docstrings from service model
--save/--print --print Save to disk or print to stdout
--path ./localstack-core/localstack/aws/api Output directory

Key Classes Reference

Class Module Purpose
LocalstackRuntime runtime/runtime.py Main runtime lifecycle (run, shutdown, exit, is_ready)
LocalstackAwsGateway aws/app.py Gateway with handler chain
InitScriptManager runtime/init.py Init hook discovery and execution
ShellScriptRunner runtime/init.py Executes .sh init scripts
PythonScriptRunner runtime/init.py Executes .py init scripts
ShutdownHandlers runtime/runtime.py Priority-based shutdown handler registry
Directories config.py 10 directory path properties
HostAndPort config.py IPv4/IPv6 address parsing
UniqueHostAndPortList config.py Deduplicating listen address list
ServiceProviderConfig services/plugins.py Service provider configuration
DnsServerProtocol dns/server.py DNS record management (add_host, delete_host, add_alias)
RecordType dns/server.py DNS record types (A, AAAA, CNAME, TXT, MX, SOA, NS, SRV)
PortRange utils/net.py Dynamic port allocation with reservation
Batcher / AsyncBatcher utils/batching.py Batch processing utilities
Extension extensions/api.py Plugin lifecycle interface
Container / RunningContainer utils/bootstrap.py Docker container management
LocalstackContainerServer utils/bootstrap.py Container server wrapper
HealthResource services/edge.py Health endpoint handler

Contributing

From CONTRIBUTING.md:

  • Pull requests: Fork, create feature branch, submit PR against main
  • Coding style: Follow existing patterns; use black for formatting
  • CLA: Contributors must sign the Contributor License Agreement
  • Tests: All changes must include appropriate test coverage
  • Documentation: Update relevant docs for user-facing changes

9. Integration Points

AWS SDK Integration

Any AWS SDK can be configured to use LocalStack by setting the endpoint URL:

SDK Configuration Method
Python (boto3) endpoint_url="http://localhost:4566"
JavaScript (v3) endpoint: "http://localhost:4566"
Java .endpointOverride(URI.create("http://localhost:4566"))
Go EndpointResolver configuration
.NET ServiceURL = "http://localhost:4566"
Rust endpoint_url("http://localhost:4566")

IaC Tool Integration

Tool Integration Method
Terraform tflocal wrapper or manual provider endpoints
CDK cdklocal wrapper
Pulumi AWS provider endpoint configuration
CloudFormation Direct via awslocal cloudformation
Serverless Framework serverless-localstack plugin
SAM CLI --endpoint-url flag

Docker Integration

LocalStack interacts with Docker in multiple ways:

  • Docker socket: Required for Lambda container management
  • Docker networks: Configurable for inter-container communication
  • Docker images: Custom images via LAMBDA_RUNTIME_IMAGE_MAPPING
  • Docker flags: Passthrough via DOCKER_FLAGS and LAMBDA_DOCKER_FLAGS

DNS Integration

The built-in DNS server supports:

Record Type Support
A Full
AAAA Full
CNAME Full
TXT Full
MX Full
SOA Full
NS Full
SRV Full

Operations available via DnsServerProtocol:

  • add_host(name, ip) — Add A/AAAA record
  • delete_host(name) — Remove record
  • add_host_pointing_to_localstack(name) — Add record pointing to LocalStack gateway
  • add_alias(source, target) — Add CNAME alias
  • add_skip(name) — Skip resolution for name
  • clear() — Remove all records

The DNS server starts at priority 20 (before Pro activation) and shuts down at priority -30 (after all services).

Runtime Hooks

Hook When Use Case
on_runtime_create Runtime object created Early initialization
on_infra_start Infrastructure starting Pre-service setup
on_infra_ready All services ready Integration triggers
on_infra_shutdown Shutdown initiated Cleanup

Analytics & Telemetry

LocalStack tracks environment variable presence for analytics:

  • TRACKED_ENV_VAR: 60+ variables whose values are reported
  • PRESENCE_ENV_VAR: 25+ variables where only presence/absence is reported

This data helps the LocalStack team understand feature usage. No service data or request content is transmitted.

Known Compatibility Issues

Issue Service Description Workaround
#13858 Cognito MFA challenge not issued for SOFTWARE_TOKEN_MFA Skip MFA in local testing
#13899 S3 Healthcheck broken in S3-only image Use full localstack/localstack image
#13580 CDK Bootstrap fails on free tier Wait for full initialization
#13882 Route53 DNS stops after pod state load Restart LocalStack
#13883 Core LOCALSTACK_HOST breaks healthcheck Leave unset unless needed
#13886 KMS ECC_NIST_EDWARDS25519 validation error Use RSA or standard ECC
#13898 EventBridge Binary type serialization failure in Pipes Use string-encoded binary
#13867 ECR list-images throws ImageNotFoundException Use describe-images
#13585 DynamoDB Composite key limitations Use simple key schemas
#13488 EC2/Terraform Burstable instance regression Update LocalStack
#13039 Core HTTP/2 protocol errors Use GATEWAY_SERVER=twisted
#13020 Lambda Hypercorn 500 errors on creation Use GATEWAY_SERVER=twisted
#13138 Kinesis Mock engine returns latest record only Switch to kinesalite engine
#13157 CloudFront Routing fails with IP/URL access Use localhost