<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9" -->

---
title: Laravel&#x27;s lazy filesystem migration trick has a...
description: Laravel 13.26 ships a new read-through filesystem driver that pairs a primary disk with a fallback disk, letting apps migrate storage backends (like S3 to R2)...
canonical: https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Laravel&#x27;s lazy filesystem migration trick has a resurrection bug | daily.dev
og:description: Laravel 13.26 ships a new read-through filesystem driver that pairs a primary disk with a fallback disk, letting apps migrate storage backends (like S3 to R2)...
og:url: https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9
og:image: https://api.daily.dev/og/posts/DbmSXRJJ9.png
og:image:alt: Laravel&#x27;s lazy filesystem migration trick has a resurrection bug
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.

# Laravel's lazy filesystem migration trick has a resurrection bug

**[Trends](https://daily.dev/sources/trends)** · 3 min read · 7 upvotes · 0 comments

## Summary

Laravel 13.26 ships a new read-through filesystem driver that pairs a primary disk with a fallback disk, letting apps migrate storage backends (like S3 to R2) gradually instead of via a bulk sync: reads fall back to the old store and promote files to primary, while writes and deletes only touch primary. Analysis pieces following the release surface a nasty edge case: deleting a promoted file doesn't remove it from the fallback disk, so the next read resurrects and re-promotes it. Other details covered include best-effort vs strict promotion modes, streaming for large files, metadata caveats, and a copy=>false option for read-only access useful in local dev seeded from production snapshots.

## Content

Taylor Otwell shipped a Turbopuffer driver for Scout last week. This week, at Aaron Francis's suggestion, he shipped something more broadly useful: a "read-through" filesystem driver for Laravel 13.26. His own framing was casual: "Really useful for graceful filesystem migrations. What's next week?" But the write-ups that followed dug into what makes this actually clever, and where it bites.

The core idea: pair a primary disk with a fallback disk. Reads check primary first, fall back to the old store if missing, and quietly copy the file into primary on the way through. Writes, deletes, and directory listings only ever touch primary. The upshot is that migrating from, say, an old S3 bucket to R2 stops being an all-or-nothing bulk sync. Hot files migrate themselves the first time someone touches them. Cold files just sit in the old bucket until you're ready to deal with them, or never, if nobody ever needs them again.

That's the pitch, and it's a good one for anyone who's sweated through a multi-terabyte bucket migration with strict downtime windows. But the deeper analysis pieces flag a genuinely weird edge case: because deletes only hit primary, deleting a file that's already been promoted doesn't actually kill it. The fallback disk still has the old copy, so the very next read resurrects it from the legacy store and re-promotes it to primary. A file you thought you deleted just comes back from the dead.  That's the kind of bug you find in production at 2am, not in a demo.

The write-ups also cover the less glamorous but equally important stuff: promotion can be best-effort or strict depending on how much you trust the failure mode, large files get streamed rather than loaded into memory, and metadata handling has its own caveats worth reading before you rely on it. There's also a `copy=>false` option from a separate PR that lets you read through the fallback without promoting anything, handy for local dev environments seeded from a production snapshot where you don't want your laptop slowly hoovering up the entire bucket.

Worth noting this isn't solving a new problem. Cloudflare's Sippy, Rclone, AWS DataSync, and Backblaze's Super Slurper already do bucket-to-bucket migration. What's different here is that Laravel's version lives inside your app's existing filesystem abstraction, so you don't need a separate migration tool running alongside your deploy. Whether that convenience is worth the delete-resurrection footgun is going to depend entirely on how careful your team is about reading the docs before flipping the switch.

## Questions this post answers

### What does Laravel 13.26's read-through filesystem driver do?

It pairs a primary disk with a fallback disk so reads check primary first, fall back to the old store if a file is missing, and copy that file into primary on the way through. Writes, deletes, and directory listings only ever touch primary, letting apps migrate storage backends like S3 to R2 gradually instead of doing an all-or-nothing bulk sync.

_Teams planning a storage migration can track how Laravel's read-through driver evolves through daily.dev._

### Why does a deleted file come back in Laravel's read-through filesystem driver?

Because deletes only ever hit the primary disk, deleting a file that has already been promoted from the fallback disk does not remove it from that fallback store. The next read for that file finds it still present on the fallback disk and re-promotes it back into primary, effectively resurrecting a file that was supposedly deleted.

_Developers relying on Laravel's filesystem abstraction can follow bug reports and workarounds like this on daily.dev._

### What does the copy=>false option do in Laravel's read-through filesystem driver?

It lets a read pass through to the fallback disk without promoting the file into primary storage. This is useful for local development environments seeded from a production snapshot, where you want read access to production data without your laptop gradually pulling the entire bucket down to local disk.

_Developers configuring local dev environments against production data can find practical setup details 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

---

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/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9)

```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":"Laravel's lazy filesystem migration trick has a resurrection bug","url":"https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9"},"datePublished":"2026-08-19T14:15:18.360Z","dateModified":"2026-09-13T19:27:32.205Z","description":"Laravel 13.26 ships a new read-through filesystem driver that pairs a primary disk with a fallback disk, letting apps migrate storage backends (like S3 to R2)...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6ae95943595e5b77241fe4756f8eb2f9?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6ae95943595e5b77241fe4756f8eb2f9?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Trends","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":"Trends","logo":"https://media.daily.dev/image/upload/s--ZfSp3asX--/f_auto,q_auto/v1780996004/logos/trends?_a=BAMAMiWQ0","url":"https://daily.dev/sources/trends"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":7},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"php,laravel,aws-s3","timeRequired":"PT3M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Trends","item":"https://daily.dev/sources/trends"},{"@type":"ListItem","position":3,"name":"Laravel's lazy filesystem migration trick has a resurrection bug"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/laravel-s-lazy-filesystem-migration-trick-has-a-resurrection-bug-dbmsxrjj9#faq","mainEntity":[{"@type":"Question","name":"What does Laravel 13.26's read-through filesystem driver do?","acceptedAnswer":{"@type":"Answer","text":"It pairs a primary disk with a fallback disk so reads check primary first, fall back to the old store if a file is missing, and copy that file into primary on the way through. Writes, deletes, and directory listings only ever touch primary, letting apps migrate storage backends like S3 to R2 gradually instead of doing an all-or-nothing bulk sync. Teams planning a storage migration can track how Laravel's read-through driver evolves through daily.dev."}},{"@type":"Question","name":"Why does a deleted file come back in Laravel's read-through filesystem driver?","acceptedAnswer":{"@type":"Answer","text":"Because deletes only ever hit the primary disk, deleting a file that has already been promoted from the fallback disk does not remove it from that fallback store. The next read for that file finds it still present on the fallback disk and re-promotes it back into primary, effectively resurrecting a file that was supposedly deleted. Developers relying on Laravel's filesystem abstraction can follow bug reports and workarounds like this on daily.dev."}},{"@type":"Question","name":"What does the copy=>false option do in Laravel's read-through filesystem driver?","acceptedAnswer":{"@type":"Answer","text":"It lets a read pass through to the fallback disk without promoting the file into primary storage. This is useful for local development environments seeded from a production snapshot, where you want read access to production data without your laptop gradually pulling the entire bucket down to local disk. Developers configuring local dev environments against production data can find practical setup details like this on daily.dev."}}]}
```

