Skip to main content

What is file storage?

Laravel provides a powerful filesystem abstraction built on top of Flysystem. A single, consistent API works across local storage, SFTP, Amazon S3, and compatible services — switching drivers requires no changes to your application code.
Changing the driver doesn’t change your code. Use the local driver in development and S3 in production without touching your application logic.

Configuration

Filesystem configuration lives in config/filesystems.php. A disk is a named combination of a driver and a storage location.

The local driver

The local driver operates relative to the root directory defined in your filesystems configuration. The default root is storage/app/private:

Change the default disk

Set the FILESYSTEM_DISK environment variable to switch the default disk:
The public disk is for files that should be accessible from the web. By default it uses storage/app/public. To make those files accessible, create a symbolic link from public/storage to storage/app/public:
1

Create the symbolic link

2

Generate a URL to the file

After the link is created, use the asset helper to build a URL:
You can add extra symbolic links in the links array in config/filesystems.php:
Remove all symbolic links with:

Basic operations

Reading files

Writing files

When put fails it returns false by default. Set 'throw' => true on the disk configuration to throw an exception instead.

Deleting files

Download responses

Generating URLs

Regular URLs

The local driver returns a relative URL such as /storage/file.jpg. The s3 driver returns the full remote URL.

Temporary URLs

Generate a time-limited URL for private files. Available for the local and s3 drivers:
Pass additional S3 request parameters when needed:
For client-side direct uploads to S3, use temporaryUploadUrl:

Uploading files

Automatic file name (store)

Explicit file name (storeAs)

Upload to a specific disk

Using the Storage facade

getClientOriginalName() and getClientOriginalExtension() can be tampered with by the user. Use hashName() for the file name and extension() to determine the extension from the MIME type:

File visibility

Flysystem controls public and private access through visibility:
Upload and immediately mark a file as public:

Working with multiple disks

Amazon S3 configuration

Install the package

Environment variables

S3-compatible services such as DigitalOcean Spaces, Cloudflare R2, and Vultr Object Storage work with the s3 driver. Add an endpoint option pointing to the service’s URL:

File metadata

Directory operations

Testing

Use Storage::fake() to test file operations without touching a real disk:
UploadedFile::fake()->image() requires PHP’s GD extension.

Practical example: profile avatar upload

A complete controller that validates the upload, replaces an existing avatar, stores the file, and saves the path to the database:
Display the avatar in a template:
Last modified on March 29, 2026