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

Published: (May 3, 2026 at 03:29 PM EDT)
3 min read
Source: Dev.to

Source: Dev.to

Overview

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.
Floci ships four storage modes (all free, all in core) with per‑service overrides, letting you pick the right trade‑off for the job.

Storage modes

ModeSurvives restartWrite behaviorBest for
memoryPure RAMCI, unit tests, ephemeral integration tests
hybridAsync flush to diskLocal development (the sweet spot)
persistentSync write on every change“Don’t lose my last write” workflows
walAppend‑only log + compactionHigh‑throughput durable workloads

You set a global default and override per service when a different behavior is required.

Configuration examples

Memory (default) – ideal for CI

# docker-compose.yml
services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    environment:
      FLOCI_STORAGE_MODE: memory

Everything stays in RAM. Container restarts wipe the slate. Fastest possible writes, smallest footprint.

Hybrid – local development

# docker-compose.yml
services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    volumes:
      - ./data:/app/data
    environment:
      FLOCI_STORAGE_MODE: hybrid

Reads and writes hit memory; a background flush moves data to disk every ~5 seconds. docker‑compose down doesn’t nuke your seeded test data.

Persistent – when losing the last write hurts

# docker-compose.yml
services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    volumes:
      - ./data:/app/data
    environment:
      FLOCI_STORAGE_MODE: persistent

Every change syncs to disk before responding. Slower writes, but acknowledged data is genuinely on disk—even if Docker hard‑kills the container.

WAL – high‑write workloads that still need durability

# 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

Mutations go to an append‑only log first, with periodic compaction. You get durability without the random‑write cost of the persistent mode.

Global default with per‑service overrides

# 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    # keep DynamoDB on disk
      FLOCI_STORAGE_SERVICES_S3_MODE: hybrid               # keep S3 buckets across restarts

Fast tests overall, but retain seeded DynamoDB tables and S3 buckets across restarts.

Comparison with LocalStack (Pro)

FeatureLocalStack (Pro)Floci
CostPaid tierFree, MIT‑licensed
GranularityGlobal on/offFour modes, per‑service overrides
Write strategySnapshots (point‑in‑time)Sync, async, or WAL — your choice
During snapshotService is locked, requests blockNo locking, writes never pause
Cross‑versionSnapshots may break across versionsPlain on‑disk format
ImplementationPython pickle serializationNative, format per service

The locking part is the one most people don’t anticipate. LocalStack’s snapshot mechanism blocks requests while a service is being saved—acceptable at shutdown but surprising mid‑test. Floci never pauses writes; durability comes from the chosen storage mode, not from a freeze‑and‑dump.

Typical setups

CI

services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    environment:
      FLOCI_STORAGE_MODE: memory

Local development

services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    volumes:
      - ./data:/app/data
    environment:
      FLOCI_STORAGE_MODE: hybrid

No auth token, no Pro tier, no surprise locking. Persistence is a basic developer ergonomic, not an enterprise‑only feature.

0 views
Back to Blog

Related posts

Read more »