Tools: Floci (LocalStack alternative) storage modes: pick the right tradeoff per service (and never pay for it)

Tools: Floci (LocalStack alternative) storage modes: pick the right tradeoff per service (and never pay for it)

The four modes at a glance

When to use each

memory (default) for CI and ephemeral tests

hybrid for local development

persistent when losing the last write hurts

wal: for high-write workloads that still need durability

Per-service overrides

How this compares to LocalStack

A pattern that just works State that survives a docker compose down is one of those things you don't think about, until your test suite needs it, your local dev needs it, and your CI pipeline absolutely doesn't. LocalStack handles persistence with one switch (PERSISTENCE=1) and it's a Pro-only feature. Floci ships four storage modes, all free, all in core, with per-service overrides. Pick the right tradeoff for the job. You set a global default, and override per service when one needs different behavior. That's it. Everything stays in RAM. Container restarts wipe the slate. Fastest possible writes, smallest possible footprint. This is the right answer for almost every CI pipeline. Each test run starts clean, you don't manage volumes, and you don't fight stale state from a previous job. Combined with Floci's 24ms cold start and 13 MiB idle footprint, you can spin up a fresh emulator per test class without thinking. Reads and writes hit memory. A background flush moves data to disk every ~5 seconds. Container restarts pick up where you left off. This is the mode I run locally. It feels exactly like memory while you're working, no I/O latency on writes, but docker compose down doesn't nuke your seeded test data. You spend less time re-running setup scripts. Every change syncs to disk before responding. Slower writes, but if Docker hard-kills the container at the wrong moment, the data that was acknowledged is genuinely on disk. Reach for this when you're building something where "did this actually save?" matters, like reproducing a production data corruption issue, or running a long-running local script you don't want to redo. Every mutation goes to an append-only log first, with periodic compaction. You get durability without paying the random-write cost of persistent mode. Useful when you're stress-testing a service that writes a lot and high-volume DynamoDB, Kinesis-heavy pipelines, anything where persistent becomes the bottleneck but you still want crash-safety. This is the part that doesn't exist anywhere else: set the global mode, then override only the services that need different behavior. Want fast tests but keep your seeded DynamoDB tables across restarts? Two env vars. LocalStack persistence is a single boolean (PERSISTENCE=1) that's locked behind the Pro tier. Beyond pricing, the design itself is different: The locking part is the one most people don't see coming. LocalStack's snapshot mechanism blocks requests to a service while it's being saved, which is fine for shutdown, but surprising mid-test. Floci never pauses writes; durability comes from the storage mode you picked, not from a freeze-and-dump. For most teams, this covers 90% of what you need. CI: No auth token, no Pro tier, no surprise locking. That's the point. Persistence isn't an enterprise feature, it's a basic developer ergonomic. Floci ships it that way. ๐Ÿ”— github.com/floci-io/floci ยท ๐Ÿ“š Storage docs ยท ๐Ÿ’ฌ floci.slack.com Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

# -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" environment: FLOCI_STORAGE_MODE: memory # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" environment: FLOCI_STORAGE_MODE: memory # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" environment: FLOCI_STORAGE_MODE: memory # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: hybrid # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: hybrid # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: hybrid # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: persistent # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: persistent # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: persistent # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: ["4566:4566"] volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: wal FLOCI_STORAGE_WAL_COMPACTION_INTERVAL_MS: 30000 # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: ["4566:4566"] volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: wal FLOCI_STORAGE_WAL_COMPACTION_INTERVAL_MS: 30000 # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: ["4566:4566"] volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: wal FLOCI_STORAGE_WAL_COMPACTION_INTERVAL_MS: 30000 # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: memory # everything is ephemeral by default FLOCI_STORAGE_SERVICES_DYNAMODB_MODE: persistent # except DynamoDB โ€” keep that on disk FLOCI_STORAGE_SERVICES_S3_MODE: hybrid # and S3 โ€” keep buckets across restarts # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: memory # everything is ephemeral by default FLOCI_STORAGE_SERVICES_DYNAMODB_MODE: persistent # except DynamoDB โ€” keep that on disk FLOCI_STORAGE_SERVICES_S3_MODE: hybrid # and S3 โ€” keep buckets across restarts # -weight: 500;">docker-compose.yml services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: memory # everything is ephemeral by default FLOCI_STORAGE_SERVICES_DYNAMODB_MODE: persistent # except DynamoDB โ€” keep that on disk FLOCI_STORAGE_SERVICES_S3_MODE: hybrid # and S3 โ€” keep buckets across restarts services: floci: image: floci/floci:latest ports: - "4566:4566" environment: FLOCI_STORAGE_MODE: memory services: floci: image: floci/floci:latest ports: - "4566:4566" environment: FLOCI_STORAGE_MODE: memory services: floci: image: floci/floci:latest ports: - "4566:4566" environment: FLOCI_STORAGE_MODE: memory services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: hybrid services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: hybrid services: floci: image: floci/floci:latest ports: - "4566:4566" volumes: - ./data:/app/data environment: FLOCI_STORAGE_MODE: hybrid