Floci: The Lightweight Local AWS Emulator
No auth tokens. No telemetry. No JVM overhead. 24ms startup. 13 MiB idle. MIT licensed.
If you’ve been following the local AWS emulation space, you know what happened in March 2026. LocalStack’s Community edition sunset — requiring authentication tokens for basic usage and freezing all security updates on the last Community release. For teams running CI pipelines, local development environments, and Terraform validation workflows, this created an immediate gap.
Enter Floci — a fast, free, and open-source local AWS emulator that fills that gap completely.
Named after cirrocumulus floccus (a small, fluffy cloud formation), Floci is a drop-in replacement for LocalStack that requires zero configuration, zero authentication, and zero compromises. Pull the Docker image, point your AWS SDK at localhost:4566, and you're running 45+ AWS services locally.
Why Local AWS Emulators Matter
Before we dive in — why would you even want to run AWS services locally?
What Makes Floci Different
Floci isn’t just “another LocalStack clone.” Its architecture choices produce dramatically different performance characteristics.
Service Architecture
Floci takes a pragmatic approach to service emulation:
- In-process handlers — S3, SQS, SNS, DynamoDB, IAM, STS, KMS, and most services run as native in-process handlers. They’re fast, lightweight, and wire-protocol compatible.
- Real Docker containers — Lambda, RDS (PostgreSQL, MySQL), ElastiCache (Redis), ECS, EKS, and EC2 run as actual Docker containers managed by Floci’s Docker engine. This means genuine protocol fidelity — you’re talking to a real PostgreSQL engine, not a mock.
The Docker backend approach is what sets Floci apart from mock-only emulators. When you run
aws rds describe-db-instances, Floci returns metadata about actual running containers. The service metadata you get back matches what real Docker containers produce.
Installation Guide
Floci ships as a Docker image (floci/floci) with three variants:
Install with Docker
The simplest way to get started:
docker run --rm -p 4566:4566 floci/floci:latestThat’s it. Floci is now running all 45+ services on port 4566.
For persistent storage (so your data survives container restarts):
docker run --rm \
-p 4566:4566 \
-v floci-data:/var/lib/floci \
floci/floci:latestPort 4566 is the same port LocalStack uses. If you’re migrating, you don’t need to change any application code — just swap the image.
Install with Docker Compose
For most development setups, Docker Compose is the way to go. Here’s a complete setup:
# docker-compose.yml
version: "3.8"services:
floci:
image: floci/floci:latest
container_name: floci
ports:
- "4566:4566"
volumes:
- floci-data:/var/lib/floci
- /var/run/docker.sock:/var/run/docker.sock # Required for Lambda, ECS, RDS
environment:
- FLOCI_LOG_LEVEL=info
- FLOCI_DATA_DIR=/var/lib/floci
restart: unless-stoppedvolumes:
floci-data:
Start Floci:
docker compose up -dCheck it’s running:
docker compose logs floci# Expected output:
# floci | 2026-05-18 10:15:23 INFO Starting Floci v1.15.0
# floci | 2026-05-18 10:15:23 INFO Listening on http://0.0.0.0:4566
# floci | 2026-05-18 10:15:23 INFO 45 services availableStop Floci:
docker compose downStop and delete all data:
docker compose down -vWhy Mount docker.sock?
volumes:
- /var/run/docker.sock:/var/run/docker.sockThis gives Floci the ability to create and manage Docker containers on your host. This is required for:
- Lambda — Each function invocation runs in an ephemeral Docker container
- RDS — PostgreSQL and MySQL databases run as managed containers
- ElastiCache — Redis instances are real Redis containers
- ECS — Tasks and services spin up actual containers
- EC2 — EC2 instances run as Docker containers with SSH access
If you don’t mount
docker.sock, Lambda, RDS, and ElastiCache will not work. S3, SQS, SNS, DynamoDB, IAM, STS, and KMS will still work fine since they're in-process.
Install with systemd
For development servers or dedicated CI runners, you can run Floci as a systemd service:
# /etc/systemd/system/floci.service
[Unit]
Description=Floci - Local AWS Emulator
Documentation=https://floci.io
After=docker.service
Requires=docker.service[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/docker start -a floci
ExecStop=/usr/bin/docker stop floci
ExecStartPre=-/usr/bin/docker rm floci
ExecStartPre=/usr/bin/docker pull floci/floci:latest
ExecStartPre=/usr/bin/docker run \
--name floci \
-p 4566:4566 \
-v floci-data:/var/lib/floci \
-v /var/run/docker.sock:/var/run/docker.sock \
floci/floci:latest[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable floci
sudo systemctl start flociCheck status:
sudo systemctl status flociTroubleshooting:
# View logs
sudo journalctl -u floci -f# Restart
sudo systemctl restart floci# Check port
ss -tlnp | grep 4566
Using Floci
Configure AWS CLI
Floci accepts any credentials and any region. This simplifies configuration significantly:
# Install AWS CLI if you haven't already
pip install awscli# Configure for Floci
aws configure set aws_access_key_id floci
aws configure set aws_secret_access_key floci
aws configure set region us-east-1# Set the endpoint URL (use --endpoint-url for every command)
export AWS_ENDPOINT_URL=http://localhost:4566
Set
AWS_ENDPOINT_URLas an environment variable to avoid typing--endpoint-urlon every command. Floci uses the same port as LocalStack (4566), soAWS_ENDPOINT_URL=http://localhost:4566is all you need.
Full Configuration Options
# Option 1: Environment variables (recommended)
export AWS_ACCESS_KEY_ID=any-value-works
export AWS_SECRET_ACCESS_KEY=any-value-works
export AWS_DEFAULT_REGION=us-east-1
export AWS_ENDPOINT_URL=http://localhost:4566# Option 2: Per-command (useful for testing)
aws s3 ls --endpoint-url=http://localhost:4566# Option 3: Config file (~/.aws/config)
cat >> ~/.aws/config << 'EOF'
[profile floci]
region = us-east-1
output = json
endpoint_url = http://localhost:4566
EOF# Then use with --profile
aws s3 ls --profile floci
Test S3
Floci’s S3 implementation is nearly feature-complete — buckets, objects, versioning, encryption, lifecycle rules, and Object Lock all work.
# Create a bucket
aws s3 mb s3://my-floci-bucket --endpoint-url=http://localhost:4566# Expected output:
# make_bucket: my-floci-bucket# List buckets
aws s3 ls --endpoint-url=http://localhost:4566# Expected output:
# 2026-05-18 10:20:00 my-floci-bucket# Create a test file
echo "Hello from Floci!" > hello.txt# Upload it
aws s3 cp hello.txt s3://my-floci-bucket/ --endpoint-url=http://localhost:4566# Expected output:
# upload: ./hello.txt to s3://my-floci-bucket/hello.txt
# Download it
aws s3 cp s3://my-floci-bucket/hello.txt ./downloaded.txt --endpoint-url=http://localhost:4566# Verify
cat downloaded.txt
# Hello from Floci!# List objects
aws s3 ls s3://my-floci-bucket/ --endpoint-url=http://localhost:4566# Expected output:
# 2026-05-18 10:20:15 20 hello.txt# Delete the bucket
aws s3 rb s3://my-floci-bucket --force --endpoint-url=http://localhost:4566Test SQS
SQS works identically to AWS. Queues, messages, visibility timeouts, DLQs — everything.
# Create a standard queue
aws sqs create-queue \
--queue-name my-floci-queue \
--endpoint-url=http://localhost:4566# Expected output:
# {
# "QueueUrl": "http://localhost:4566/000000000000/my-floci-queue"
# }# List queues
aws sqs list-queues --endpoint-url=http://localhost:4566# Expected output:
# {
# "QueueUrls": [
# "http://localhost:4566/000000000000/my-floci-queue"
# ]
# }# Get the queue URL
QUEUE_URL=$(aws sqs get-queue-url \
--queue-name my-floci-queue \
--endpoint-url=http://localhost:4566 \
--query 'QueueUrl' \
--output text)echo $QUEUE_URL
# http://localhost:4566/000000000000/my-floci-queue# Send a message
aws sqs send-message \
--queue-url "$QUEUE_URL" \
--message-body "Hello from Floci SQS" \
--endpoint-url=http://localhost:4566# Expected output:
# {
# "MD5OfMessageBody": "abc123def456",
# "MessageId": "550e8400-e29b-41d4-a716-446655440000"
# }# Send multiple messages (batch)
aws sqs send-message-batch \
--queue-url "$QUEUE_URL" \
--entries \
'{"Id":"msg1","MessageBody":"First message"}' \
'{"Id":"msg2","MessageBody":"Second message"}' \
--endpoint-url=http://localhost:4566# Receive messages
aws sqs receive-message \
--queue-url "$QUEUE_URL" \
--max-number-of-messages 10 \
--wait-time-seconds 5 \
--endpoint-url=http://localhost:4566# Expected output:
# {
# "Messages": [
# {
# "MessageId": "550e8400-e29b-41d4-a716-446655440000",
# "ReceiptHandle": "abc123...",
# "MD5OfBody": "abc123def456",
# "Body": "Hello from Floci SQS"
# },
# {
# "MessageId": "...",
# "ReceiptHandle": "...",
# "MD5OfBody": "...",
# "Body": "First message"
# },
# {
# "MessageId": "...",
# "ReceiptHandle": "...",
# "MD5OfBody": "...",
# "Body": "Second message"
# }
# ]
# }# Delete a queue
aws sqs delete-queue \
--queue-url "$QUEUE_URL" \
--endpoint-url=http://localhost:4566SQS in Floci supports all standard features: FIFO queues, dead-letter queues, message attributes, delay queues, and long polling. There are no functional limitations compared to the real AWS SQS API.
Test Lambda
Floci’s Lambda support runs each function in an ephemeral Docker container. This means you get real execution environments — not mocks.
Get Gerardo Ocampos’s stories in your inbox
Join Medium for free to get updates from this writer.
First, create a simple Node.js function:
mkdir my-lambda && cd my-lambda# Create the handler
cat > index.js << 'EOF'
exports.handler = async (event) => {
console.log("Event received:", JSON.stringify(event, null, 2)); const name = event.name || "Floci";
return {
statusCode: 200,
body: JSON.stringify({
message: `Hello, ${name}! Lambda is running on Floci.`,
timestamp: new Date().toISOString(),
}),
};
};
EOF# Package it
zip -r function.zip index.js
Now create and invoke the function:
# Create the function
aws lambda create-function \
--function-name hello-floci \
--runtime nodejs20.x \
--role arn:aws:iam::000000000000:role/lambda-role \
--handler index.handler \
--zip-file fileb://function.zip \
--endpoint-url=http://localhost:4566
# Expected output:
# {
# "FunctionName": "hello-floci",
# "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:hello-floci",
# "Runtime": "nodejs20.x",
# "Handler": "index.handler",
# ...
# }# Invoke the function synchronously
aws lambda invoke \
--function-name hello-floci \
--payload '{"name": "DevOps Engineer"}' \
--cli-binary-format raw-in-base64-out \
response.json \
--endpoint-url=http://localhost:4566
# Expected output:
# {
# "StatusCode": 200,
# "ExecutedVersion": "$LATEST"
# }
# Check the response
cat response.json | python3 -m json.tool
# {
# "statusCode": 200,
# "body": "{\"message\": \"Hello, DevOps Engineer! Lambda is running on Floci.\", \"timestamp\": \"2026-05-18T10:25:00.000Z\"}"
# }# Invoke asynchronously (fire-and-forget)
aws lambda invoke \
--function-name hello-floci \
--invocation-type Event \
--payload '{"name": "Async Call"}' \
--cli-binary-format raw-in-base64-out \
/dev/null \
--endpoint-url=http://localhost:4566
# Expected output:
# {
# "StatusCode": 202
# }
# List functions
aws lambda list-functions --endpoint-url=http://localhost:4566
# View logs (Floci captures Lambda logs)
aws logs describe-log-groups --endpoint-url=http://localhost:4566Lambda cold starts with Floci take about 1–2 seconds (to spin up the Docker container). Subsequent invocations are warm (sub-millisecond routing). This is significantly faster than LocalStack’s Lambda emulation.
Testing with Terraform
This is where Floci really shines. Terraform validation against real AWS APIs without touching an actual AWS account — or waiting for an apply against LocalStack’s slower emulation.
Floci implements the same AWS service API responses that Terraform’s AWS provider expects. The wire protocol is identical. When Terraform calls CreateBucket, Floci returns the same XML response AWS would. Terraform doesn't know — or care — that no real S3 service exists behind that response.
This means:
terraform planruns against real-seeming stateterraform applyactually mutates state in Floci's data directoryterraform importpopulates local state from Floci's resources- Terraform’s
hashicorp/awsprovider works without modification
Complete Terraform Example
Here’s a full example that creates an S3 bucket
# main.tf
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
# Floci / LocalStack compatible endpoint
endpoints {
s3 = "http://localhost:4566"
sqs = "http://localhost:4566"
lambda = "http://localhost:4566"
iam = "http://localhost:4566"
}
# Floci accepts any credentials
access_key = "floci"
secret_key = "floci"
# Skip AWS-specific validation
skip_credentials_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true
skip_region_validation = true
s3_use_path_style = true
}
# ──────────────────────────────────────
# S3 Bucket
# ──────────────────────────────────────
resource "aws_s3_bucket" "storage" {
bucket = "floci-terraform-demo-${random_id.suffix.hex}"
force_destroy = true
}
resource "aws_s3_bucket_versioning" "storage" {
bucket = aws_s3_bucket.storage.id
versioning_configuration {
status = "Enabled"
}
}
resource "random_id" "suffix" {
byte_length = 4
}Floci vs LocalStack
Since Floci positions itself as a LocalStack alternative, let’s do a thorough comparison.
Head-to-Head Comparison
When to Choose Floci
Floci is the better choice when:
- You need fast startup — CI pipelines where every second counts
- You’re memory-constrained — GitHub Actions runners, small dev machines
- You need Lambda/RDS/ElastiCache — Real containers, not emulations
- You don’t want auth tokens — No sign-ups, no API keys, no telemetry
- You want MIT licensing — Fork it, embed it, no restrictions
- You need ECS/EKS testing — Real Docker container orchestration
- You want offline development — No internet required after pulling the image
When to Consider LocalStack Pro
LocalStack Pro still has value in some scenarios:
- You already have an enterprise contract — Migration takes time
- You need the LocalStack-specific Pro features — Some CloudFormation edge cases
- You’re deep in the LocalStack Pro ecosystem — Existing integrations, custom extensions
But for the vast majority of teams — especially those using LocalStack Community before the March 2026 changes — Floci is a direct upgrade.
Final Thoughts
Floci represents a fundamental shift in what local AWS emulation looks like. The combination of GraalVM native compilation, Quarkus reactive runtime, and a pragmatic Docker-backend architecture produces something that genuinely feels faster and simpler than its predecessor.
Who Should Use Floci
PersonaRecommendationDevOps engineerReplace your LocalStack setup today. The CI pipeline speedup alone is worth it.Terraform / OpenTofu userFloci is the best IaC validation tool I’ve tested. Plans and applies complete in under a second.Kubernetes / EKS developerFloci’s k3s-based EKS emulation gives you real Kubernetes testing without a real cluster.Lambda developerThe real Docker container execution means your Lambda will behave identically to production.CI/CD engineer24ms startup + 13 MiB memory means Floci barely registers in your runner metrics.
Strengths
- Fast — Unbelievably fast startup. Your CI pipeline won’t notice it’s starting a service.
- Lightweight — 13 MiB idle makes a real difference on constrained runners (GitHub Actions, GitLab CI).
- Real containers — Lambda runs in Docker, not a process mock. RDS and ElastiCache are real databases.
- Truly open source — MIT license, no “community edition” sunset, no enterprise feature gates.
- Zero friction — No auth tokens, no sign-ups, no telemetry. Pull and run.
Limitations
- Still maturing — Floci is newer than LocalStack. Some edge cases may not be covered yet.
- Docker dependency — Lambda/RDS/ElastiCache require Docker on the host. This isn’t a problem in most environments but matters for some CI setups.
- Documentation — Growing rapidly, but not as extensive as LocalStack’s years of docs.
- Pro services — Some very niche AWS services (e.g. advanced CloudFormation transforms) may not be implemented yet.
Useful Links
- Floci Website: https://floci.io
- GitHub Repository: https://github.com/floci-io/floci
- Docker Hub: https://hub.docker.com/r/floci/floci
- Floci Documentation: https://floci.io/docs









