<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://blog.cloudstic.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.cloudstic.com/" rel="alternate" type="text/html" /><updated>2026-03-18T13:17:56+00:00</updated><id>https://blog.cloudstic.com/feed.xml</id><title type="html">The Cloudstic Engineering Blog</title><subtitle>Engineering insights, cloud architecture, and technical deep dives from the Cloudstic team.</subtitle><author><name>Cloudstic</name></author><entry><title type="html">Reading a Native Backup Through –debug</title><link href="https://blog.cloudstic.com/2026/03/16/reading-a-native-backup-through-debug/" rel="alternate" type="text/html" title="Reading a Native Backup Through –debug" /><published>2026-03-16T00:00:00+00:00</published><updated>2026-03-16T00:00:00+00:00</updated><id>https://blog.cloudstic.com/2026/03/16/reading-a-native-backup-through-debug</id><content type="html" xml:base="https://blog.cloudstic.com/2026/03/16/reading-a-native-backup-through-debug/"><![CDATA[<p>When I build this kind of tool, I like to look at the debug output.</p>

<p>It is the easiest way to see if the architecture really does what it claims.</p>

<p>In the case of a native Google Drive backup, I want to verify a few things:</p>

<ul>
  <li>the repository is initialized cleanly</li>
  <li>the first backup performs a full scan</li>
  <li>the next backup does not scan the whole drive again</li>
  <li>small objects are not written one by one to the object store</li>
</ul>

<p>If you want the general explanation first, you can read <a href="/2026/03/04/google-drive-is-not-a-backup-heres-how-to-fix-that/">Google Drive Is Not a Backup (Here’s How to Fix That)</a> and <a href="/2026/03/16/why-sync-is-not-backup-technically/">Why Sync Is Not Backup, Technically</a>.</p>

<p>This article is only about the logs.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>Before reproducing the debug runs below, make sure you have:</p>

<ul>
  <li>the Cloudstic CLI installed by following the <a href="https://docs.cloudstic.com/installation">installation guide</a></li>
  <li>a repository destination configured and reachable</li>
  <li>Google Drive authentication available for the <code class="language-plaintext highlighter-rouge">gdrive-changes</code> source</li>
  <li><code class="language-plaintext highlighter-rouge">--debug</code> output enabled on a test setup rather than on production data you do not want to inspect live</li>
</ul>

<h2 id="repository-initialization">Repository Initialization</h2>

<p>Here is a representative <code class="language-plaintext highlighter-rouge">cloudstic init --debug</code> run:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cloudstic init --debug
[store #1] GET    config                                              2074.6ms err=NoSuchKey
[store #2] LIST   keys/                                                 99.4ms
[store #3] PUT    keys/kms-platform-default                            119.8ms 311B
[store #4] PUT    config                                               123.6ms 63B
Created new encryption key slots.
Repository initialized (encrypted: true).
</code></pre></div></div>

<p>This is short, but it already tells a lot.</p>

<p><code class="language-plaintext highlighter-rouge">GET config</code> confirms that the repository does not exist yet.</p>

<p><code class="language-plaintext highlighter-rouge">LIST keys/</code> checks the existing key slots.</p>

<p><code class="language-plaintext highlighter-rouge">PUT keys/...</code> creates the encryption slot.</p>

<p><code class="language-plaintext highlighter-rouge">PUT config</code> writes the repository marker.</p>

<p>So before backing up any file, the repository has an identity and key material.</p>

<h2 id="first-backup">First Backup</h2>

<p>Now the first Google Drive backup:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cloudstic backup -source gdrive-changes --debug
[store #8] GET    index/snapshots                                      101.0ms err=NoSuchKey
[hamt] get node/... hit staging (158 bytes)
...
Scanning             ... done! [20 in 790ms]
[store #14] PUT    chunk/d2667...                                      807.7ms 1.2MB
[store #15] PUT    chunk/3134f...                                      261.2ms 587.8KB
...
Uploading            ... done! [45.65MB in 5.995s]
[store #51] PUT    packs/d7596...                                      191.9ms 1.2MB
Backup complete. Snapshot: snapshot/6f70aa...
</code></pre></div></div>

<p>The main points are simple.</p>

<p><code class="language-plaintext highlighter-rouge">GET index/snapshots</code> returns <code class="language-plaintext highlighter-rouge">NoSuchKey</code>, so there is no previous snapshot.</p>

<p>This means the source has to perform a full scan. This is expected, even with <code class="language-plaintext highlighter-rouge">gdrive-changes</code>.</p>

<p><code class="language-plaintext highlighter-rouge">PUT chunk/...</code> means new file data is uploaded.</p>

<p><code class="language-plaintext highlighter-rouge">PUT packs/...</code> means Cloudstic is bundling small metadata objects into packfiles instead of writing thousands of tiny objects individually.</p>

<p>That point is important for object stores like S3. It reduces API calls and makes metadata reads cheaper on later runs.</p>

<h2 id="what-the-first-snapshot-gives-you">What the First Snapshot Gives You</h2>

<p>After this first backup, Cloudstic has more than just stored bytes.</p>

<p>It has created a real snapshot containing:</p>

<ul>
  <li>references to data chunks</li>
  <li>metadata nodes</li>
  <li>source identity</li>
  <li>backup metadata</li>
  <li>for an incremental source, the change token for the next run</li>
</ul>

<p>This is what makes the second backup interesting.</p>

<h2 id="second-backup">Second Backup</h2>

<p>Here is a representative second run with no changes:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cloudstic backup -source gdrive-changes --debug
[store #8] GET    index/snapshots                                      115.8ms 350B
[store #10] GET   packs/d7596...                                       729.8ms 1.2MB
Scanning (incremental) ... done! [0 in 212ms]
...
Added to the repository: 286 B (315 B compressed)
Processed 0 entries in 1s
Snapshot 3eb699... saved
</code></pre></div></div>

<p>This is the part I care about most.</p>

<p><code class="language-plaintext highlighter-rouge">Scanning (incremental) ... done! [0 in 212ms]</code></p>

<p>This means Cloudstic reused the previous snapshot, read the stored change token, asked Google Drive for the delta, and found nothing to process.</p>

<p>So it did not walk the whole tree again.</p>

<p>This is the practical difference between a native integration and a mounted drive scanned like a local filesystem.</p>

<h2 id="why-get-packs-is-good-news">Why <code class="language-plaintext highlighter-rouge">GET packs/...</code> Is Good News</h2>

<p>On the second run, there is still a metadata read:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[store #10] GET   packs/d7596...                                       729.8ms 1.2MB
</code></pre></div></div>

<p>This is normal.</p>

<p>The engine still needs metadata to reason about the previous state.</p>

<p>The good sign is that it fetches a packfile, not hundreds of tiny metadata objects.</p>

<p>This is exactly why packfiles exist.</p>

<h2 id="why-a-no-change-backup-still-writes-a-few-bytes">Why a No-Change Backup Still Writes a Few Bytes</h2>

<p>This line is also expected:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Added to the repository: 286 B (315 B compressed)
</code></pre></div></div>

<p>Even if the files did not change, the backup still produces a new checkpoint.</p>

<p>So Cloudstic writes a very small amount of metadata for the new snapshot and the updated incremental state.</p>

<p>That is what you want: a new restore point without re-uploading the source.</p>

<h2 id="what-the-logs-show">What the Logs Show</h2>

<p>For me, the logs validate four things:</p>

<ul>
  <li>the first run is a normal full backup</li>
  <li>the second run uses Google Drive’s native change tracking</li>
  <li>the repository stores immutable snapshots</li>
  <li>packfiles avoid object-store overhead on small metadata</li>
</ul>

<p>This is why the second backup can complete in about a second.</p>

<p>It is not doing the same work again. It is using the source’s own incremental mechanism and reusing the existing structure.</p>

<p>That is also why I find <code class="language-plaintext highlighter-rouge">--debug</code> useful. It lets you see the difference between a real native backup flow and a tool that only looks native from the outside.</p>

<p>If you want to try this yourself, start with the <a href="https://docs.cloudstic.com/installation">Cloudstic installation guide</a>.</p>]]></content><author><name>loichrn</name></author><category term="backup" /><category term="architecture" /><category term="backup" /><category term="debug" /><category term="google-drive" /><category term="cloudstic" /><category term="incremental" /><category term="packfiles" /><summary type="html"><![CDATA[A short walkthrough of Cloudstic debug output: repository initialization, first Google Drive backup, incremental scans through change tokens, and the role of packfiles.]]></summary></entry><entry><title type="html">Practical Backups with Cloudstic Profiles</title><link href="https://blog.cloudstic.com/2026/03/16/practical-backups-with-cloudstic-profiles/" rel="alternate" type="text/html" title="Practical Backups with Cloudstic Profiles" /><published>2026-03-16T00:00:00+00:00</published><updated>2026-03-16T00:00:00+00:00</updated><id>https://blog.cloudstic.com/2026/03/16/practical-backups-with-cloudstic-profiles</id><content type="html" xml:base="https://blog.cloudstic.com/2026/03/16/practical-backups-with-cloudstic-profiles/"><![CDATA[<p>The first backup command is easy.</p>

<p>The problem starts when you want to keep running it.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>Before creating stores, auth entries, or profiles, make sure you have:</p>

<ul>
  <li>the Cloudstic CLI installed by following the <a href="https://docs.cloudstic.com/installation">installation guide</a></li>
  <li>a backup destination already chosen, such as local storage or an S3-compatible bucket</li>
  <li>the credentials for that destination available through environment variables or your system secret manager</li>
  <li>a writable Cloudstic config location on the machine where you are defining the profiles</li>
</ul>

<p>At the beginning, many people do something like this:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="se">\</span>
  <span class="nt">-store</span> s3:my-backups/cloudstic <span class="se">\</span>
  <span class="nt">-password</span> <span class="s2">"correct horse battery staple"</span> <span class="se">\</span>
  <span class="nt">-source</span> <span class="nb">local</span>:~/Documents
</code></pre></div></div>

<p>This works.</p>

<p>It is also how you end up with secrets in shell history, slightly different commands on each machine, and an automation story that becomes fragile very quickly.</p>

<p>This is why I added profiles.</p>

<h2 id="why-profiles-matter">Why Profiles Matter</h2>

<p>For a backup workflow, the command itself should be short.</p>

<p>The complexity should live in configuration that you define once.</p>

<p>Profiles let you separate three things:</p>

<ul>
  <li>where backups are stored</li>
  <li>how a cloud source authenticates</li>
  <li>what each backup job actually backs up</li>
</ul>

<p>This is not about adding abstraction for the sake of abstraction.</p>

<p>It is about making the workflow repeatable.</p>

<h2 id="the-goal">The Goal</h2>

<p>Let us say you want:</p>

<ul>
  <li>one S3-backed repository</li>
  <li>one profile for <code class="language-plaintext highlighter-rouge">~/Documents</code></li>
  <li>one profile for <code class="language-plaintext highlighter-rouge">~/Pictures</code></li>
  <li>one Google Drive profile for work files</li>
</ul>

<p>The end result should look like this:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-profile</span> documents
cloudstic backup <span class="nt">-profile</span> pictures
cloudstic backup <span class="nt">-profile</span> work-drive
</code></pre></div></div>

<p>Or, if you want everything:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-all-profiles</span>
</code></pre></div></div>

<p>That is the practical value.</p>

<h2 id="step-1-define-the-store-once">Step 1: Define the Store Once</h2>

<p>First define the destination.</p>

<p>For example, an S3-backed store:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic store new <span class="se">\</span>
  <span class="nt">-name</span> home-s3 <span class="se">\</span>
  <span class="nt">-uri</span> s3:my-backup-bucket/cloudstic <span class="se">\</span>
  <span class="nt">-s3-region</span> eu-west-1
</code></pre></div></div>

<p>At this point, the destination has a name.</p>

<p>You no longer need to repeat the bucket path and region in every command.</p>

<h2 id="step-2-initialize-the-repository">Step 2: Initialize the Repository</h2>

<p>Configuration alone does not create the repository.</p>

<p>You still need to initialize it once:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic store init home-s3
</code></pre></div></div>

<p>This creates the encrypted repository and its key slots.</p>

<p>The important distinction is that repository encryption and runtime secret resolution are two different concerns.</p>

<p>The repository protects the backup data.</p>

<p>Profiles tell the CLI how to obtain the credentials needed to operate.</p>

<h2 id="step-3-create-local-profiles">Step 3: Create Local Profiles</h2>

<p>Now define what should be backed up.</p>

<p>For documents:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic profile new <span class="se">\</span>
  <span class="nt">-name</span> documents <span class="se">\</span>
  <span class="nt">-source</span> <span class="nb">local</span>:~/Documents <span class="se">\</span>
  <span class="nt">-store-ref</span> home-s3
</code></pre></div></div>

<p>For pictures:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic profile new <span class="se">\</span>
  <span class="nt">-name</span> pictures <span class="se">\</span>
  <span class="nt">-source</span> <span class="nb">local</span>:~/Pictures <span class="se">\</span>
  <span class="nt">-store-ref</span> home-s3
</code></pre></div></div>

<p>At this stage, daily commands already become simpler:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-profile</span> documents
cloudstic backup <span class="nt">-profile</span> pictures
</code></pre></div></div>

<h2 id="step-4-reuse-cloud-authentication">Step 4: Reuse Cloud Authentication</h2>

<p>The same idea also applies to cloud sources.</p>

<p>For example, define a Google auth entry once:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic auth new <span class="se">\</span>
  <span class="nt">-name</span> google-work <span class="se">\</span>
  <span class="nt">-provider</span> google <span class="se">\</span>
  <span class="nt">-google-token-file</span> ~/.config/cloudstic/tokens/google-work.json
</code></pre></div></div>

<p>Then authenticate once:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic auth login <span class="nt">-name</span> google-work
</code></pre></div></div>

<p>Now create a profile that uses it:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic profile new <span class="se">\</span>
  <span class="nt">-name</span> work-drive <span class="se">\</span>
  <span class="nt">-source</span> <span class="s2">"gdrive-changes:/"</span> <span class="se">\</span>
  <span class="nt">-store-ref</span> home-s3 <span class="se">\</span>
  <span class="nt">-auth-ref</span> google-work
</code></pre></div></div>

<p>The resulting command stays short:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-profile</span> work-drive
</code></pre></div></div>

<h2 id="step-5-do-not-put-raw-secrets-in-the-config">Step 5: Do Not Put Raw Secrets in the Config</h2>

<p>This is the part that matters most operationally.</p>

<p>Do not store raw secrets directly in <code class="language-plaintext highlighter-rouge">profiles.yaml</code>.</p>

<p>Store references instead.</p>

<p>The two practical patterns are:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">env://VAR_NAME</code></li>
  <li><code class="language-plaintext highlighter-rouge">keychain://service/account</code> on macOS</li>
</ul>

<p>For example:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">stores</span><span class="pi">:</span>
  <span class="na">home-s3</span><span class="pi">:</span>
    <span class="na">uri</span><span class="pi">:</span> <span class="s">s3:my-backup-bucket/cloudstic</span>
    <span class="na">s3_region</span><span class="pi">:</span> <span class="s">eu-west-1</span>
    <span class="na">s3_access_key_secret</span><span class="pi">:</span> <span class="s">env://AWS_ACCESS_KEY_ID</span>
    <span class="na">s3_secret_key_secret</span><span class="pi">:</span> <span class="s">keychain://cloudstic/home-s3/s3-secret-key</span>
    <span class="na">password_secret</span><span class="pi">:</span> <span class="s">keychain://cloudstic/home-s3/repo-password</span>
</code></pre></div></div>

<p>This keeps the configuration file shareable while the actual secret values stay outside it.</p>

<p>On a server or in CI, environment variables are usually the easiest option.</p>

<p>On a personal macOS machine, Keychain is often more convenient.</p>

<h2 id="what-the-file-looks-like">What the File Looks Like</h2>

<p>With one store, one auth entry, and three profiles, the configuration stays readable:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">stores</span><span class="pi">:</span>
  <span class="na">home-s3</span><span class="pi">:</span>
    <span class="na">uri</span><span class="pi">:</span> <span class="s">s3:my-backup-bucket/cloudstic</span>
    <span class="na">s3_region</span><span class="pi">:</span> <span class="s">eu-west-1</span>
    <span class="na">s3_access_key_secret</span><span class="pi">:</span> <span class="s">env://AWS_ACCESS_KEY_ID</span>
    <span class="na">s3_secret_key_secret</span><span class="pi">:</span> <span class="s">keychain://cloudstic/home-s3/s3-secret-key</span>
    <span class="na">password_secret</span><span class="pi">:</span> <span class="s">keychain://cloudstic/home-s3/repo-password</span>

<span class="na">auth</span><span class="pi">:</span>
  <span class="na">google-work</span><span class="pi">:</span>
    <span class="na">provider</span><span class="pi">:</span> <span class="s">google</span>
    <span class="na">google_token_file</span><span class="pi">:</span> <span class="s">~/.config/cloudstic/tokens/google-work.json</span>

<span class="na">profiles</span><span class="pi">:</span>
  <span class="na">documents</span><span class="pi">:</span>
    <span class="na">source</span><span class="pi">:</span> <span class="s">local:~/Documents</span>
    <span class="na">store_ref</span><span class="pi">:</span> <span class="s">home-s3</span>

  <span class="na">pictures</span><span class="pi">:</span>
    <span class="na">source</span><span class="pi">:</span> <span class="s">local:~/Pictures</span>
    <span class="na">store_ref</span><span class="pi">:</span> <span class="s">home-s3</span>

  <span class="na">work-drive</span><span class="pi">:</span>
    <span class="na">source</span><span class="pi">:</span> <span class="s">gdrive-changes:/</span>
    <span class="na">store_ref</span><span class="pi">:</span> <span class="s">home-s3</span>
    <span class="na">auth_ref</span><span class="pi">:</span> <span class="s">google-work</span>
</code></pre></div></div>

<p>This is the main idea:</p>

<ul>
  <li>stores define destinations</li>
  <li>auth entries define reusable cloud login configuration</li>
  <li>profiles define backup jobs</li>
</ul>

<h2 id="step-6-verify-before-automating">Step 6: Verify Before Automating</h2>

<p>Before trusting the setup, inspect it.</p>

<p>List profiles:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic profile list
</code></pre></div></div>

<p>Show one profile:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic profile show documents
</code></pre></div></div>

<p>Verify the store:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic store verify home-s3
</code></pre></div></div>

<p>This is especially useful after rotating credentials or moving to a new machine.</p>

<h2 id="step-7-run-the-routine">Step 7: Run the Routine</h2>

<p>Once the setup exists, the real workflow becomes boring, which is exactly what I want from a backup system.</p>

<p>Run one profile:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-profile</span> documents
</code></pre></div></div>

<p>Run everything:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-all-profiles</span>
</code></pre></div></div>

<p>Inspect snapshots:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic list
</code></pre></div></div>

<p>Restore what you need:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic restore &lt;snapshot-hash&gt; <span class="nt">-output</span> ./restore.zip
</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>

<p>For me, profiles are not a cosmetic CLI feature.</p>

<p>They are the point where backup commands stop being one-off experiments and become an actual workflow.</p>

<p>The benefit is simple:</p>

<ul>
  <li>shorter commands</li>
  <li>cleaner automation</li>
  <li>safer secret handling</li>
  <li>less duplication</li>
  <li>less room for operational mistakes</li>
</ul>

<p>If the command you run every day still contains every flag, every secret, and every path inline, the setup is not finished yet.</p>

<p>To get started, see the <a href="https://docs.cloudstic.com/installation">installation guide</a>. For the complete command reference, see the <a href="https://docs.cloudstic.com">Cloudstic CLI documentation</a>. The CLI is also open source on <a href="https://github.com/cloudstic/cli">GitHub</a>.</p>]]></content><author><name>loichrn</name></author><category term="backup" /><category term="cli" /><category term="backup" /><category term="cli" /><category term="profiles" /><category term="secrets" /><category term="s3" /><category term="google-drive" /><category term="automation" /><summary type="html"><![CDATA[Learn how to turn Cloudstic CLI into a practical daily backup workflow using profiles, named stores, reusable auth entries, and secret references instead of long one-off commands.]]></summary></entry><entry><title type="html">Backing Up Portable Drives</title><link href="https://blog.cloudstic.com/2026/03/12/backing-up-portable-drives/" rel="alternate" type="text/html" title="Backing Up Portable Drives" /><published>2026-03-12T00:00:00+00:00</published><updated>2026-03-12T00:00:00+00:00</updated><id>https://blog.cloudstic.com/2026/03/12/backing-up-portable-drives</id><content type="html" xml:base="https://blog.cloudstic.com/2026/03/12/backing-up-portable-drives/"><![CDATA[<p>A portable drive is convenient storage but It is not a backup.</p>

<p>There is also a second problem that appears as soon as you try to back it up seriously: the drive moves.</p>

<p>On one machine it is mounted as <code class="language-plaintext highlighter-rouge">/Volumes/WorkDrive</code>.</p>

<p>On another one it becomes <code class="language-plaintext highlighter-rouge">/media/alice/WorkDrive</code>.</p>

<p>On Windows it may become <code class="language-plaintext highlighter-rouge">E:\</code>.</p>

<p>For a human, this is obviously the same drive, for many backup tools, it is not.</p>

<h2 id="the-actual-problem">The Actual Problem</h2>

<p>Many backup tools identify a source using some combination of:</p>

<ul>
  <li>hostname</li>
  <li>absolute path</li>
  <li>mount point</li>
</ul>

<p>This is acceptable for internal disks.</p>

<p>It is not acceptable for portable drives.</p>

<p>If the identity changes every time the drive moves to another machine, incremental history breaks. Even when deduplication prevents re-uploading all data, the tool still has to rebuild state as if it had discovered a new source.</p>

<p>In practice, this means more scanning, more metadata, and a fragmented backup history.</p>

<h2 id="what-the-identity-should-be">What the Identity Should Be</h2>

<p>For a portable drive, the identity should come from the drive itself.</p>

<p>On modern drives, the right identifier already exists: the GPT partition UUID.</p>

<p>This UUID is:</p>

<ul>
  <li>stable across reboots</li>
  <li>independent of mount point</li>
  <li>independent of hostname</li>
  <li>usable across operating systems</li>
</ul>

<p>This is the identifier I wanted Cloudstic to use for portable drives.</p>

<h2 id="how-common-tools-behave">How Common Tools Behave</h2>

<p>There are several good backup tools on the market. The issue here is not quality in general. The issue is portable-drive identity.</p>

<h3 id="rsync">rsync</h3>

<p><code class="language-plaintext highlighter-rouge">rsync</code> is a very useful file copy tool.</p>

<p>It can be used to build snapshot-like workflows with <code class="language-plaintext highlighter-rouge">--link-dest</code>, but it does not have a real notion of encrypted repository, snapshot identity, or portable drive UUID.</p>

<p>For this use case, it requires scripting and discipline.</p>

<h3 id="time-machine">Time Machine</h3>

<p>Time Machine is tied to macOS and works per machine.</p>

<p>If the same portable drive is backed up from two different Macs, you effectively get two different histories.</p>

<h3 id="restic-and-borg">Restic and Borg</h3>

<p>Restic and Borg are serious backup tools, and I like both.</p>

<p>However, their default source identity model is still centered on the machine and the path.</p>

<p>You can work around this with manual overrides such as <code class="language-plaintext highlighter-rouge">--host</code>, but then the correctness of the history depends on the user remembering to keep the override identical everywhere.</p>

<p>This works, but I do not consider it a satisfying solution for a portable drive.</p>

<h2 id="the-approach-in-cloudstic">The Approach in Cloudstic</h2>

<p>Cloudstic treats a portable local source differently.</p>

<p>When a volume UUID is available, it takes precedence over hostname and path for snapshot matching.</p>

<p>This means that if you:</p>

<ol>
  <li>back up a drive on macOS</li>
  <li>unplug it</li>
  <li>connect it to Linux</li>
  <li>run the backup again</li>
</ol>

<p>Cloudstic can continue the same snapshot lineage automatically.</p>

<p>This is the behavior I expected from the start.</p>

<p>The path inside the snapshot is stored relative to the volume root, so changing the mount point does not create an artificial identity change.</p>

<h2 id="what-this-changes-in-practice">What This Changes in Practice</h2>

<p>Suppose you have a 100 GB external SSD.</p>

<p>You back it up from machine A.</p>

<p>The next day you modify only 200 MB of files and plug the same drive into machine B.</p>

<p>The correct outcome is simple: the next backup should process the same source lineage and upload only the delta.</p>

<p>That is exactly what a UUID-based identity gives.</p>

<p>Without it, you still get deduplication benefits, but you lose the continuity of the source history.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>Before running the examples below, make sure you have:</p>

<ul>
  <li>the Cloudstic CLI installed on each machine that will back up the drive by following the <a href="https://docs.cloudstic.com/installation">installation guide</a></li>
  <li>a portable drive formatted with a stable partition identifier such as a GPT partition UUID</li>
  <li>access to the backup repository from every machine involved</li>
  <li>repository credentials available before you start the first backup</li>
</ul>

<h2 id="minimal-example-with-cloudstic">Minimal Example with Cloudstic</h2>

<h3 id="1-initialize-the-repository">1. Initialize the Repository</h3>

<p>For example on local storage:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic init <span class="se">\</span>
  <span class="nt">-store</span> <span class="nb">local</span>:/Volumes/BackupDrive/cloudstic <span class="se">\</span>
  <span class="nt">-recovery</span>
</code></pre></div></div>

<p>Or on object storage, for example S3-compatible storage:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">CLOUDSTIC_STORE</span><span class="o">=</span>s3:my-backup-bucket
<span class="nb">export </span><span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span>your-key
<span class="nb">export </span><span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span>your-secret

cloudstic init <span class="nt">-recovery</span>
</code></pre></div></div>

<h3 id="2-first-backup-on-machine-a">2. First Backup on Machine A</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="se">\</span>
  <span class="nt">-source</span> <span class="nb">local</span>:/Volumes/WorkDrive <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".Spotlight-V100/"</span> <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".fseventsd/"</span> <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".Trashes/"</span> <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".DS_Store"</span> <span class="se">\</span>
  <span class="nt">-tag</span> work-drive
</code></pre></div></div>

<p>At this point Cloudstic detects the volume UUID and stores it in the snapshot metadata.</p>

<h3 id="3-second-backup-on-machine-b">3. Second Backup on Machine B</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="se">\</span>
  <span class="nt">-source</span> <span class="nb">local</span>:/media/alice/WorkDrive <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".Spotlight-V100/"</span> <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".fseventsd/"</span> <span class="se">\</span>
  <span class="nt">-exclude</span> <span class="s2">".Trashes/"</span> <span class="se">\</span>
  <span class="nt">-tag</span> work-drive
</code></pre></div></div>

<p>Same drive, different hostname, different mount point.</p>

<p>Cloudstic matches the volume UUID and continues the same incremental chain.</p>

<p>On macOS and Linux this UUID is detected automatically. When auto-detection is unavailable, you can still provide <code class="language-plaintext highlighter-rouge">-volume-uuid</code> manually.</p>

<h2 id="retention-also-becomes-cleaner">Retention Also Becomes Cleaner</h2>

<p>This matters for retention as well.</p>

<p>If snapshots are grouped by volume UUID, a retention policy applies to the drive as one source, not once per machine.</p>

<p>So keeping 7 daily snapshots means 7 daily snapshots for the portable drive, not 7 on the Mac side and 7 on the Linux side.</p>

<p>This is a small detail, but it keeps history much cleaner.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Portable drives move between machines.</p>

<p>If the backup tool identifies them by hostname or mount point, it will eventually treat the same drive as multiple sources.</p>

<p>For me, this is the wrong model.</p>

<p>The identity should come from the drive itself.</p>

<p>Using the GPT partition UUID solves that problem and makes cross-machine incremental backups behave as expected.</p>

<p>That is the approach implemented in Cloudstic for portable local sources.</p>

<p>If you want to get started, see the <a href="https://docs.cloudstic.com/installation">installation guide</a>. If you want the full command reference, see the <a href="https://docs.cloudstic.com">Cloudstic CLI documentation</a>.</p>]]></content><author><name>loichrn</name></author><category term="backup" /><category term="storage" /><category term="backup" /><category term="portable-drive" /><category term="external-drive" /><category term="incremental" /><category term="restic" /><category term="borg" /><category term="uuid" /><category term="cross-machine" /><summary type="html"><![CDATA[Portable drives move between machines, mount points, and operating systems. This article explains why many backup tools break incremental history in that situation, and how Cloudstic uses GPT partition UUIDs to keep a single backup lineage across machines.]]></summary></entry><entry><title type="html">The Anatomy of Modern Incremental Backups</title><link href="https://blog.cloudstic.com/2026/03/11/the-anatomy-of-modern-incremental-backups/" rel="alternate" type="text/html" title="The Anatomy of Modern Incremental Backups" /><published>2026-03-11T00:00:00+00:00</published><updated>2026-03-11T00:00:00+00:00</updated><id>https://blog.cloudstic.com/2026/03/11/the-anatomy-of-modern-incremental-backups</id><content type="html" xml:base="https://blog.cloudstic.com/2026/03/11/the-anatomy-of-modern-incremental-backups/"><![CDATA[<p>If you have ever tried to back up a terabyte of data to the cloud, you know the naive approach of copying everything every time is a disaster. It is slow, expensive, and kills your bandwidth. To solve this, the industry moved to incremental backups where only changed data is uploaded. However, as data scales into the petabytes, the standard way of doing incrementals is hitting a wall.</p>

<p>In this article, we look at the state of the art techniques used by modern storage engines and why the next generation of backup tech is moving toward a more flexible, flat architecture.</p>

<h2 id="1-content-addressable-storage-cas">1. Content Addressable Storage (CAS)</h2>

<p>The biggest leap in modern backup architecture is abandoning files and folders at the storage layer. Instead, industry leaders use <strong>Content Addressable Storage (CAS)</strong>. In a traditional system, data is found by its path. In CAS, data is found by its cryptographic hash such as SHA-256.</p>

<pre><code class="language-mermaid">graph LR
    subgraph "Traditional: Location-Based"
        P1["/docs/report.pdf"] --&gt;|path lookup| D1["Data Block A"]
        P2["/backup/report.pdf"] --&gt;|path lookup| D2["Data Block A (duplicate)"]
    end

    subgraph "CAS: Content-Based"
        F1["report.pdf"] --&gt;|SHA-256| H1["a8f5e..."]
        F2["report_copy.pdf"] --&gt;|SHA-256| H1
        H1 --&gt;|hash lookup| D3["Data Block A (stored once)"]
    end
</code></pre>

<p>The CAS logic is simple. Same content leads to the same hash which is stored once. This is the foundation of <strong>deduplication</strong>. If you rename a file or move it to a different folder, a CAS based system realizes the content has not changed and uploads exactly zero bytes.</p>

<h3 id="the-confirmation-attack">The Confirmation Attack</h3>

<p>Standard CAS has a privacy hole. If a cloud provider knows the hash of a specific file, they can see if your bucket contains that hash even if they cannot read the encrypted content.</p>

<p>To solve this, one solution is to avoid using raw hashes for chunk names. Instead, we can use <strong>Keyed HMAC-SHA256</strong>. By using a secret key known only to you to salt the hashes, your data remains fully deduplicated but becomes cryptographically opaque to the host.</p>

<h3 id="the-boundary-shift-problem">The Boundary Shift Problem</h3>

<p>What if you have a 10GB database and change one single row?</p>

<p>Slicing it at fixed 1MB intervals is a trap. If you insert one byte at the very beginning, every 1MB boundary shifts. This changes the hash of every block.</p>

<h3 id="the-solution-content-defined-chunking-cdc">The Solution: Content Defined Chunking (CDC)</h3>

<p>Modern systems use algorithms like <strong>FastCDC</strong>. It rolls a sliding window across the data. When the data matches a specific mathematical pattern, it slices the chunk.</p>

<pre><code class="language-mermaid">graph TD
    subgraph "Fixed-Size Chunking"
        FS["Original File: AABBCCDDEE"]
        FS --&gt; C1["AA | BB | CC | DD | EE"]
        INS1["Insert 'X' at start: XAABBCCDDEE"]
        INS1 --&gt; C2["XA | AB | BC | CD | DE"]
        C2 -.- NOTE1["⚠ Every chunk changed!"]
    end

    subgraph "Content-Defined Chunking (CDC)"
        CDC["Original File: AABBCCDDEE"]
        CDC --&gt; C3["AAB | BCC | DDEE"]
        INS2["Insert 'X' at start: XAABBCCDDEE"]
        INS2 --&gt; C4["XAAB | BCC | DDEE"]
        C4 -.- NOTE2["✓ Only first chunk changed"]
    end
</code></pre>

<p>Because the boundaries are determined by the content itself, an insertion at the start only changes the first chunk. The rest of the puzzle pieces realign perfectly.</p>

<h2 id="2-structural-sharing-the-magic-of-merkle-trees">2. Structural Sharing: The Magic of Merkle Trees</h2>

<p>Once you have thousands of content addressed chunks, you must remember which chunks belong to which files at a specific point in time. The industry standard is the <strong>Merkle Tree</strong>. This is a hierarchical structure where every node is the hash of its children. This enables <strong>Structural Sharing</strong>.</p>

<pre><code class="language-mermaid">graph TD
    subgraph "Snapshot 1"
        R1["Root Hash: abc123"] --&gt; A1["Dir A: def456"]
        R1 --&gt; B1["Dir B: 789abc"]
        A1 --&gt; F1["file1.txt: aaa"]
        A1 --&gt; F2["file2.txt: bbb"]
        B1 --&gt; F3["file3.txt: ccc"]
    end

    subgraph "Snapshot 2 (file2.txt changed)"
        R2["Root Hash: xyz789"] --&gt; A2["Dir A: new111"]
        R2 -.-&gt;|"shared"| B1
        A2 -.-&gt;|"shared"| F1
        A2 --&gt; F2new["file2.txt: ddd (new)"]
    end

    style B1 fill:#90EE90
    style F1 fill:#90EE90
    style F3 fill:#90EE90
    style F2new fill:#FFB347
</code></pre>

<p>When you take a new backup:</p>

<ul>
  <li>You only upload the <strong>modified chunks</strong>.</li>
  <li>A new root hash is generated for the snapshot.</li>
  <li>Most of the tree simply <strong>points to the previous snapshot’s nodes</strong>.</li>
</ul>

<p>The result is that every snapshot acts like a full backup for recovery, but it only consumes the storage space of an incremental update.</p>

<h2 id="3-the-directory-tree-trap">3. The Directory Tree Trap</h2>

<p>Most modern tools build their Merkle Trees by mirroring the computer’s natural directory structure. While intuitive, this path based approach creates two major headaches at scale.</p>

<p><strong>Path Amplification:</strong> If you have a file buried ten folders deep, changing that one file forces the system to recalculate and reupload metadata for all ten parent directories.</p>

<p><strong>The Rigid Hierarchy Problem:</strong> Modern data does not always live in a neat tree. Cloud drives like Google Drive allow a single file to have multiple parents, and flat data streams like database dumps do not have folders at all. Standard tools struggle to map these non tree structures efficiently, which often leads to metadata bloat.</p>

<h2 id="4-about-the-author">4. About the Author</h2>

<p>I have been looking into these industry standards while building <a href="https://github.com/cloudstic/cli">Cloudstic</a>, a project aimed at solving these specific bottlenecks. To achieve both zero trust privacy and high performance, I realized the engine needed to be built from the ground up.</p>

<p>Cloudstic is a content addressable, encrypted CLI backup tool designed to be fully stateless. Unlike many traditional tools, it can back up from Google Drive and OneDrive using incremental APIs without ever needing to mount the drive.</p>

<p><strong>Core Features:</strong></p>

<ul>
  <li><strong>Encrypted by Default:</strong> Uses AES-256-GCM encryption with password, platform key, or recovery key slots.</li>
  <li><strong>Content Addressable:</strong> Native deduplication across all sources; identical files are stored only once.</li>
  <li><strong>Versatile Backends:</strong> Supports local filesystems, Amazon S3 (R2, MinIO), and Backblaze B2.</li>
  <li><strong>Smart Retention:</strong> Automated keep-last, hourly, daily, and yearly retention policies.</li>
  <li><strong>Point-in-Time Restore:</strong> Instant access to any snapshot or file from any point in history.</li>
</ul>

<p>If you want to try Cloudstic, start with the <a href="https://docs.cloudstic.com/installation">installation guide</a>. For the full command reference and configuration options, see the <a href="https://docs.cloudstic.com">Cloudstic CLI documentation</a>.</p>]]></content><author><name>loichrn</name></author><category term="backup" /><category term="architecture" /><category term="backup" /><category term="incremental" /><category term="deduplication" /><category term="merkle-tree" /><category term="content-addressable-storage" /><category term="encryption" /><summary type="html"><![CDATA[A deep dive into content-addressable storage, content-defined chunking, and Merkle trees — the building blocks of modern incremental backup engines.]]></summary></entry><entry><title type="html">Google Drive Is Not a Backup (Here’s How to Fix That)</title><link href="https://blog.cloudstic.com/2026/03/04/how-to-backup-from-google-drive/" rel="alternate" type="text/html" title="Google Drive Is Not a Backup (Here’s How to Fix That)" /><published>2026-03-04T00:00:00+00:00</published><updated>2026-03-04T00:00:00+00:00</updated><id>https://blog.cloudstic.com/2026/03/04/how-to-backup-from-google-drive</id><content type="html" xml:base="https://blog.cloudstic.com/2026/03/04/how-to-backup-from-google-drive/"><![CDATA[<p>Google Drive is a synchronization product, It is not a backup product.</p>

<p>This distinction matters because many people use Google Drive as the place where they put important data and assume the problem is solved.</p>

<p>In practice, Google Drive protects you well against infrastructure failures on Google’s side. It does not protect you well against logical failures on your side.</p>

<p>For example:</p>

<ul>
  <li>you delete a folder by mistake</li>
  <li>ransomware encrypts local files and sync propagates the result</li>
  <li>your account is suspended or locked</li>
</ul>

<p>In all these cases, sync can work exactly as designed and you can still lose access to your data.</p>

<h2 id="what-a-backup-gives-that-sync-does-not">What a Backup Gives That Sync Does Not</h2>

<p>The main difference is history.</p>

<p>With a real backup, you can go back to a previous point in time and restore the state that existed before the problem.</p>

<p>Without that, you only have the current state of the synchronized drive and whatever limited recovery features the provider exposes.</p>

<p>This is why file versioning is useful but not sufficient. In a real incident, you do not want to inspect documents one by one. You want to restore a coherent state.</p>

<h2 id="common-approaches">Common Approaches</h2>

<p>If you want to protect Google Drive properly, there are a few possible approaches.</p>

<h3 id="google-takeout">Google Takeout</h3>

<p>Google Takeout allows you to export your data.</p>

<p>This is useful as an export mechanism, but I do not consider it a practical backup strategy. It is manual, slow, and difficult to run frequently enough.</p>

<h3 id="backup-through-a-mounted-drive">Backup Through a Mounted Drive</h3>

<p>Another option is to mount Google Drive locally with a tool such as <code class="language-plaintext highlighter-rouge">rclone</code> and then use a traditional backup tool on top of that mount.</p>

<p>This works, but it is not ideal.</p>

<p>The backup tool sees a filesystem. Google Drive is not really a filesystem. It is an API-backed data source with its own semantics and its own incremental mechanisms.</p>

<p>As a consequence, this approach often ends up rescanning large trees, creating latency and local caching overhead even when very little changed.</p>

<h3 id="native-backup-through-the-provider-api">Native Backup Through the Provider API</h3>

<p>The third option is to back up Google Drive natively through the provider API.</p>

<p>This is the approach I wanted.</p>

<p>Instead of pretending Google Drive is a local disk, the backup tool can use the change tracking exposed by Google itself and create real snapshots in an external repository.</p>

<h2 id="why-i-built-cloudstic">Why I Built Cloudstic</h2>

<p>I started working on Cloudstic because I did not find a solution that matched what I wanted.</p>

<p>I wanted a tool able to:</p>

<ul>
  <li>create encrypted snapshots</li>
  <li>deduplicate data across sources</li>
  <li>store backups outside the original account boundary</li>
  <li>back up Google Drive without mounting it locally</li>
</ul>

<p>Cloudstic uses the Google Drive Changes API through the <code class="language-plaintext highlighter-rouge">gdrive-changes</code> source.</p>

<p>This means the first backup performs a full scan, but the following ones can request only what changed since the previous snapshot.</p>

<p>That is the main reason this approach is much faster than scanning a mounted drive again and again.</p>

<p>If you want the technical explanation behind this, I wrote a companion articles: <a href="/2026/03/05/reading-a-native-backup-through-debug/">Reading a Native Backup Through –debug</a>.</p>

<h2 id="what-this-gives-in-practice">What This Gives in Practice</h2>

<p>Using a native backup flow, the result is straightforward:</p>

<ul>
  <li>your Google Drive is backed up into a real repository</li>
  <li>snapshots are immutable checkpoints</li>
  <li>unchanged data is reused through deduplication</li>
  <li>the backup can live outside Google Drive itself</li>
  <li>restore does not depend on browsing version history file by file</li>
</ul>

<p>This is, for me, the main value of a backup tool. It should give a predictable restore path.</p>

<h2 id="who-should-care">Who Should Care</h2>

<p>This is not only for large companies or security teams.</p>

<p>It is useful for anyone who stores important documents in Google Drive, especially:</p>

<ul>
  <li>freelancers storing customer deliverables</li>
  <li>small teams working from shared folders</li>
  <li>families storing photos, scans, and administrative documents</li>
  <li>founders running operations out of docs, sheets, and shared drives</li>
</ul>

<p>The more operational value your Google Drive contains, the less reasonable it is to treat sync as backup.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>Before running the commands below, make sure you have:</p>

<ul>
  <li>access to a backup destination such as local storage or an S3-compatible bucket</li>
  <li>credentials for that destination available in your shell environment</li>
  <li>a Google account ready to authorize Cloudstic on first use</li>
</ul>

<h2 id="a-simple-setup">A Simple Setup</h2>

<p>Here is the minimal setup with Cloudstic.</p>

<h3 id="1-install-the-cli">1. Install the CLI</h3>

<p>If Cloudstic is not installed yet, start with the <a href="https://docs.cloudstic.com/installation">installation guide</a>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew <span class="nb">install </span>cloudstic/tap/cloudstic
</code></pre></div></div>

<h3 id="2-create-an-encrypted-repository">2. Create an Encrypted Repository</h3>

<p>For example on S3-compatible storage:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">CLOUDSTIC_STORE</span><span class="o">=</span>s3:my-backup-bucket
<span class="nb">export </span><span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span>your-key
<span class="nb">export </span><span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span>your-secret

cloudstic init <span class="nt">-add-recovery-key</span>
</code></pre></div></div>

<p>This creates the repository and generates a recovery key.</p>

<h3 id="3-authenticate-with-google">3. Authenticate with Google</h3>

<p>On first use, Cloudstic opens a browser window for OAuth authentication and stores the token locally for later runs.</p>

<h3 id="4-run-the-backup">4. Run the Backup</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cloudstic backup <span class="nt">-source</span> gdrive-changes <span class="nt">-tag</span> cloud
</code></pre></div></div>

<p>The first run performs a full scan.</p>

<p>The following runs are incremental.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Google Drive is very useful.</p>

<p>I use it as a source of data, not as a backup destination.</p>

<p>If the data matters, I want snapshots, an external repository, and a restore path that does not depend on the current state of the synced account.</p>

<p>That is why I think backing up <em>from</em> Google Drive is just as important as backing up <em>to</em> it.</p>

<p>Cloudstic is open source on <a href="https://github.com/cloudstic/cli">GitHub</a>. If you want to get started, see the <a href="https://docs.cloudstic.com/installation">installation guide</a>, and for the full command reference see the <a href="https://docs.cloudstic.com">Cloudstic CLI documentation</a>.</p>]]></content><author><name>loichrn</name></author><category term="backup" /><category term="cloud" /><category term="google-drive" /><category term="backup" /><category term="cloud-storage" /><category term="ransomware" /><category term="data-protection" /><summary type="html"><![CDATA[Most people think Google Drive is a backup. It is not. Learn the difference between sync and backup, the risks of relying on cloud storage alone, and how to protect your files with real point-in-time snapshots.]]></summary></entry><entry><title type="html">Welcome to The Cloudstic Engineering Blog</title><link href="https://blog.cloudstic.com/2026/02/25/welcome-to-the-blog/" rel="alternate" type="text/html" title="Welcome to The Cloudstic Engineering Blog" /><published>2026-02-25T00:00:00+00:00</published><updated>2026-02-25T00:00:00+00:00</updated><id>https://blog.cloudstic.com/2026/02/25/welcome-to-the-blog</id><content type="html" xml:base="https://blog.cloudstic.com/2026/02/25/welcome-to-the-blog/"><![CDATA[<p>We’re excited to launch The Cloudstic Engineering Blog! This is where we’ll share
our learnings, architectural decisions, and technical deep dives on the topics
we’re passionate about.</p>

<p>Stay tuned for upcoming posts on cloud architecture, infrastructure as code,
and modern engineering practices.</p>

<p>If you want to try Cloudstic, start with the <a href="https://docs.cloudstic.com/installation">installation guide</a>.</p>]]></content><author><name>Cloudstic</name></author><category term="announcements" /><category term="announcement" /><category term="blog" /><category term="cloudstic" /><summary type="html"><![CDATA[Introducing The Cloudstic Engineering Blog — cloud architecture, backup strategies, and technical deep dives from the Cloudstic team.]]></summary></entry></feed>