<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marx Oblan III</title>
    <description>The latest articles on DEV Community by Marx Oblan III (@marx_oblaniii_0c5d9e3fb2).</description>
    <link>https://dev.to/marx_oblaniii_0c5d9e3fb2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1664170%2F04b81d0c-5080-4681-a26d-8e30454601a6.jpeg</url>
      <title>DEV Community: Marx Oblan III</title>
      <link>https://dev.to/marx_oblaniii_0c5d9e3fb2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marx_oblaniii_0c5d9e3fb2"/>
    <language>en</language>
    <item>
      <title>Why I ditched "Soft Deletes" for S3: Building a Physical Purge Workflow</title>
      <dc:creator>Marx Oblan III</dc:creator>
      <pubDate>Mon, 09 Mar 2026 21:57:53 +0000</pubDate>
      <link>https://dev.to/marx_oblaniii_0c5d9e3fb2/why-i-ditched-soft-deletes-for-s3-building-a-physical-purge-workflow-4ipk</link>
      <guid>https://dev.to/marx_oblaniii_0c5d9e3fb2/why-i-ditched-soft-deletes-for-s3-building-a-physical-purge-workflow-4ipk</guid>
      <description>&lt;p&gt;As a Laravel dev, I’ve relied on SoftDeletes for years. It’s great for accidentally deleted users or blog posts, but it’s a massive liability when you’re handling sensitive files like .env configurations, private keys, or PII.&lt;/p&gt;

&lt;p&gt;I started auditing how the "big" file-sharing services handle data, and I realized most of them are just flipping a deleted_at flag in a DB. The actual object stays in an S3 bucket for 30 days "just in case."&lt;/p&gt;

&lt;p&gt;I got a bit paranoid about this "ghost data" sitting in cloud storage, so I spent my weekends building FortByte.io.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjix09xr9d66ue3coq303.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjix09xr9d66ue3coq303.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Goal: True Zero-Persistence&lt;br&gt;
I wanted a "burn after reading" workflow where the second a link expires (or is viewed), the S3 object is physically and permanently wiped. No 30-day retention, no "trash" folder, and no recovery.&lt;/p&gt;

&lt;p&gt;The Stack:&lt;br&gt;
Backend: Laravel &lt;/p&gt;

&lt;p&gt;Frontend: Inertia.js/Vue.js&lt;/p&gt;

&lt;p&gt;Storage: S3&lt;/p&gt;

&lt;p&gt;Infrastructure: DigitalOcean&lt;/p&gt;

&lt;p&gt;How it works:&lt;br&gt;
Instead of just hiding the record, I’ve set up a triggered workflow. When a file hits its expiry limit:&lt;/p&gt;

&lt;p&gt;The database record is purged.&lt;/p&gt;

&lt;p&gt;An S3 DeleteObject command is issued immediately.&lt;/p&gt;

&lt;p&gt;Any temporary logs associated with the transfer are cleared.&lt;/p&gt;

&lt;p&gt;I did include an optional 30-day retention toggle for users who actually want a safety net, but by default, "Delete" actually means "Gone."&lt;/p&gt;

&lt;p&gt;Why I built it:&lt;br&gt;
It was originally just to solve my own workflow headaches when sending keys to clients, but I’ve made it live and included a free tier for anyone else who is tired of leaving a digital trail.&lt;/p&gt;

&lt;p&gt;I’d honestly love some feedback from other devs on the UI or the purging logic. If you've ever dealt with the "ghost data" problem in your own apps, how did you handle it?&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>webdev</category>
      <category>security</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
