<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl" -->

---
title: Object storage migrations with Laravel&#x27;s read-through...
description: Laravel 13 introduces a read-through filesystem driver that composes a primary and fallback disk to enable zero-downtime migrations between object storage...
canonical: https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Object storage migrations with Laravel&#x27;s read-through filesystem | daily.dev
og:description: Laravel 13 introduces a read-through filesystem driver that composes a primary and fallback disk to enable zero-downtime migrations between object storage...
og:url: https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl
og:image: https://api.daily.dev/og/posts/YEHIdeJpl.png
og:image:alt: Object storage migrations with Laravel&#x27;s read-through filesystem
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Object storage migrations with Laravel's read-through filesystem

**[Laravel](https://daily.dev/sources/laravel)** · 11 min read · 4 upvotes · 0 comments

## Summary

Laravel 13 introduces a read-through filesystem driver that composes a primary and fallback disk to enable zero-downtime migrations between object storage providers, such as S3 to R2. New writes go to primary, reads fall back to the legacy store and can be promoted (copied) into primary on access. The post covers the read path logic, filesystem operation routing, promotion failure modes (best-effort vs strict), streamed reads for large files, metadata caveats, delete semantics, egress cost implications, a full migration playbook, and alternative tools like Cloudflare Sippy, Super Slurper, rclone, and AWS DataSync.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://laravel.com/blog/object-storage-migrations-with-laravels-read-through-filesystem>

## Questions this post answers

### How do I migrate object storage from S3 to Cloudflare R2 without downtime in Laravel?

Laravel 13 provides a read-through filesystem driver that composes a primary disk (the new R2 destination) and a fallback disk (the old S3 source) behind the standard filesystem API. New writes go to primary immediately, while reads that miss on primary fall back to S3, and optionally copy (promote) the object into R2 during the same request so later reads use R2 directly.

_Teams planning a live storage cutover can follow ongoing Laravel storage-migration coverage on daily.dev._

### What is the difference between best-effort and strict promotion in Laravel's read-through filesystem driver?

Best-effort promotion (the default) returns the fallback contents to the caller even if the copy to primary fails, leaving the object on fallback for a later retry, and emits no error. Strict mode, enabled by setting throw_on_promotion_failure to true alongside the disk's throw option, turns a failed promotion copy into an UnableToReadFile error visible to application code.

_Developers configuring storage migrations can weigh these tradeoffs alongside other Laravel release notes on daily.dev._

### What are the egress cost implications of migrating from AWS S3 to Cloudflare R2 using a read-through driver?

A fallback read during migration can trigger up to two R2 existence checks, one S3 GET, and one logical R2 write, incurring AWS data transfer out charges once per object since R2 internet egress is free. R2 charges $4.50 per million Class A operations (writes) with 1 million free monthly, and $0.36 per million Class B operations (checks) with 10 million free monthly, while AWS egress starts around $0.09 per GB after the first 100 GB free.

_Anyone budgeting a cloud storage migration can track pricing and tooling changes like this on daily.dev._

## Similar posts on daily.dev

- [Storage Cache Store in Laravel 13.10.0](https://daily.dev/posts/storage-cache-store-in-laravel-13-10-0-r1lc1xf37) · Laravel News · 35 upvotes · 5 comments
- [Laravel S3 Image Proxy: Clean URLs with CDN Caching](https://daily.dev/posts/laravel-s3-image-proxy-clean-urls-with-cdn-caching-mxuxmu0hk) · Daniel Petrica · 7 upvotes · 1 comments
- [Cloudflare R2: object storage without egress fees](https://daily.dev/posts/cloudflare-r2-object-storage-without-egress-fees-facb8qxkw) · Flavio Copes · 0 upvotes · 0 comments

---

Tags: [#php](https://daily.dev/tags/php), [#laravel](https://daily.dev/tags/laravel), [#aws-s3](https://daily.dev/tags/aws-s3)

[View this post on daily.dev](https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Object storage migrations with Laravel's read-through filesystem","url":"https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl"},"datePublished":"2026-08-18T16:33:40.990Z","dateModified":"2026-09-14T06:30:29.760Z","description":"Laravel 13 introduces a read-through filesystem driver that composes a primary and fallback disk to enable zero-downtime migrations between object storage...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/7dcb3f4981fb4c56d23305c8d357babe?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/7dcb3f4981fb4c56d23305c8d357babe?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Laravel","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Laravel","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/1f77002e78e1486ab699e1b8e03d7fd2","url":"https://daily.dev/sources/laravel"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":4},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"php,laravel,aws-s3","timeRequired":"PT11M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Laravel","item":"https://daily.dev/sources/laravel"},{"@type":"ListItem","position":3,"name":"Object storage migrations with Laravel's read-through filesystem"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/object-storage-migrations-with-laravel-s-read-through-filesystem-yehidejpl#faq","mainEntity":[{"@type":"Question","name":"How do I migrate object storage from S3 to Cloudflare R2 without downtime in Laravel?","acceptedAnswer":{"@type":"Answer","text":"Laravel 13 provides a read-through filesystem driver that composes a primary disk (the new R2 destination) and a fallback disk (the old S3 source) behind the standard filesystem API. New writes go to primary immediately, while reads that miss on primary fall back to S3, and optionally copy (promote) the object into R2 during the same request so later reads use R2 directly. Teams planning a live storage cutover can follow ongoing Laravel storage-migration coverage on daily.dev."}},{"@type":"Question","name":"What is the difference between best-effort and strict promotion in Laravel's read-through filesystem driver?","acceptedAnswer":{"@type":"Answer","text":"Best-effort promotion (the default) returns the fallback contents to the caller even if the copy to primary fails, leaving the object on fallback for a later retry, and emits no error. Strict mode, enabled by setting throw_on_promotion_failure to true alongside the disk's throw option, turns a failed promotion copy into an UnableToReadFile error visible to application code. Developers configuring storage migrations can weigh these tradeoffs alongside other Laravel release notes on daily.dev."}},{"@type":"Question","name":"What are the egress cost implications of migrating from AWS S3 to Cloudflare R2 using a read-through driver?","acceptedAnswer":{"@type":"Answer","text":"A fallback read during migration can trigger up to two R2 existence checks, one S3 GET, and one logical R2 write, incurring AWS data transfer out charges once per object since R2 internet egress is free. R2 charges $4.50 per million Class A operations (writes) with 1 million free monthly, and $0.36 per million Class B operations (checks) with 10 million free monthly, while AWS egress starts around $0.09 per GB after the first 100 GB free. Anyone budgeting a cloud storage migration can track pricing and tooling changes like this on daily.dev."}}]}
```

