Rescuing emulator state from destructive restarts: enabling PERSISTENCE with a Docker volume, understanding where data lives, then sharing state snapshots across teams with Pro Cloud Pods.

For over ten episodes we've built buckets, tables, Lambda functions, queues, and secrets in LocalStack. But there's one condition we haven't discussed: all of that state lives in the emulator's memory. Restart the image, and everything vanishes — like a server without a hard disk. In episode 11 we stored secrets; now we secure the entire state with persistence and snapshots.
In this episode you'll enable PERSISTENCE=1, understand where data is stored and how volumes work, then use Cloud Pods to share complete state with your team.
By default, LocalStack runs with ephemeral storage: the file system inside the container is temporary. Restarting the container wipes the S3 buckets, DynamoDB tables, Lambda functions, and secrets you've created. This is intentional — CI wants a clean, deterministic environment on every run.
The problem shows up during development: rebuilding the entire infrastructure every time you switch branches or reboot your laptop wastes time. The solution is persistence: writing state to disk that survives restarts.
It's just one environment variable: PERSISTENCE=1. Define it via docker-compose so it applies consistently:
services:
localstack:
image: localstack/localstack:latest
ports:
- "4566:4566"
environment:
- PERSISTENCE=1
- DEBUG=1
volumes:
- localstack_data:/var/lib/localstack
volumes:
localstack_data:Note the volume line: that's the real key. PERSISTENCE=1 tells the emulator to save state to /var/lib/localstack inside the container, and the Docker named volume keeps that directory alive after the container dies.
Tip
A named volume (localstack_data) is preferable to a bind mount for normal use: permission handling is automatic and doesn't depend on a host path. A bind mount is only needed if you want to inspect raw files from the host.
Data lives in /var/lib/localstack with per-service subdirectories: S3 objects, DynamoDB tables, Lambda state, and more. Verify from inside the container:
docker compose exec localstack ls -la /var/lib/localstack
docker compose exec localstack du -sh /var/lib/localstackIf you've ever used DynamoDB Local or moto, this pattern is familiar: stateful emulation is written to disk so it can be read back on the next startup.
Here's a simple test to prove state survives. Create a bucket, restart the container, then check whether the bucket is still there:
awslocal s3 mb s3://survives
docker compose restart localstack
awslocal s3 lsIf survives shows up, persistence is working. Make sure the emulator is back up with localstack status before running the verification command. The reverse case: turn off PERSISTENCE, do the same steps, and the bucket will be gone — proof that this env var is what controls state.
Persistence isn't always good. In CI/CD, keep state clean: every job needs a deterministic environment from scratch, and old state only pollutes test results. In local dev, turn persistence on for iteration convenience. The rule of thumb: persistence for humans, cleanliness for machines.
Warning
Never test empty-state scenarios (e.g. a brand-new bucket) with persistence on — leftover data from earlier tests can cause false passes. Turn persistence off or use a separate volume for your test suite.
Persistence protects state on one machine. But what if you want to share state with a colleague or move it to CI? LocalStack Pro's answer is Cloud Pods: a snapshot of the entire state uploaded to the cloud and reloadable on any instance.
Cloud Pods use the localstack pod CLI:
localstack pod save staging-ready
localstack pod list
localstack pod load staging-readyAfter pod save staging-ready, all buckets, tables, functions, and secrets are packaged into a single named snapshot. Another developer just runs pod load staging-ready to have an identical environment — no manual setup.
This pattern changes how teams work: before a big refactor, save a pod as a checkpoint; when things go wrong, reload and start from a clean state:
localstack pod save before-refactor
# ... eksperimen merusak state ...
localstack pod load before-refactorPods also carry metadata like name, description, and version history — very useful for sharing a "golden environment" across developers and pipelines.
Note
Cloud Pods require a Pro license configured via LOCALSTACK_API_KEY. Without a license, localstack pod will reject with an authentication message — use regular persistence for single-machine needs.
Summary of this episode:
PERSISTENCE=1 + the named volume localstack_data:/var/lib/localstack makes state survive restarts./var/lib/localstack inside the container, with per-service subfolders.localstack pod save and load it with localstack pod load.Your state is now safe. But there's one mystery unexplored all series: how do connections actually happen between clients, containers, and the emulator? In episode 13 we lift the curtain on networking and client integration — port 4566, Docker host vs bridge networks, and how to connect code to LocalStack from anywhere. See you there!