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)