Langflow Storage Options and Factory Pattern: Local vs S3 Configuration Guide
Langflow supports pluggable storage backends including local file system and AWS S3, selected at runtime via a factory pattern that instantiates the appropriate service based on the storage_type configuration setting.
Langflow provides a flexible storage architecture for managing binary assets such as uploaded files, generated PDFs, and images. The system implements a factory pattern that abstracts storage implementation details, allowing developers to switch between local disk storage and cloud object storage without modifying application logic. This guide examines the available Langflow storage options and explains how the storage factory pattern orchestrates backend selection according to the langflow-ai/langflow source code.
Available Langflow Storage Backends
Langflow currently supports two primary storage implementations for binary asset persistence. The concrete implementation is determined by the storage_type field defined in src/backend/base/langflow/services/settings/base.py.
Local File System Storage
The local storage backend writes files directly to the host file system. By default, assets are stored in a cache directory under the user's home folder, configurable via the config_dir setting. This implementation is defined in src/backend/base/langflow/services/storage/local.py and serves as the default fallback when no specific storage type is configured or when an unsupported type is specified.
AWS S3 Object Storage
The s3 backend enables cloud object storage using AWS S3 buckets. Implemented in src/backend/base/langflow/services/storage/s3.py, this service utilizes aioboto3 for asynchronous operations. Configuration requires the object_storage_bucket_name parameter, with optional object_storage_prefix for key namespacing and object_storage_tags for metadata classification.
Configuration Settings
The global settings model in src/backend/base/langflow/services/settings/base.py controls storage behavior:
storage_type: str = "local"
"""Storage type for file storage. Defaults to 'local'. Supports 'local' and 's3'."""
Related S3 configuration parameters include object_storage_bucket_name, object_storage_prefix, and object_storage_tags. Environment variables prefixed with LANGFLOW_ override these settings (e.g., LANGFLOW_STORAGE_TYPE=s3).
How the Langflow Storage Factory Pattern Works
The storage architecture follows the factory pattern implemented throughout the LFX service layer. This design decouples service instantiation from business logic, enabling runtime backend selection.
The ServiceFactory Base Class
All service factories inherit from the abstract ServiceFactory defined in src/lfx/src/lfx/services/factory.py:
class ServiceFactory(ABC):
@abstractmethod
def create(self, **kwargs) -> "Service":
"""Create a service instance."""
This contract ensures consistent instantiation across Langflow's service layer.
StorageServiceFactory Implementation
The concrete factory resides in src/backend/base/langflow/services/storage/factory.py. The StorageServiceFactory.create() method implements runtime selection logic:
class StorageServiceFactory(ServiceFactory):
def __init__(self) -> None:
super().__init__(StorageService)
@override
def create(self, session_service: SessionService, settings_service: SettingsService):
storage_type = settings_service.settings.storage_type
if storage_type.lower() == "local":
from .local import LocalStorageService
return LocalStorageService(session_service, settings_service)
if storage_type.lower() == "s3":
from .s3 import S3StorageService
return S3StorageService(session_service, settings_service)
logger.warning(f"Storage type {storage_type} not supported. Using local storage.")
from .local import LocalStorageService
return LocalStorageService(session_service, settings_service)
If the storage_type value is unrecognized, the factory logs a warning and falls back to LocalStorageService.
Service Registration and Retrieval
The ServiceManager registers factories on application startup. Components retrieve the storage instance via get_storage_service() in src/lfx/src/lfx/services/deps.py:
def get_storage_service() -> StorageServiceProtocol | None:
"""Retrieves the storage service instance."""
from lfx.services.schema import ServiceType
return get_service(ServiceType.STORAGE_SERVICE)
The manager lazily invokes the factory's create method upon first request, caching the instance for subsequent calls.
Abstract StorageService Interface
Both concrete implementations inherit from StorageService defined in src/backend/base/langflow/services/storage/service.py. This abstract base class standardizes operations such as save_file(), get_file(), and list_files(). Because LocalStorageService and S3StorageService implement this identical API, the remainder of the codebase remains storage-agnostic.
Practical Implementation Examples
Configuring Your Storage Backend
Define storage settings in settings.yaml or via environment variables:
storage_type: s3
object_storage_bucket_name: my-bucket
object_storage_prefix: flow-assets
object_storage_tags:
project: langflow
env: production
For local development, set storage_type: local or omit the field to use the default.
Using the Storage Service in Application Code
Access the storage service through the dependency helper regardless of backend:
from lfx.services.deps import get_storage_service
async def store_uploaded_image(flow_id: str, filename: str, data: bytes):
storage = get_storage_service()
if storage is None:
raise RuntimeError("No storage service available")
await storage.save_file(flow_id, filename, data)
async def download_image(flow_id: str, filename: str) -> bytes:
storage = get_storage_service()
return await storage.get_file(flow_id, filename)
This code functions identically for both local and S3 backends due to the shared interface.
Runtime Backend Detection
Diagnostics may require identifying the active backend:
from lfx.services.deps import get_storage_service
storage = get_storage_service()
print(type(storage).__name__) # Outputs: LocalStorageService or S3StorageService
Summary
- Langflow storage options include local file system and AWS S3 backends, configurable via the
storage_typesetting insrc/backend/base/langflow/services/settings/base.py. - The storage factory pattern centers on
StorageServiceFactoryinsrc/backend/base/langflow/services/storage/factory.py, which instantiates the appropriate service at runtime based on configuration. - Service instantiation follows the abstract
ServiceFactorycontract fromsrc/lfx/src/lfx/services/factory.py, ensuring consistency across the service layer. - Uniform API access is provided through
get_storage_service()insrc/lfx/src/lfx/services/deps.py, returning eitherLocalStorageServiceorS3StorageServiceboth inheriting from the abstractStorageService. - Automatic fallback to local storage occurs when an unsupported storage type is specified, with a warning logged for visibility.
Frequently Asked Questions
What storage types does Langflow support?
Langflow natively supports local file system storage and AWS S3 object storage. The local backend stores files in a configurable directory on disk, while the S3 backend persists assets to specified buckets using asynchronous boto3 operations. Both implementations are located in src/backend/base/langflow/services/storage/ and share a common interface defined in service.py.
How do I switch from local storage to S3 in Langflow?
Set the storage_type configuration value to "s3" and provide the required object_storage_bucket_name parameter. These settings reside in src/backend/base/langflow/services/settings/base.py and can be configured via settings.yaml or environment variables prefixed with LANGFLOW_. Optional parameters include object_storage_prefix for key namespacing and object_storage_tags for metadata.
Where is the storage factory pattern implemented in Langflow?
The factory pattern implementation spans multiple files: the abstract ServiceFactory base class is defined in src/lfx/src/lfx/services/factory.py, while the concrete StorageServiceFactory resides in src/backend/base/langflow/services/storage/factory.py. This factory reads the storage_type setting and returns the appropriate LocalStorageService or S3StorageService instance, falling back to local storage if the type is unrecognized.
Does Langflow storage support custom or third-party backends?
While the current codebase only includes local and S3 implementations in src/backend/base/langflow/services/storage/, the architecture supports extension through the factory pattern. Developers could implement additional backends by creating a new class inheriting from StorageService in src/backend/base/langflow/services/storage/service.py and extending StorageServiceFactory.create() to instantiate the new implementation based on a custom storage_type value.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →