Docs / Known Limitations

Known Limitations

We believe transparency builds trust. Here is what LocalEmu does not emulate, and why.

Our philosophy

Every emulator has limits. Rather than hiding them, we document them. This page is updated as we improve coverage. If something matters to you that's listed here, open an issue, it helps us prioritize.

Recently resolved

The following issues were fixed in the latest campaign and are no longer limitations.

CloudTrail: 60/60 APIs working

CloudTrail coverage is complete (53 custom, 7 moto-backed, 0 not implemented). CloudTrail-to-EventBridge event forwarding is implemented. SNS log-delivery subscriptions work. EventDataStore SQL query execution remains stubbed (see below).

DynamoDB: FilterExpression on key attributes

Previously accepted silently. Now correctly rejected with the same ValidationException that real AWS returns when a FilterExpression references a key attribute.

EventBridge: DeleteEventBus / DeleteRule crash

Deleting event buses or rules no longer causes a server crash. Both operations now succeed cleanly.

CloudWatch: PutMetricData self-healing

The SQLite database backing CloudWatch metrics now self-heals on corruption, preventing 500 errors on PutMetricData.

API Gateway V2: Lambda ARN extraction

Lambda ARN extraction from API Gateway V2 integration URIs now works correctly, enabling HTTP API integrations with Lambda functions.

Still limited

S3 moto bridge: bucket-existence only

The systemic S3 moto bridge verifies bucket existence for cross-service calls, but does not provide byte-level object access. Services like Firehose, CloudWatch Logs, and Athena that need to write or read S3 object bytes still cannot do so through the bridge.

CloudTrail Lake: metadata-only query engine

EventDataStore lifecycle APIs (Create/Describe/List/Update/Delete, ingestion status, termination protection, advanced event selectors) work. Event ingestion into the Lake store and SQL query execution are not implemented, queries return structural metadata only.

Networking

VPC networking: real with Docker backend

With EC2_VM_MANAGER=docker, each VPC is a real Docker network providing IP-level isolation. Transit Gateway attachments, VPC peering (with two-way NAT), route tables, and security groups all work end-to-end, see the Transit Gateway + VPC Peering tutorial. Without the Docker backend, VPC resources are metadata-only.

No real DNS resolution

Route53 hosted zones and records are stored but don't resolve DNS queries.

No CloudFront

Distributions are created as metadata but don't cache or distribute content.

No real ELB

Load balancers exist as metadata but don't route traffic. ECS containers are accessible directly via port mappings.

NAT Gateway & Internet Gateway: Docker-backed

Private subnets reach the internet through a NAT-Gateway alpine bridge container; IGW-attached VPCs get an unrestricted Docker network for outbound. Egress-Only Internet Gateways (IPv6) and VPC Endpoints over PrivateLink remain CRUD-only.

Storage

S3: no real lifecycle policy execution

Policies are stored but objects aren't transitioned or expired automatically.

S3: no cross-region replication

Replication configurations are accepted but data is not replicated across regions.

S3: no S3 Select with full SQL

Basic support exists but full SQL query capabilities are not implemented.

EBS: volumes exist as metadata

Volumes are not real block storage. They are tracked as API objects only.

EFS: file systems are CRUD-only

No NFS mount support.

Compute

Lambda: no real microVM isolation

Lambda functions run in Docker containers, not real microVMs.

Lambda: Provisioned Concurrency is partial

Basic lifecycle is supported and the flag is respected to skip cold-start simulation. Allocation-status transitions, the "allocated" intermediate state, and cross-version/alias routing are limited. Actual warm-pool pre-provisioning is not implemented.

Lambda: layers work but extensions do not

Lambda layers are extracted and mounted correctly. Lambda extensions are not executed.

ECS: both launch types supported, with caveats

RunTask with launchType=FARGATE and EC2 both run real Docker containers via the on-by-default Docker backend (ECS_DOCKER_BACKEND=0 disables). Fargate-only features (platform versions, ephemeral storage sizing, FireLens log driver) are recorded in moto but not emulated by the Docker driver.

EC2: instances are Docker containers

The Docker VM manager is on by default (EC2_VM_MANAGER=docker); instances run as Docker containers, not real VMs. No GPU, no instance store, no placement groups. Set EC2_VM_MANAGER=none for metadata-only mode if you don't need real compute.

Databases

RDS: real engines, limited features

Runs real PostgreSQL, MySQL, and MariaDB (with RDS_DOCKER_BACKEND=1) but no automated backups, no multi-AZ, no read replicas, no Performance Insights.

DynamoDB: no Streams cross-region replication

DynamoDB Streams work locally but cross-region replication is not implemented.

DynamoDB: no adaptive capacity / auto-scaling

Billing mode is stored but not enforced. Read and write capacity are not throttled.

ElastiCache: CRUD-only

No real Redis or Memcached instance is started. Planned for a future release.

Neptune: CRUD-only

No real graph query engine. API operations are accepted but queries are not executed.

Analytics & ETL

Glue: Data Catalog only, no runtime

All 265 Glue operations are wired through moto, so the Data Catalog (databases, tables, partitions, columns, schemas, tags, resource policies) round-trips correctly and Athena reads from it via the Glue resolver. Crawlers do not crawl S3, ETL jobs do not execute, Glue Studio / DataBrew / Streaming Jobs / DataQuality / SchemaRegistry runtime / Interactive Sessions are not emulated. CreateCrawler + StartCrawler succeed at the API but infer no schema; CreateJob + StartJobRun succeed at the API but run no Spark or Python code.

Service quotas and limits

AWS enforces service quotas (e.g., 1000 S3 buckets per account, 75 Lambda concurrent executions). LocalEmu does not enforce these limits. Your code may work locally but hit quota errors on real AWS.

Eventual consistency

S3 is strongly consistent (both on AWS and LocalEmu). However, some AWS services exhibit eventual consistency (IAM policy propagation takes seconds, DynamoDB global table replication has lag). LocalEmu applies changes immediately. Code that depends on eventual consistency patterns may behave differently.

What we're working on

  • API Coverage auto-generation (tracking every operation per service)
  • State export/import (Cloud Pods equivalent, free)
  • Docker image for containerized deployments
  • ElastiCache Docker backend (real Redis)