AWS Emulator: Amazon's Free, Public-Domain Local AWS Is a Game Changer for Local Development and Startups

On 11 November AWS shipped AWS Emulator: a local copy of its APIs, free, no account, public domain, 438 service models. I ran it on a Mac the next day: healthy in 0.42 s, DynamoDB calls in 2.5 ms, AWS's own errors, a Lambda that actually ran. Why it changes the inner loop, and the maths for a ten-person startup.
On 11 November 2026, AWS did something the local-development world had waited years for: it shipped its own emulator. AWS Emulator is a local program that serves the AWS APIs on your laptop or in your CI job. Your existing AWS CLI and SDK calls go to it instead of to the cloud and come back in milliseconds, with the same results for valid calls and the same errors for invalid ones. It costs nothing, needs no AWS account, and its source is dedicated to the public domain. I built it on my Mac the next morning and ran a day's worth of S3, DynamoDB, SQS, Lambda and Secrets Manager calls against it. This post is what I found, and why I think it changes the economics of building on AWS for small teams.
AWS Emulator 1.0.338 (released 12 November 2026) in Docker Desktop 29.1 on an Apple M4 Max; boto3 1.42.97. Price, licence and service count from AWS's announcement and the repository.
The timing matters. For a decade the answer to "how do I test AWS code without an AWS bill" was LocalStack, an independent project whose open-source Community edition was archived on 23 March 2026. What remains free is a Hobby plan for non-commercial use; a company pays $39 or $89 per developer per month. Eight months later the vendor itself has published a free emulator covering 438 service models, generated from the same Smithy API models that build the SDKs, with per-service fidelity scores published on every release. That is a different category of thing from a third-party reimplementation, and the rest of this post is about why.
What it is, in one paragraph
AWS Emulator is a single Rust binary. It listens for HTTPS on 127.0.0.1:9297, generates its own access key (the IDs start with EMULATOR), a config file and a certificate on every start, and requires every request to be SigV4-signed with that key, as AWS does. It acts as one account, 000000000000, keeps every resource in memory, and forgets everything when it stops. Operations it implements return what AWS returns; operations it has not implemented yet return 501 Not Implemented, so a test fails at once rather than passing on a stub. Linux gets an RPM or Debian package; macOS and Windows build a small Docker image from AWS's Dockerfile. You point your SDK at it with environment variables and change no application code (user guide).
Why it changes local development
The inner loop collapses to milliseconds. A DynamoDB put took 2.5 ms on my machine, a get 2.9 ms, an SQS send 2.7 ms, an S3 get 3.3 ms, and the emulator was healthy 0.42 seconds after docker run. Against a real Region the same calls are tens of milliseconds plus the deploy that has to happen first. Nothing to provision, nothing to tear down, nothing to forget.
You get AWS's errors, not a mock's. This is the part that hand-written mocks never deliver and the part I checked hardest. A two-letter DynamoDB table name was refused with a ValidationException whose message is character-for-character what the real service sends. A conditional put on an existing key failed with ConditionalCheckFailedException. A missing S3 key was NoSuchKey; an upper-case bucket name, InvalidBucketName. A created table reported CREATING first and became ACTIVE three seconds later, and a put in between was refused the way AWS refuses it. A received SQS message stayed hidden until its visibility timeout, then came back with receive count 2. Code that handles these errors gets exercised on every run instead of on the first deploy.
import boto3, json # the shell above already points boto3 at the emulator
ddb = boto3.client("dynamodb")
ddb.create_table(TableName="orders", BillingMode="PAY_PER_REQUEST",
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}]) # 2.7 ms, TableStatus CREATING
ddb.get_waiter("table_exists").wait(TableName="orders") # ACTIVE after 3.0 s, like AWS
ddb.put_item(TableName="orders", Item={"id": {"S": "o-7"}, "status": {"S": "NEW"}, "amount": {"N": "21"}})
ddb.update_item(TableName="orders", Key={"id": {"S": "o-7"}},
UpdateExpression="SET #s = :s ADD amount :a",
ExpressionAttributeNames={"#s": "status"},
ExpressionAttributeValues={":s": {"S": "PAID"}, ":a": {"N": "100"}},
ReturnValues="ALL_NEW")["Attributes"]
# -> {'amount': {'N': '121'}, 'id': {'S': 'o-7'}, 'status': {'S': 'PAID'}} 3.4 ms
ddb.create_table(TableName="ab", ...) # two letters: AWS refuses this
# ValidationException: 1 validation error detected: Value 'ab' at 'tableName' failed to
# satisfy constraint: Member must have length greater than or equal to 3 (AWS's exact text)
lam = boto3.client("lambda") # after create_function(Runtime="python3.12", Code={"ZipFile": ...})
lam.invoke(FunctionName="double", Payload=json.dumps({"n": 21}).encode())["Payload"].read()
# -> b'{"ok": true, "n": 42}' StatusCode 200 in 76 ms; the handler ran on this machine
Lambda code actually runs. I zipped a two-line Python 3.12 handler, created the function, and invoked it: {"ok": true, "n": 42} came back with status 200 in 76 ms. Lambda's fidelity score is the lowest of the core serverless services, 55.9%, so expect gaps, but write-invoke-read works without leaving the machine.
One emulator per thing that needs isolation. Each instance gets its own port, keys and memory, and AWS's guidance is to run as many as you like: one per test suite, one per CI branch, one per coding agent. No shared account, so no collisions; --idle-timeout stops a forgotten instance by itself.
It is built for coding agents, and that is the quiet headline. AWS ships an aws-emulator skill for Kiro, Cursor and Claude Code that installs the emulator, points the project at it and, asked "will my app work on AWS Emulator?", reads the project's AWS calls against the fidelity tests and says which ones it can trust. An agent that can create the table, run the code, read the real error and fix it, with nothing it does reaching your account, is an agent you can leave alone. Every team that lets agents touch cloud infrastructure has a story about the run that did not stay in the sandbox. This is the sandbox.
| what I did | time | what came back |
|---|---|---|
| Build the image from the user guide's Dockerfile | 26 s | a 1.66 GB image; version 1.0.338, released that day |
| Start the container to a passing health check | 0.42 s | 177 MiB of memory idle; 201 MiB after everything below |
| S3: create bucket · put 200 objects · get 200 · list 200 keys | 3.6 · 47.4 · 3.3 · 26.6 ms | NoSuchKey for a missing key; InvalidBucketName for an upper-case name, as on AWS |
| DynamoDB: create table · put 200 items · get 200 · update expression | 2.7 · 2.5 · 2.9 · 3.4 ms | CREATING at first, ACTIVE after 3.0 s; SET … ADD … returned the right item; a conditional put failed with ConditionalCheckFailedException |
| DynamoDB: a two-letter table name | rejected | ValidationException with AWS's exact message: length must be greater than or equal to 3 |
| SQS: create queue · send 200 messages · visibility timeout | 2.7 ms per send | queue URL in AWS's shape; the received message was hidden, then came back with receive count 2 after the timeout |
| Lambda: create a python3.12 function from a zip · invoke it | 10.6 · 75.9 ms | StatusCode 200 and the payload {"ok": true, "n": 42}: the code ran on my machine |
| Secrets Manager and SSM Parameter Store round trips | 10.6 ms create | both values came back exactly |
| SNS topic subscribed to an SQS queue, one publish | 0 delivered | the subscription and publish were accepted, nothing arrived in the queue: a gap on this build |
One row in that table is a miss: an SQS queue subscribed to an SNS topic received nothing from a publish that was accepted. It is the right way to read the emulator. Look up the services your code uses in the published scores, trust the ones that pass, and keep a real-AWS test for the ones that do not.
Why it changes the maths for a startup
A ten-person team has three ways to let everyone develop against AWS: a sandbox account per developer, an emulator licence per seat, or, as of this week, AWS Emulator.
| option | ten developers, one year | what you get and what it assumes |
|---|---|---|
| AWS Emulator | $0 | no fee, no account, CC0; commercial use included; new services arrive from the API models |
| LocalStack Hobby | $0 | non-commercial use only, so not for a company; 30+ emulated services; account required since the Community edition was archived on 23 March 2026 |
| LocalStack Base | $4,680 | $39 per licence per month billed annually ($45 monthly); 55+ services, state persistence, basic IAM enforcement |
| LocalStack Ultimate | $10,680 | $89 per licence per month billed annually; 110+ services, advanced IAM testing, live-resource replicator |
| A real AWS sandbox account per developer | varies | whatever the forgotten buckets, idle instances and NAT gateways add up to each month, plus the time spent cleaning them |
The licence line is real money for a seed-stage company: $4,680 to $10,680 a year that now rounds to zero. The larger saving never appeared on an invoice. Per-developer AWS accounts cost whatever the forgotten resources cost, plus the afternoon spent in Cost Explorer finding them. CI pipelines that test against real AWS keep credentials in the CI system, the most common way cloud keys leak; the emulator needs none, because it mints its own on every start and rejects everything else. A new hire can run AWS code before their IAM user exists. A laptop on a plane can run the whole integration suite. And because the emulator is generated from AWS's own API models, a service announced at re:Invent arrives in the emulator with the model, which no third party could promise.
Startups also carry a risk larger companies do not: one bad agent run in a real account can be the month's budget. The emulator makes "let the agent try things" a free experiment instead of a gamble, with no vendor relationship, token, seat count or licence that can change its terms. CC0 cannot be revoked.
How honest the fidelity numbers are
AWS publishes a scores.json with every release and keeps the fidelity tests public in a second repository, 29,676 of them, each verified against at least two real AWS accounts before it counts. I added up the file attached to version 1.0.338.
| service | checks passing | of | fidelity |
|---|---|---|---|
| SNS | 483 | 641 | 75.4% |
| Step Functions | 736 | 987 | 74.6% |
| EventBridge | 719 | 968 | 74.3% |
| Cognito user pools | 679 | 976 | 69.6% |
| SQS | 1,061 | 1,536 | 69.1% |
| Secrets Manager | 302 | 444 | 68.0% |
| DynamoDB | 1,442 | 2,142 | 67.3% |
| S3 | 1,903 | 2,845 | 66.9% |
| API Gateway | 807 | 1,219 | 66.2% |
| IAM | 730 | 1,238 | 59.0% |
| Lambda | 1,689 | 3,021 | 55.9% |
| EC2 | 1,043 | 2,499 | 41.7% |
| CloudFormation | 840 | 4,282 | 19.6% |
| every service, 355 scored | 26,001 | 43,548 | 59.7% |
scores.json.gz attached to release v1.0.338 (scored 12 November 2026, 19:26 UTC): a check passes when the emulator matches AWS on every step of a recorded workflow, including the exact error. The user guide says control-plane fidelity is currently higher than data-plane fidelity and that infrastructure-as-code support varies by service; CloudFormation's row is that sentence in numbers.Three things to take from the table. The serverless core a startup builds on, S3, DynamoDB, SQS, SNS, EventBridge, Step Functions, Secrets Manager, Cognito, API Gateway, sits between two-thirds and three-quarters today, which matches what I saw: everything ordinary worked, one fan-out did not. CloudFormation at 19.6% means deploying a CDK or SAM stack into the emulator is not yet the way to use it; call the services directly from your tests, which is how most integration tests work anyway. And the number moves fast and in public: eight releases between 10 and 12 November, three of them on the 12th, and an issues/ tree holding 13,225 fixed behaviours and 6,937 open ones, each a dated note of one way the emulator differed from AWS. AWS also warns that a score can go down as new tests are added even while the emulator improves, which is the right way to run a scoreboard.
The way it was built, and why that is part of the story
The launch essay on All Things Distributed and the AWS News Blog post say that every line of the emulator was written and tested by agents and that the engineers wrote none of it. The repository bears this out: the first commit, "Initial emulator scaffold", is dated 21 October 2026, three weeks before launch, and the 30,681 commits since are signed by agents named for their jobs. One team writes fidelity tests from the API models and corrects them until they pass against real AWS; one replays them against the emulator and files issues; one fixes issues and pushes each change through a merge gate of build, coding-standard, security and fidelity-regression checks, with security agents reviewing adversarially. It began as a weekend experiment: one prompt asking a coding agent for an in-memory SQS that passed tests recorded against the real one, answered in about fifteen minutes.
That belongs in a post about local development because it explains what you are getting. The emulator is not a team's best reading of the documentation. It is the output of a machine whose only definition of correct is "the same bytes real AWS sent back", run continuously, with the failures published. That is a stronger guarantee than any mock.
What to keep on real AWS
AWS's own security page is unusually direct, and I will be too. The emulator does not evaluate IAM or resource-based policies the way AWS does and never denies a request signed with its own key: a request AWS would refuse may succeed locally, so it is not a tool for testing permissions. It is one account and one Region; to test two Regions you run two emulators. It does not simulate throttling, outages or Regional differences, so retry and back-off logic still needs a real target. State vanishes on stop. Function code it runs for you runs with your user's permissions, unsandboxed, so run only code you trust. Telemetry is on by default and anonymous; --telemetry off turns it off, and the telemetry page lists exactly what is sent. None of these are reasons not to use it. They are the list of what your pre-production suite on a real account is for, and that list just got shorter.
Start in five minutes
# 1. copy the eight-line Dockerfile from the user guide (aarch64 package on Apple silicon)
$ docker build -t aws-emulator . # 26 s on my Mac; a 1.66 GB image
$ mkdir -p ~/.aws/emulator
$ docker run --rm --memory=2g --memory-swap=2g -p 127.0.0.1:9297:9297 \
-e HOME="$HOME" -v "$HOME/.aws/emulator:$HOME/.aws/emulator" \
aws-emulator -p 9297 --telemetry off --idle-timeout 3600
# 2. in the shell that runs your code or tests: eight variables, then drop any real keys
$ export AWS_ENDPOINT_URL=https://127.0.0.1:9297
$ export AWS_SHARED_CREDENTIALS_FILE=~/.aws/emulator/9297/emulator_credentials
$ export AWS_CONFIG_FILE=~/.aws/emulator/9297/config
$ export AWS_CA_BUNDLE=~/.aws/emulator/9297/ca.pem
$ export AWS_EC2_METADATA_DISABLED=true AWS_DISABLE_HOST_PREFIX_INJECTION=true
$ export AWS_REGION=us-east-1 AWS_DEFAULT_REGION=us-east-1
$ unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE
# 3. prove you are not on AWS: the account is 000000000000, the key starts with EMULATOR
$ aws sts get-caller-identity --query Account --output text
000000000000
Three notes from doing it. Publish the port on 127.0.0.1, not -p 9297:9297, or your whole network can reach the emulator. Unset real credentials in the test shell: environment variables outrank the credentials file, and the emulator rejects requests signed with real keys, which is a feature. And a 501 means that operation is not implemented yet; check the service's score and the open-issues folder before filing a bug.
Where this leaves the field
LocalStack remains the more complete product for a team that needs persisted state, enforced IAM, a replicator for live resources, or Snowflake and Azure under the same roof, and it has a decade of edge cases the new emulator will spend the next year rediscovering. The community forks that appeared after March, LocalEmu, Floci, MiniStack and others, keep a free open-source option alive. But the centre of gravity has moved. The company that defines the APIs now ships a free, public-domain, machine-verified emulator of them, scored on every release, with an agent skill that tells you which of your calls to trust. For a developer, that is the inner loop they always wanted. For a startup, it is a line item that disappeared, a class of credential leak that cannot happen, and permission to let agents build without fear. Game changer is an overused phrase. This time the game actually changed.
FAQ: AWS Emulator for local development, CI and startups
Is AWS Emulator free, and can a company use it?
Yes. AWS Emulator has no service fee, needs no AWS account, and its source is released under the CC0 1.0 public-domain dedication, which allows commercial use. You pay only for real AWS resources when you deploy to AWS.
Is AWS Emulator a LocalStack replacement?
For the common case, local development and CI tests against S3, DynamoDB, SQS, Lambda and the rest of the serverless set, it is a free one, maintained by the vendor from the same API models the SDKs use. LocalStack's paid tiers still offer things the emulator does not: persisted state across restarts, IAM policy enforcement, a live-resource replicator, Snowflake and Azure emulation.
Does AWS Emulator run on macOS and Windows?
Yes, in Docker. AWS publishes Linux packages (RPM and Debian, x86_64 and aarch64) and an eight-line Dockerfile; on macOS and Windows you build the image from it and run the container with its port published on 127.0.0.1. There is no prebuilt image.
Can AWS Emulator test IAM policies or security?
No, and AWS says so plainly. It does not evaluate IAM or resource-based policies the way AWS does and never denies a request signed with its own key, so a call AWS would refuse may succeed locally. Keep security tests, and a final pass of the whole application, on a real AWS account.
Read next
References & Citations
- AWS (2026). AWS Emulator is now available for building and testing AWS applications locally, What's New, 11 November 2026; the product page; Test your applications against AWS locally with AWS Emulator, AWS News Blog, 11 November 2026.
- All Things Distributed (2026). AWS Emulator and the engineer's job when agents write the code, guest post, 11 November 2026: the three agent teams, the merge gate, the weekend SQS prototype.
- AWS Emulator User Guide (read 12 November 2026): What is AWS Emulator, Fidelity, Security, Getting started with Docker, Pointing your AWS SDK at AWS Emulator, Getting started with an AI coding agent, Checking whether your project works, Command reference, Telemetry.
- github.com/aws/aws-emulator (read 12 November 2026, 22:00 UTC): CC0-1.0 licence, 438 service crates, 30,681 commits on main, first commit 21 October 2026; releases v1.0.290 to v1.0.338; issues/things-that-do-not-work (6,937 files) and issues/things-that-now-work (13,225). Fidelity rows computed from
scores.json.gzon v1.0.338: 43,548 scored checks, 26,001 passing, 355 services scored. - github.com/aws/aws-emulator-evaluation-suite: 29,676 rows in
manifest.jsonl; README on verification against at least two AWS accounts (read 12 November 2026). - LocalStack (2026). localstack/localstack, archived 23 March 2026, banner on the Hobby plan; pricing page, read 12 November 2026: Hobby free for non-commercial use, Base $39 per licence per month billed annually ($45 monthly), Ultimate $89 billed annually.
- InfoWorld (2026). AWS unveils local emulator service, 11 November 2026: analyst remarks on throttling, outages and Regional behaviour not being simulated.
- The measured rows are a run for this post on 12 November 2026: AWS Emulator 1.0.338 built from the user guide's Dockerfile (aarch64) in Docker Desktop 29.1 on an Apple M4 Max; boto3 1.42.97; 200 calls per data-plane row, medians, wall-clock at the client; SNS-to-SQS fan-out observed to deliver 0 of 1 messages.
Subscribe to new posts from theaivibe.org
Related Posts

Stop Treating Vector Databases as the Default Answer for Similarity Search
The vector database became a default architectural choice before most teams understood what problem it actually solves. Here's when that choice is wrong.

When an AI-Generated Answer Actually Works, Who Is the Rule Protecting? A Fair Look at Both Sides — and a Rule Both Could Sign
A programming community I take part in watches for AI-generated answers. The moderators have real reasons; so do the people the rule lands on. Here are both cases argued fairly, the three things both sides actually want, and a tiered guideline — verification, disclosure, capacity — that is stricter than a blanket ban, not looser.

The Context Window Is Not a Database and You Should Stop Treating It Like One
Throwing more tokens at a problem feels like progress. It isn't. The context window is a compute surface, not a database, and the distinction has real architectural consequenc