<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - Software Engineering</title>
    <link>https://emresahin.net/categories/software-engineering/</link>
    <description>Posts in the Software Engineering category</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/categories/software-engineering/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>A Brief History of Xvc</title>
      <published>2024-01-22T09:17:15+00:00</published>
      <updated>2024-01-22T09:17:15+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 22 Jan 2024 09:17:15 +0000</pubDate>
      <link>https://emresahin.net/a-brief-history-of-xvc/</link>
      <guid isPermaLink="true">https://emresahin.net/a-brief-history-of-xvc/</guid>
      <description>In the first months of 2021, I decided to return to life after a long legal battle for divorce. Covid was still raging. I wasn’t keen to start a company or work in my country due to my half-deaf ears. I decided to find some open source projects and contribute, maybe get recognition, maybe hired. ...</description>
      <category>xvc</category>
      <category>development</category>
      <category>free software</category>
      <category>Software Engineering</category>
      <category>xvc</category>
      <category>history</category>
      <category>dvc</category>
      <category>Rust</category>
      <category>MLOps</category>
      <category>Open Source</category>
      <category>Iterative.ai</category>
      <category>Git Annex</category>
      <category>serde</category>
      <category>Blake3</category>
      <category>PyO3</category>
      <content:encoded><![CDATA[<p>In the first months of 2021, I decided to return to life after a long legal battle for divorce. Covid was still raging. I wasn’t keen to start a company or work in my country due to my half-deaf ears. I decided to find some open source projects and contribute, maybe get recognition, maybe hired.</p>
<p>I saw an ad on Stack Overflow Jobs those days about <em>employment by contributing to open source projects.</em> I applied to that. A few weeks later, the CTO of [iterative.ai] got in touch and I started working on DVC documentation. Initially on a per-hour basis, and after May 2021, as a full-time employee.</p>
<p>Initially, I liked the tool we were building very much. The team was awesome. (Still, they are.) It was one of the best periods of my life, especially in my turbulent still-ongoing-divorce-period pressures. I know I will always miss them.</p>
<p>My job was learning DVC, documenting it, and helping newcomers grasp it easily. It was a fun job. Until then, I didn’t see myself as a technical writer. English is not my native tongue and I never have lived in an English-speaking country. Nevertheless, I think I wasn’t <em>too bad</em> at it.</p>
<p>When I was first learning the tool, I began to use it everywhere. I was an avid user of Git Annex once. DVC looked better. I don’t remember why I lost interest in Git Annex after many years, but it was probably related to symbolic links not working on Windows (or on Termux). DVC had multiple ways of connecting the cache and the files in the workspace, including hardlinks and copy, so it was a breath of fresh air for me.</p>
<p>I began to use it for my large collections. Keeping track of my binary files in Git was something I always desired. Git is the <em>least sucking</em> version control system among the ones I used previously (SVN, hg, darcs…) and I’d rather keep using it everywhere rather than learning new tools for binary files.</p>
<p>After some time I began to use the tool for my personal file collections. I noticed its performance became a burden. I was tracking maybe a few gigabytes of files with it and basic file operations became slower as I added more. I noticed I was becoming distracted after I wrote a <code>dvc</code> command. It took some time to confess that the tool I liked once and was earning my salary with was not a tool that I liked to use.</p>
<p>I don’t know what <em>real professionals</em> would do at this point. I never had a good LinkedIn profile. When I met a similar problem with the example repository that’s supposed to contain 70,000 small files, I brought the issue forward. I wrote a shell script that was basically doing the same thing as <code>dvc add</code> and it worked much faster than the actual command. The shell script was naïve and I thought DVC must have <em>at least</em> that level of speed. It didn’t. Simply calling <code>md5sum</code> on files and copying them to appropriate location in <code>.dvc/cache</code> was way faster. How could this be?</p>
<p>I had cursory observations on the codebase. I know some decisions (like a large central class that connects everything, separate <code>.dvc</code> files for each tracked file) that may lead to degradation. Although I don’t see it as <em>the problem</em>, Python was also not helpful. These are rough observations.</p>
<p>It was September 2021. I was also teaching myself Rust. I wrote an email to the CTO and CEO of the company to request a sabbatical to work on DVC. My plan was to rewrite certain portions (or commands) in Rust and wrap them with PyO3. It could fail. So to have <em>skin in the game</em>, I said I’ll work for free during this time and if I fail to make DVC faster for some reason, I’ll return to my writing position.</p>
<p>They didn’t accept. I didn’t try to persuade them. The decision was rational and although I’d say <em>go ahead and see what happens</em> if I were in their shoes just to make my employee happy, they aren’t <em>crazy-managers</em> as I once was. Probably there are many factors that I’m not aware of. I returned to my post and continued to write documentation for another 9 months. In the meantime I studied Rust and thought about how I could architect a similar tool. Where does DVC go wrong?</p>
<p>In April 2022, I informed the CTO that I’d like to take a sabbatical for my book. I have a political-SF book and after the Ukrainian war started with a (albeit minor) probability of nuclear attack <em>on the other shore of Black Sea</em>, I thought it’s not a time to work on something I stopped liking. My performance in the last quarter was also not something I was proud of. I didn’t feel good.</p>
<p>When I retired to sabbatical in July though, while writing the book, I thought writing the software that I wanted to see was also <em>something on my mind before nuclear war.</em> I had notes about the architecture I was planning. I wanted to see if I could apply an Entity-Component System to this basic problem, without any Object-Oriented conceptions. I believe it looks cool. I’m still simplifying and testing the idea, and it looks better to my mind than mixing data and functions for no reason.</p>
<p>After I made the repository public, I resigned from Iterative.</p>
<p>In a sense, Xvc owes its existence to DVC, and the name is a tribute to this. I hope they squash their bugs, and improve their user experience, and be a long-term player in the crowded market they are in. I don’t intend to be a “competitor”, because I prefer being developer/architect rather than a “technical steward to VC money”, and the license of Xvc is GPL-3 to signal this.</p>
<p>The Xvc command line interface, however, is as different as it can be from DVC. The command names are different; DVC has commands similar to Git (<code>push</code>, <code>fetch</code>, <code>pull</code>, <code>commit</code>), while Xvc tries to be different from Git to reduce the user’s mental load. For example, as a writer, I noticed that “Git remotes” and “DVC remotes” was confusing, so I called them “Xvc storages”. DVC calls the units of a pipeline <em>stages</em>; the same concept is called <em>steps</em> in Xvc, because <em>stage</em> in Git is something completely different.</p>
<p>Internally, the architecture is also very different. Xvc uses serialization (with serde) instead of YAML. It can export/import pipelines from YAML (or JSON), but YAML is not as central as in DVC. (I believe YAML is overused in our industry, and it’s an employment guarantee for another generation of developers but there is better work than keeping up a half-baked configuration format.) Xvc doesn’t keep its artifacts in the user’s workspace (except <code>.xvcignore</code> files). They are all stored in the <code>.xvc/</code> directory. The DVC way of doing things makes merging <code>.dvc</code> files easier. To overcome the problems caused by merging large metadata files, Xvc keeps track of events and replays them to get the final state of the repository. All metadata storage and retrieval operations revolve around the <code>XvcStore&lt;T&gt;</code> struct in Xvc. Typically, if the user runs an <code>xvc</code> command, only the updated store events (added files, changed pipelines, etc.) are stored. There are optimizations in this front, but I profile first and optimize later.</p>
<p>Algorithms for data digests are configurable; by default Xvc uses Blake3, but it is configurable to use SHA2-256, SHA3-256, or Blake2s. It can be modified to use any 256-bit digest quickly. There are some features that are not found in DVC, and more will come. So, although I’m solving a similar problem, Xvc is not “DVC rewritten in Rust,” it’s a different tool completely.</p>
<p>Currently, it doesn’t have as much eye candy as DVC. In time, I plan to add Python, Julia, and R APIs, notebook integration, experiment tracking (without relying on Git internals), data labeling and filtering, and other MLOps features. I’m building with a goal to make these features available without making the rest of the software slower.</p>
<p>I’ve found the tool I was looking for to track my kids’ photos and Ottoman OCR datasets in a Git repository. I’m tracking more than 1TB of files in a single repository with Xvc and adding another 10TB looks feasible now.</p>]]></content:encoded>
    </item>
    <item>
      <title>Quote from the Mythical Man-Month</title>
      <published>2022-04-09T05:26:31+00:00</published>
      <updated>2022-04-09T05:26:31+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sat, 09 Apr 2022 05:26:31 +0000</pubDate>
      <link>https://emresahin.net/Quote-from-the-Mythical-Man-Month/</link>
      <guid isPermaLink="true">https://emresahin.net/Quote-from-the-Mythical-Man-Month/</guid>
      <description>Although we don’t rent IBM mainframes anymore, it seems that using rented resources for software is not a new concept. The following still applies today for cloud services, perhaps on a different scale:</description>
      <category>Software Engineering</category>
      <category>Quotations</category>
      <category>Space Complexity</category>
      <category>Cloud Computing</category>
      <category>Mythical Man-Month</category>
      <category>Fred Brooks</category>
      <content:encoded><![CDATA[<p>Although we don’t rent IBM mainframes anymore, it seems that using rented resources
for software is not a new concept. The following still applies today for cloud services,
perhaps on a different scale:</p>
<figure><img src="https://emresahin.net/images/quote-mythical-man-month-2022-04-09.jpg" alt="" style="width: 300px"></figure>]]></content:encoded>
    </item>
    <item>
      <title>Premature Caching is the Root of All Evil</title>
      <published>2021-12-22T20:32:35+00:00</published>
      <updated>2021-12-22T20:32:35+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Wed, 22 Dec 2021 20:32:35 +0000</pubDate>
      <link>https://emresahin.net/premature-caching/</link>
      <guid isPermaLink="true">https://emresahin.net/premature-caching/</guid>
      <description>I’m writing a Rust command line app in my spare time to learn the language. It involves some file system checks where I use fs::metadata . As everyone knows , accessing the disk is an expensive operation and must be kept to a minimum. I was thinking of using a HashMap::&lt;Path, Metadata&gt; to cache t...</description>
      <category>Development</category>
      <category>Software Engineering</category>
      <category>rust</category>
      <category>caching</category>
      <category>xvc</category>
      <category>optimization</category>
      <category>performance</category>
      <content:encoded><![CDATA[<p>I’m writing a Rust command line app in my spare time to learn the language. It
involves some file system checks where I use <code>fs::metadata</code>. As <em>everyone
knows</em>, accessing the disk is an <em>expensive</em> operation and must be kept to a
minimum. I was thinking of using a <code>HashMap::&lt;Path, Metadata&gt;</code> to cache the
results for paths.</p>
<p>I then came across the <a href="https://crates.io/cached">cached</a> crate. It caches the results of functions for
memoization. <em>This is exactly what I need</em>, I thought. Internally, it does what I
was planning to do.</p>
<p>Later, I noticed the possible bugs that could arise. I’m thinking of using the
function in a short-running process, so the metadata is not expected to change
during the run. For some reason, suppose the runtime of the process began to
get longer, or I decided to add a web server on top of it. At that time,
probably many moons from now, I’ll have forgotten the decision I made about
caches and my assumption that the metadata won’t change during the run. It
will cause some weird bugs when file timestamp changes aren’t detected.</p>
<p>No one will notice that I’m fixing bugs if they never appear, but I believe this
is the best kind of software engineering.</p>
<h2 id="commentary-2022-08-01">Commentary (2022-08-01)</h2>
<ul>
<li>It looks like my assumption that RAM is <em>significantly faster</em> than disk access may also be wrong.
SSDs are fast, and for parallel access, they may perform as fast as RAM.</li>
</ul>]]></content:encoded>
    </item>
  </channel>
</rss>
