Your Replit app writes a file — a user upload, a generated PDF, a local SQLite database, a cache. It works. Then you push a new deploy, or the deployment restarts, and the file is just gone. No error, no warning — the file that was there yesterday isn’t there today.
Why this happens
It’s not a bug in your code, and it’s not something you configured wrong. It’s how Replit Deployments work by design: every deploy builds a fresh filesystem from your project’s source, and any file your app writes at runtime — not committed as part of your code — doesn’t survive to the next deploy. Replit’s own troubleshooting docs state it directly: “The file system in published apps is not persistent and resets every time you publish” — and that applies across deployment types, Autoscale and Reserved VM included.
The reason it’s easy to miss: the Replit workspace (where you build and where the Agent runs) has a persistent filesystem — write a file there and it sticks around between sessions. A deployment is a separate, freshly-built instance. If your app’s storage logic is “write to a local path” — a common pattern for handling uploads or caching results, including code an Agent generates without being told otherwise — it’ll work fine the moment you deploy, and quietly lose everything on the next one. You won’t notice until the second deploy, which is exactly when it stops looking like a fluke.
How to confirm this is what’s happening
- Write a file at runtime through your actual app (upload a test file, trigger whatever generates the data) on the live deployed URL — not the workspace preview.
- Confirm the file is retrievable on that same deployment.
- Trigger a new deploy (even a no-op one — redeploy with no code changes) and check for that file again on the live URL.
- If it’s gone after step 3 but nothing in your app logged an error, this is the filesystem reset, not a separate bug in your upload/save code.
The fix
Move anything that needs to survive a redeploy off the app’s local filesystem — this is what Replit’s own docs point you toward instead:
- For files (uploads, generated documents, images, etc.): use Replit Object Storage. Buckets live outside the deployment’s filesystem, so they persist across every redeploy and are shared between your workspace and every deployment of the app. Swapping a local file write for an Object Storage upload/download call is a small integration change, not a rewrite.
- For structured data (user records, app state, anything you’d otherwise put in a JSON file or a SQLite file on disk): use a real database — Replit’s built-in SQL Database or an external Postgres — instead of a file on the local filesystem. A database is a separate service the deployment connects to, not part of the filesystem that gets rebuilt on every publish.
- If the storage code was written by the Agent (or by you, following its lead), check specifically for local file writes —
fs.writeFile,open(..., 'w'), or any local path used as the actual source of truth for user data. That’s the pattern to replace, not just “the one file that went missing.” - If what you’re storing is only a cache and not data you can’t afford to lose, accepting the reset and rebuilding on cold start is a valid choice — but make it deliberately, rather than discovering it’s the default behavior after real data disappears.
How to verify it’s actually fixed
Testing on the workspace preview tells you nothing here — the workspace filesystem was never the problem. Verify against a real deploy cycle:
- Deploy with the storage fix in place.
- Write or upload the same test data through the live app.
- Trigger a second redeploy (no code change needed) — this is the step that exposed the bug originally.
- Confirm the data is still there on the live URL after that second deploy. One successful deploy isn’t proof of anything, since the pattern looks fine right up until the next publish — the second deploy is the real check.
Comments
Sign in to join the conversation.
No comments yet — be the first.