Filesystem Storage

Filesystem storage provides a simple, lightweight alternative to etcd for storing FlagFlow data, ideal for small companies and single-instance deployments

Overview

FlagFlow 1.5.0 introduces filesystem storage through the new PersistentService abstraction layer as an alternative to etcd. This storage option is perfect for:

  • Small companies without heavy infrastructure requirements
  • Development and testing environments where simplicity is preferred
  • Single-instance deployments that don't require distributed storage
  • Organizations wanting to avoid etcd complexity and maintenance overhead

💡 When to Choose Filesystem Storage

Choose filesystem storage when you need a simple, reliable storage solution without the complexity of distributed systems. It's perfect for teams that want to get started quickly with FlagFlow or don't need real-time synchronization across multiple instances.

Filesystem vs etcd Comparison

FeatureFilesystem Storageetcd Storage
Setup ComplexitySimple - No additional servicesModerate - Requires etcd installation
Real-time SyncDelayed - Auto refresh with few milliseconds delay across replicasExcellent - Automatic watch-based updates
PerformanceFast - Direct file system accessFast - Optimized for key-value operations
ScalabilityLimited - Works with replicas but sync has few milliseconds delayDistributed - Multiple nodes with clustering
Data PersistenceReliable - Direct filesystem storageReliable - etcd's durability guarantees
Resource UsageLow - No additional processesHigher - etcd server resources
Ideal ForSmall teams, development, single instancesProduction, distributed systems, high availability

Configuration

To use filesystem storage, simply omit the etcd configuration. FlagFlow's PersistentService abstraction will automatically detect the absence of etcd settings and initialize the filesystem storage engine with full type safety and Zod schema validation.

No etcd Configuration Required Environment Variables

When these etcd environment variables are not set or empty, FlagFlow uses filesystem storage:

Environment Configuration for Filesystem Storage
# These should NOT be set for filesystem storage
# ETCD_SERVER=
# ETCD_USERNAME=
# ETCD_PASSWORD=
# ETCD_NAMESPACE=

# Other FlagFlow configuration remains the same
LOGLEVEL=info
ENVIRONMENT=production

Data Volume Mount Critical Requirement

⚠️ Critical: When using filesystem storage, you must mount the /data volume to persist data between container restarts. Without this mount, all your feature flags and configuration will be lost when the container stops or new version installed.

FlagFlow stores all data in the /data directory inside the container. This includes:

  • Feature flag definitions and values
  • User accounts and permissions
  • Session data
  • Configuration settings

Storage Architecture

FlagFlow 1.5.0 introduces a new dual-engine persistence architecture that supports both etcd and filesystem storage through the PersistentService abstraction layer:

🏗️ PersistentService Abstraction

The service layer now supports pluggable persistence engines, allowing seamless switching between storage types without changing application logic.

  • Unified API for all storage operations
  • Type-safe persistence with Zod schema validation
  • Real-time flag watching in both storage modes
  • Consistent behavior across storage engines

📁 Filesystem Storage Engine

The filesystem storage engine provides robust local storage with automatic file watching and change detection for real-time updates.

  • JSON-based data storage for transparency
  • File system watching for real-time synchronization
  • Atomic write operations for data consistency
  • Enhanced type safety throughout persistence layer

Docker Setup

Docker Compose Recommended

docker-compose.yml
version: '3.8'
services:
  flagflow:
    image: flagflow/flagflow:latest
    container_name: flagflow
    ports:
      - "3000:3000"
    # CRITICAL: Mount /data volume for persistence
    volumes:
      - flagflow-data:/data
    environment:
      - LOGLEVEL=info
      - ENVIRONMENT=production
      # Notice: NO etcd configuration - filesystem storage will be used automatically
      - SESSION_USERS_ENABLED=true
      - SESSION_DEFAULT_USERNAME=admin
      - SESSION_DEFAULT_PASSWORD=change_this_password
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  flagflow-data:
    driver: local

Docker Run Command Alternative

Docker Run with Filesystem Storage
# Create a named volume for data persistence
docker volume create flagflow-data

# Run FlagFlow with filesystem storage
docker run -d \
  --name flagflow \
  -p 3000:3000 \
  -v flagflow-data:/data \
  -e LOGLEVEL=info \
  -e ENVIRONMENT=production \
  -e SESSION_USERS_ENABLED=true \
  -e SESSION_DEFAULT_USERNAME=admin \
  -e SESSION_DEFAULT_PASSWORD=change_this_password \
  --restart unless-stopped \
  flagflow/flagflow:latest

Kubernetes Setup

For Kubernetes deployments, use a PersistentVolumeClaim to ensure data persistence:

kubernetes-filesystem.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: flagflow-data
  namespace: flagflow
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: flagflow
  namespace: flagflow
spec:
  replicas: 1  # Single replica recommended for filesystem storage
  selector:
    matchLabels:
      app: flagflow
  template:
    metadata:
      labels:
        app: flagflow
    spec:
      containers:
      - name: flagflow
        image: flagflow/flagflow:latest
        ports:
        - containerPort: 3000
        # Mount the persistent volume to /data
        volumeMounts:
        - name: data
          mountPath: /data
        env:
        - name: LOGLEVEL
          value: "info"
        - name: ENVIRONMENT
          value: "production"
        - name: SESSION_USERS_ENABLED
          value: "true"
        - name: SESSION_DEFAULT_USERNAME
          value: "admin"
        - name: SESSION_DEFAULT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: flagflow-secret
              key: admin-password
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: flagflow-data

Data Structure

FlagFlow stores data in a structured directory format within /data:

Data Directory Structure
/data/
├── flag/
│   ├── feature_a
│   ├── feature_b
│   └── group/
│       └── nested_feature
├── user/
│   ├── admin
│   └── developer
└── session/
    ├── session_1
    └── session_2

Each file contains JSON data representing the corresponding FlagFlow entity. This structure provides:

  • Transparency: Data is stored in human-readable JSON files
  • Backup-friendly: Easy to backup and restore using standard filesystem tools
  • Version control: Can be managed with git for configuration as code
  • Debugging: Direct file access for troubleshooting

Backup and Restore

Filesystem-based Backup Simple and Reliable

One advantage of filesystem storage is the simplicity of backup and restore operations:

Backup and Restore Commands
# Backup the entire data directory
docker run --rm -v flagflow-data:/data -v $(pwd):/backup alpine:latest \
  tar czf /backup/flagflow-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .

# Restore from backup
docker run --rm -v flagflow-data:/data -v $(pwd):/backup alpine:latest \
  tar xzf /backup/flagflow-backup-20241201-143000.tar.gz -C /data

Scheduled Backup Strategy Automated Backups

Set up automated backups using cron or Kubernetes CronJobs:

Kubernetes Backup CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
  name: flagflow-backup
  namespace: flagflow
spec:
  schedule: "0 2 * * *"  # Daily at 2 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: alpine:latest
            command:
            - /bin/sh
            - -c
            - |
              apk add --no-cache aws-cli
              tar czf /tmp/flagflow-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
              aws s3 cp /tmp/flagflow-backup-*.tar.gz s3://your-backup-bucket/flagflow/
            volumeMounts:
            - name: data
              mountPath: /data
              readOnly: true
          volumes:
          - name: data
            persistentVolumeClaim:
              claimName: flagflow-data
          restartPolicy: OnFailure

Limitations and Considerations

🔄 Multi-Instance Synchronization

When running multiple FlagFlow instances with filesystem storage, changes made in one instance will be visible in others with a few milliseconds delay due to file system watching. The PersistentService abstraction ensures consistent behavior, though this is slower than etcd's instant distributed watch-based updates.

📈 Scaling Considerations

Filesystem storage works best with single-instance deployments. If you need to scale horizontally with real-time synchronization, consider migrating to etcd storage.

✅ Perfect for Small Teams

For teams with 1-50 developers and simple deployment requirements, filesystem storage provides excellent reliability with minimal operational overhead.

Migration Path

If you start with filesystem storage and later need etcd's distributed capabilities, FlagFlow provides migration tools:

  • Export: Use the /migration/export endpoint to create a backup
  • Setup etcd: Install and configure etcd for your new deployment
  • Import: Use the migration tools to import your data into the etcd-based FlagFlow instance

📚 For detailed migration instructions, see the Migration Documentation.

© 2025 FlagFlow All Rights Reserved. llms.txt