Local cloud emulators
A process on your laptop or CI runner that answers a cloud provider’s API, so tests and dev loops run with no account, no bill and no network.
3 technologies on this page ↓How it works
A cloud SDK turns every call, such as put_item or send_message, into an HTTP request to the provider’s regional endpoint. An emulator is a server that listens on localhost and implements the same operations with the same request and response formats. You change one setting, not your code: AWS_ENDPOINT_URL=http://localhost:4566 for the AWS SDKs and CLI, PUBSUB_EMULATOR_HOST for Google’s Pub/Sub clients, or a connection string with Azurite’s well-known development account for Azure Storage. Some emulators fake one service (DynamoDB Local, the Pub/Sub emulator, Azurite); others put dozens behind one port and route each request by the API it names (LocalStack, Floci). State lives in memory or a local file and is usually gone after a restart, which gives every test run a clean cloud. Any dummy key is accepted, and IAM policies aren’t checked unless you switch that on. Where faking is hard, emulators start real engines in Docker: a Lambda function runs in a container built from AWS’s runtime image, and an emulated RDS database can be a real PostgreSQL. The catch is fidelity. Operations finish instantly, throughput settings and quotas are ignored, reads that are only eventually consistent in the cloud look strongly consistent, error messages can differ, and whole services or newer features may be missing. A mock replaces the client inside your test process; an emulator is a separate server, so the real SDK, its serialisation and tools like Terraform are exercised too. It still isn’t the cloud, so teams keep a smaller suite that runs against a real account before release.
A flight simulator. The controls, instruments and checklists are the real ones, so pilots can practise for hours with no fuel and no risk. It never quite reproduces real weather or a failing engine, though, so they still fly the real aircraft before carrying passengers.
Reach for it when
- Integration tests in CI that call cloud APIs, with no shared account, no credentials in the pipeline and nothing to clean up
- A fast inner loop: create a bucket, queue or table in milliseconds and reset everything with a restart
- Trying infrastructure as code (Terraform, CDK, SAM) against a throwaway target before it touches a real account
- Giving new contributors or AI coding agents a sandbox with no real credentials and nothing to bill
Think twice when
- Testing IAM policies, quotas, throttling, latency or scaling: emulators skip or simplify them by default
- Services or features the emulator covers only partly; read its coverage page before building on it
- As the only test before production: keep a smaller suite that runs against a real account
- Load and performance tests: a container on a laptop says nothing about cloud throughput
A real example
In CI, a job starts an emulator container on port 4566 and sets AWS_ENDPOINT_URL=http://localhost:4566 with the dummy keys test/test. Each test creates the orders table and the receipts queue, places an order and checks that the item and the message exist, then deletes both. The 40 tests finish in under a minute with no AWS account and nothing left behind. A nightly job runs the same suite against a real staging account; it is the one that catches a missing sqs:SendMessage permission, because the emulator, with IAM checks off, let the call through.
Technologies
Specific products, and what each does differently.
FlociOpen sourceA young, MIT-licensed family of local emulators for AWS, Azure, Google Cloud and Oracle Cloud, built as a free drop-in for LocalStack and pitched at AI coding agents.
LocalStackCommercialThe best-known AWS emulator: one Docker container that answers more than 100 AWS APIs on localhost:4566, now free only for non-commercial use. Floci | Open source | Floci project (led by Hector Ventura) | MIT (all four emulators, the CLI and the Testcontainers modules) | 2026-10-06 |
LocalStack | Commercial product | LocalStack | Proprietary since the March 2026 single image (an account and auth token are needed for current releases); the archived Community edition source, up to v4.14.0, stays Apache 2.0 | 2026-10-06 |
| Open source | Cloudflare, Inc. | MIT | 2026-10-12 |
What each provider calls it
- AWS
- No general emulator. DynamoDB Local (JAR, Maven or Docker); `sam local` runs Lambda functions and API routes in Docker; the Lambda Runtime Interface Emulator tests container-image functions; Step Functions Local still downloads, but AWS now marks it unsupported and points to the TestState API
- Google Cloud
- `gcloud beta emulators` for Pub/Sub, Datastore, Firestore, Bigtable and Spanner; the Firebase Local Emulator Suite for Firestore, Realtime Database, Auth, Storage, Hosting and Functions
- Azure
- Azurite (open source: Blob, Queue and Table; replaces the deprecated Windows-only Storage Emulator); the Cosmos DB emulator for Windows plus a Linux Docker preview for the NoSQL API; Docker emulators for Service Bus and Event Hubs; Azure Functions Core Tools runs functions locally
- Open source & others
- LocalStack (AWS, plus Snowflake; the latest image needs a free or paid account since March 2026); Floci (MIT: AWS, Azure, Google Cloud and Oracle Cloud); moto (Python mocks with a standalone server mode); fake-gcs-server for Cloud Storage; S3-compatible servers such as Garage or SeaweedFS stand in for S3 alone
In code · python
# Start an emulator first, e.g. docker run -d -p 4566:4566 floci/floci:latest
# (or LocalStack with LOCALSTACK_AUTH_TOKEN set). The code under test doesn't change.
import os
import boto3
import pytest
os.environ.setdefault("AWS_ENDPOINT_URL", "http://localhost:4566") # every service, one port
os.environ.setdefault("AWS_ACCESS_KEY_ID", "test") # dummy keys, no account
os.environ.setdefault("AWS_SECRET_ACCESS_KEY", "test")
os.environ.setdefault("AWS_DEFAULT_REGION", "us-east-1")
def place_order(ddb, sqs, queue_url, order_id): # the code under test
ddb.put_item(TableName="orders", Item={"id": {"S": order_id}})
sqs.send_message(QueueUrl=queue_url, MessageBody=order_id)
@pytest.fixture
def aws():
ddb, sqs = boto3.client("dynamodb"), boto3.client("sqs")
ddb.create_table(TableName="orders", BillingMode="PAY_PER_REQUEST",
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}])
url = sqs.create_queue(QueueName="receipts")["QueueUrl"]
yield ddb, sqs, url
ddb.delete_table(TableName="orders") # a clean cloud for the next test
sqs.delete_queue(QueueUrl=url)
def test_place_order(aws):
ddb, sqs, url = aws
place_order(ddb, sqs, url, "4812")
assert "Item" in ddb.get_item(TableName="orders", Key={"id": {"S": "4812"}})
assert len(sqs.receive_message(QueueUrl=url, WaitTimeSeconds=1)["Messages"]) == 1Often confused with
Where it came from2008–2026
Testing code that talks to a cloud once meant two bad options: deploy to a real account and wait, pay and clean up, or mock the client and hope the mock behaved like the service. Google App Engine launched in April 2008 with an SDK that included a “fully featured local development environment”, so the platform could run on a laptop. Microsoft’s Azure SDK shipped a Storage Emulator that faked Blob, Queue and Table storage on top of a local SQL Server database.
In 2013 the open-source moto project began mocking AWS calls in Python tests, and that September AWS released DynamoDB Local so developers could write DynamoDB code “while sitting in a tree, on the beach, or in the desert”. In August 2016 Waldemar Hummer’s first commit of LocalStack, at Atlassian, put eight AWS APIs on a laptop at once; the team’s stated aim was to make train commutes productive. Google and Microsoft followed with emulators of their own, and LocalStack grew into a company that sells an AWS and a Snowflake emulator.
In March 2026 LocalStack stopped updating its free open-source image and required an account for its latest releases. Floci, an MIT-licensed replacement, shipped 1.0 that same month and now pitches emulators as a safe cloud for AI coding agents.
Why it’s built this way
- Speak the real wire protocol instead of mocking a library
- An in-process mock works for one language. A server on a port works with every SDK, the CLI and IaC tools, and the code under test changes only its endpoint. moto added a standalone server mode for exactly this reason.
- Keep state in memory and throw it away
- Tests want a clean, fast cloud every time. DynamoDB Local can run fully in memory, and LocalStack’s state is ephemeral unless persistence is switched on.
- Accept any credentials and skip IAM by default
- The point is to need no account. DynamoDB Local uses the access key only to name its database file and ignores the secret key; LocalStack and Floci evaluate IAM policies only when you enable it.
- Run real engines where faking falls short
- Re-implementing a function runtime or a database is hard to get right, so
sam local, LocalStack and Floci run Lambda functions in containers built from AWS’s runtime images, and Floci backs RDS with real PostgreSQL or MySQL.
Timeline
- 2008
App Engine ships with an SDK and a local development environment
- 2013
moto starts mocking AWS in February; DynamoDB Local arrives in September
- 2016
LocalStack is open-sourced at Atlassian with eight AWS APIs
- 2024
LocalStack adds an emulator for Snowflake, beyond the cloud providers
- 2026
LocalStack gates its latest image behind accounts; Floci 1.0 ships under MIT
- Google App Engine blog: Introducing Google App Engine (April 2008)
- AWS News Blog: DynamoDB Local for desktop development (Jeff Barr, September 2013)
- getmoto/moto on GitHub (repository created February 2013)
- LocalStack blog: 30k stars, 40M pulls, with a brief history of LocalStack (May 2021)
- LocalStack blog: Introducing LocalStack for Snowflake (May 2024)
- LocalStack blog: The road ahead for LocalStack (December 2025)
- Floci Chronicle: 30 days of Floci (Hector Ventura, April 2026)
Sources24
- AWS SDKs and Tools reference: Service-specific endpoints (`AWS_ENDPOINT_URL`)
- DynamoDB docs: Setting up DynamoDB local (JAR, Maven, Docker)
- DynamoDB docs: DynamoDB local usage notes (differences from the web service)
- AWS SAM docs: Introduction to testing with sam local
- AWS SAM docs: sam local invoke (builds the function in a local Docker container)
- AWS Step Functions docs: Step Functions Local (unsupported)
- AWS Lambda Runtime Interface Emulator on GitHub
- gcloud reference: gcloud beta emulators
- Pub/Sub docs: Testing apps locally with the emulator (limitations)
- Firebase docs: Local Emulator Suite
- Microsoft Learn: Use the Azurite emulator for local Azure Storage development
- Microsoft Learn: Use the Azure Storage Emulator (deprecated; SQL Server LocalDB, Windows only)
- Microsoft Learn: Azure Cosmos DB emulator (differences from the cloud service)
- Microsoft Learn: Linux-based Cosmos DB emulator, vNext (NoSQL API, preview)
- Microsoft Learn: Azure Service Bus emulator overview
- Microsoft Learn: Azure Event Hubs emulator overview
- Microsoft Learn: Develop Azure Functions locally using Core Tools
- LocalStack docs: IAM policy enforcement (disabled by default)
- LocalStack docs: Persistence (state is ephemeral by default)
- LocalStack blog: LocalStack for AWS is moving to a single image (March 2026)
- Floci README (services, real Docker integration, LocalStack migration)
- Floci docs: IAM enforcement mode (off by default)
- Moto docs: Server mode
- fake-gcs-server on GitHub