<?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: dw1</title>
    <description>The latest articles on DEV Community by dw1 (@dwisiswant0).</description>
    <link>https://dev.to/dwisiswant0</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%2F530214%2F2d02af3b-71c0-4acf-9fe7-1572ed89365a.jpeg</url>
      <title>DEV Community: dw1</title>
      <link>https://dev.to/dwisiswant0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dwisiswant0"/>
    <language>en</language>
    <item>
      <title>The most practical, fast, tiny command sandboxing for AI agents</title>
      <dc:creator>dw1</dc:creator>
      <pubDate>Tue, 17 Feb 2026 21:54:19 +0000</pubDate>
      <link>https://dev.to/dwisiswant0/the-most-practical-fast-tiny-command-sandboxing-for-ai-agents-127k</link>
      <guid>https://dev.to/dwisiswant0/the-most-practical-fast-tiny-command-sandboxing-for-ai-agents-127k</guid>
      <description>&lt;p&gt;AI tooling is a chain of small, risky commands. I keep running model helpers, scraping CLIs, installer scripts, codegen steps, third-party formatters, and the occasional binary I only trust for five minutes. Most isolation options assume you want a whole environment. I usually do not. I just want one command to behave, not a whole damn platform.&lt;/p&gt;

&lt;p&gt;Here I built sandboxer called &lt;strong&gt;sandboxec&lt;/strong&gt;. It is a fast, small, single-binary wrapper for Linux that uses Landlock to enforce an allow list on filesystem and TCP access. No daemon or root, and no image build. It locks down one command and its children without dragging in a full runtime.&lt;/p&gt;

&lt;p&gt;It starts like a normal CLI and applies policy right before execution. If it fails, it fails loud. That is what I want.&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;sandboxec&lt;/strong&gt; applies restrictions right before launching your command. The process and its children inherit them. You allow what you want and everything else is denied.&lt;/p&gt;

&lt;p&gt;It can limit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filesystem read, write, execute&lt;/li&gt;
&lt;li&gt;TCP bind and connect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a container. It does not give you a new filesystem, cgroups, or resource quotas. It will not save you from kernel bugs or a local privileged attacker. It just narrows the blast radius for one command. That is the whole point.&lt;/p&gt;

&lt;p&gt;That scope is the tradeoff. It stays focused and avoids the extra surface area that slows down bigger systems. It is fast (single binary, no warmup), clear (you see every path and port), cheap (no runtime lifecycle), and it fits the way AI pipelines actually run.&lt;/p&gt;

&lt;p&gt;When I reach for it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running a third-party CLI against a local repo&lt;/li&gt;
&lt;li&gt;Testing an install script before trusting it&lt;/li&gt;
&lt;li&gt;Executing generated code in CI&lt;/li&gt;
&lt;li&gt;Wrapping a build tool that only needs a few paths and outbound HTTPS&lt;/li&gt;
&lt;li&gt;Running AI helpers that should not roam the host&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need tenant isolation, stronger boundaries, or resource limits, use containers or a VM. That is a different problem.&lt;/p&gt;

&lt;p&gt;The reason this can stay small is Landlock. It is the kernel feature doing the heavy lifting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Landlock (briefly)
&lt;/h2&gt;

&lt;p&gt;Landlock is a Linux security feature for unprivileged sandboxing. Unlike many LSMs, it lets a process restrict its own filesystem and network access, so you can cut down ambient rights without needing root. The LSM world has a bunch of flavors already (SELinux, AppArmor, Smack, TOMOYO), and Landlock is the one built for self-restricting apps. It is stackable, so it layers on top of whatever your system already does, instead of replacing it. That is why it is a great fit for a one-command wrapper: you can be strict where you need to be strict and leave everything else alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Landlock support is required, so Linux kernel 5.13+ for filesystem rules. TCP rules need a newer Landlock ABI, usually kernel 6.7+.&lt;/p&gt;

&lt;p&gt;If the kernel is missing a feature, you can run with &lt;code&gt;--best-effort&lt;/code&gt; to degrade instead of failing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick install&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;go.dw1.io/sandboxec@v0.2.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go 1.24.0 or later is required. There are also prebuilt binaries on the &lt;a href="https://gh.dw1.io/sandboxec/releases/latest" rel="noopener noreferrer"&gt;release page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick start&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Allow read+exec on &lt;code&gt;/usr&lt;/code&gt;, then run &lt;code&gt;id&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sandboxec &lt;span class="nt"&gt;--fs&lt;/span&gt; rx:/usr &lt;span class="nt"&gt;--&lt;/span&gt; /usr/bin/id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allow read+exec on system paths, read+write on the current repo and &lt;code&gt;/tmp&lt;/code&gt;, then run a build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sandboxec &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rx:/bin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rx:/usr &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rw:&lt;span class="nv"&gt;$PWD&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rw:/tmp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--net&lt;/span&gt; c:443 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; your-build-command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outbound HTTPS only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sandboxec &lt;span class="nt"&gt;--fs&lt;/span&gt; rx:/usr &lt;span class="nt"&gt;--net&lt;/span&gt; c:443 &lt;span class="nt"&gt;--&lt;/span&gt; /usr/bin/curl https://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run a codegen step with a tight allow list, so a bad template cannot read your SSH keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sandboxec &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rx:/usr &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rw:&lt;span class="nv"&gt;$PWD&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fs&lt;/span&gt; rw:/tmp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--net&lt;/span&gt; c:443 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; ./gen-code.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Rules
&lt;/h2&gt;

&lt;p&gt;Filesystem rules are &lt;code&gt;RIGHTS:PATH&lt;/code&gt; with rights like &lt;code&gt;r&lt;/code&gt;, &lt;code&gt;rx&lt;/code&gt;, &lt;code&gt;rw&lt;/code&gt;, &lt;code&gt;rwx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Network rules are &lt;code&gt;RIGHTS:PORT&lt;/code&gt; with rights like &lt;code&gt;b&lt;/code&gt; (bind), &lt;code&gt;c&lt;/code&gt; (connect), &lt;code&gt;bc&lt;/code&gt; (bind+connect).&lt;/p&gt;

&lt;p&gt;Rules are allow-list based. If a path is not listed, it is blocked. That means you often need to include runtime paths like &lt;code&gt;/lib&lt;/code&gt;, &lt;code&gt;/usr/lib&lt;/code&gt;, &lt;code&gt;/etc&lt;/code&gt;, or the command will fail with permission errors.&lt;/p&gt;

&lt;p&gt;This is the trade. You get control in exchange for being explicit, and most AI pipelines can live with that. If you hate being explicit, you will hate this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sandboxec&lt;/strong&gt; can read YAML config from &lt;code&gt;sandboxec.yaml&lt;/code&gt; or &lt;code&gt;sandboxec.yml&lt;/code&gt;. It checks &lt;code&gt;$XDG_CONFIG_HOME/sandboxec&lt;/code&gt;, then &lt;code&gt;~/.config/sandboxec&lt;/code&gt;, then &lt;code&gt;/etc/sandboxec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;
&lt;span class="na"&gt;best-effort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;ignore-if-missing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;restrict-scoped&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;unsafe-host-runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;fs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rx:/bin&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rx:/usr&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rx:/lib&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rx:/usr/lib&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rw:/tmp&lt;/span&gt;
&lt;span class="na"&gt;net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;c:443&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CLI flags override config values. If you pass any &lt;code&gt;--fs&lt;/code&gt; or &lt;code&gt;--net&lt;/code&gt; flags, they replace the lists from the config.&lt;/p&gt;

&lt;p&gt;MCP mode exposes a single &lt;code&gt;exec&lt;/code&gt; tool. It runs commands with the same policy you define via flags or config. It is a clean fit for AI tools that want a locked down command runner without building a full sandbox system.&lt;/p&gt;

&lt;p&gt;Example MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sandboxec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/sandboxec"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--mode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--fs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rx:/usr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--fs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rw:/tmp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--fs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rw:/path/to/your/workspace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c:443"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Allow list only. Missing paths are hard failures.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--unsafe-host-runtime&lt;/code&gt; broadens access to runtime and shared libraries and can slow startup for tiny commands.&lt;/li&gt;
&lt;li&gt;This is not a container and not a VM. Use the right tool for stronger isolation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub: &lt;a href="https://gh.dw1.io/sandboxec" rel="noopener noreferrer"&gt;https://github.com/dwisiswant0/sandboxec&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want a low overhead guardrail for one command on the host, &lt;strong&gt;sandboxec&lt;/strong&gt; does the job. It is boring and strict, and that is good. Issues and PRs welcome.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>security</category>
      <category>go</category>
    </item>
    <item>
      <title>Introducing mmapfile: Unlock Fast File Access in Go with Memory-Mapped I/O</title>
      <dc:creator>dw1</dc:creator>
      <pubDate>Sun, 04 Jan 2026 17:00:00 +0000</pubDate>
      <link>https://dev.to/dwisiswant0/introducing-mmapfile-unlock-fast-file-access-in-go-with-memory-mapped-io-11ek</link>
      <guid>https://dev.to/dwisiswant0/introducing-mmapfile-unlock-fast-file-access-in-go-with-memory-mapped-io-11ek</guid>
      <description>&lt;p&gt;Hey everyone, if you're a Go developer who's ever gotten frustrated with slow file ops, especially when dealing with big files or lots of reads and writes. Meet &lt;strong&gt;mmapfile&lt;/strong&gt;, my little project that's basically a drop-in replacement for the standard &lt;a href="https://pkg.go.dev/os#File" rel="noopener noreferrer"&gt;&lt;code&gt;*os.File&lt;/code&gt;&lt;/a&gt; -- but way faster. It uses memory-mapped I/O to skip a bunch of the usual overhead.&lt;/p&gt;

&lt;p&gt;Let's chat about what it is, why it's cool, and how you can use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, What is mmapfile?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mmapfile&lt;/code&gt; is a Go library that acts just like &lt;a href="https://pkg.go.dev/os#File" rel="noopener noreferrer"&gt;&lt;code&gt;*os.File&lt;/code&gt;&lt;/a&gt; but under the hood, it maps files directly into your program's memory. Instead of calling the system for every little R/W operation, you get straight access to the file data. It's like having the file right there in RAM without actually loading it all up front.&lt;/p&gt;

&lt;p&gt;It works on different systems, but if your platform doesn't support it, it just reads the whole file into memory as a fallback. See &lt;a href="https://github.com/dwisiswant0/mmapfile#platform-support" rel="noopener noreferrer"&gt;Platform Support&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The end result is a lot way faster file operations, especially for jumping around in files or reading A LOT.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;I built this to be easy to swap in. Here are the highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It's Basically Just &lt;a href="https://pkg.go.dev/os#File" rel="noopener noreferrer"&gt;&lt;code&gt;*os.File&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;: it implements all the interfaces you know and love:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pkg.go.dev/io#Reader" rel="noopener noreferrer"&gt;&lt;code&gt;io.Reader&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://pkg.go.dev/io#Writer" rel="noopener noreferrer"&gt;&lt;code&gt;io.Writer&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://pkg.go.dev/io#Seeker" rel="noopener noreferrer"&gt;&lt;code&gt;io.Seeker&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pkg.go.dev/io#ReaderAt" rel="noopener noreferrer"&gt;&lt;code&gt;io.ReaderAt&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://pkg.go.dev/io#WriterAt" rel="noopener noreferrer"&gt;&lt;code&gt;io.WriterAt&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://pkg.go.dev/io#Closer" rel="noopener noreferrer"&gt;&lt;code&gt;io.Closer&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;And more like &lt;a href="https://pkg.go.dev/io#ReaderFrom" rel="noopener noreferrer"&gt;&lt;code&gt;io.ReaderFrom&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://pkg.go.dev/io#WriterTo" rel="noopener noreferrer"&gt;&lt;code&gt;io.WriterTo&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://pkg.go.dev/io#StringWriter" rel="noopener noreferrer"&gt;&lt;code&gt;io.StringWriter&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, you can often just replace your &lt;a href="https://pkg.go.dev/os#Open" rel="noopener noreferrer"&gt;&lt;code&gt;os.Open&lt;/code&gt;&lt;/a&gt; calls with &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#Open" rel="noopener noreferrer"&gt;&lt;code&gt;mmapfile.Open&lt;/code&gt;&lt;/a&gt; and be done.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I also write Semgrep rules to automatically detect &lt;code&gt;*os.File&lt;/code&gt; usage and suggest &lt;code&gt;mmapfile&lt;/code&gt; replacements. See &lt;a href="https://github.com/dwisiswant0/mmapfile#semgrep-rules" rel="noopener noreferrer"&gt;Semgrep Rules&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero-Copy&lt;/strong&gt;: the star of the show is the &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Bytes" rel="noopener noreferrer"&gt;&lt;code&gt;Bytes()&lt;/code&gt;&lt;/a&gt; method. It gives you a direct view into the file's memory. No copying, no extra memory use, just point and read.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Works Everywhere&lt;/strong&gt;: Linux, macOS, Windows, even the weirder Unix variants. It handles the differences for you.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Safe for Multiple Threads&lt;/strong&gt;: &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.ReadAt" rel="noopener noreferrer"&gt;&lt;code&gt;ReadAt&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.WriteAt" rel="noopener noreferrer"&gt;&lt;code&gt;WriteAt&lt;/code&gt;&lt;/a&gt; are thread-safe, so you can have goroutines hammering away without issues.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;No Memory Waste&lt;/strong&gt;: most operations don't allocate anything on the heap (read: keeps your GC chill).&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Get it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get go.dw1.io/mmapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;

    &lt;span class="s"&gt;"go.dw1.io/mmapfile"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mmapfile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// read like normal&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Read %d bytes: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c"&gt;// or grab the whole thing directly&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File contents: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For creating files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mmapfile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"newfile.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_RDWR&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_CREATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1MB file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The API (Nothing Fancy btw)
&lt;/h2&gt;

&lt;p&gt;It supports most &lt;a href="https://pkg.go.dev/os#OpenFile" rel="noopener noreferrer"&gt;&lt;code&gt;os.OpenFile&lt;/code&gt;&lt;/a&gt; flags, minus a couple we'll talk about later. Here's what you can do:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Read" rel="noopener noreferrer"&gt;Read&lt;/a&gt;([]byte)&lt;/td&gt;
&lt;td&gt;Read some bytes, move the cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.ReadAt" rel="noopener noreferrer"&gt;ReadAt&lt;/a&gt;([]byte, int64)&lt;/td&gt;
&lt;td&gt;Read from a spot without moving the cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Write" rel="noopener noreferrer"&gt;Write&lt;/a&gt;([]byte)&lt;/td&gt;
&lt;td&gt;Write bytes, move the cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.WriteAt" rel="noopener noreferrer"&gt;WriteAt&lt;/a&gt;([]byte, int64)&lt;/td&gt;
&lt;td&gt;Write to a spot without moving the cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Seek" rel="noopener noreferrer"&gt;Seek&lt;/a&gt;(int64, int)&lt;/td&gt;
&lt;td&gt;Jump to a position&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.ReadFrom" rel="noopener noreferrer"&gt;ReadFrom&lt;/a&gt;(io.Reader)&lt;/td&gt;
&lt;td&gt;Pull data from a reader&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.WriteTo" rel="noopener noreferrer"&gt;WriteTo&lt;/a&gt;(io.Writer)&lt;/td&gt;
&lt;td&gt;Push data to a writer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Close" rel="noopener noreferrer"&gt;Close&lt;/a&gt;()&lt;/td&gt;
&lt;td&gt;Shut it down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Sync" rel="noopener noreferrer"&gt;Sync&lt;/a&gt;()&lt;/td&gt;
&lt;td&gt;Save changes to disk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Stat" rel="noopener noreferrer"&gt;Stat&lt;/a&gt;()&lt;/td&gt;
&lt;td&gt;Get file info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Name" rel="noopener noreferrer"&gt;Name&lt;/a&gt;()&lt;/td&gt;
&lt;td&gt;File name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Len" rel="noopener noreferrer"&gt;Len&lt;/a&gt;()&lt;/td&gt;
&lt;td&gt;File size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Bytes" rel="noopener noreferrer"&gt;Bytes&lt;/a&gt;()&lt;/td&gt;
&lt;td&gt;Direct memory access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The sweet spot is random access. Use &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.ReadAt" rel="noopener noreferrer"&gt;&lt;code&gt;ReadAt&lt;/code&gt;&lt;/a&gt;/&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.WriteAt" rel="noopener noreferrer"&gt;&lt;code&gt;WriteAt&lt;/code&gt;&lt;/a&gt; for the best speed.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile" rel="noopener noreferrer"&gt;Go reference&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;I ran &lt;a href="https://github.com/dwisiswant0/mmapfile#benchmarks" rel="noopener noreferrer"&gt;some benchmarks&lt;/a&gt; against regular &lt;a href="https://pkg.go.dev/os#File" rel="noopener noreferrer"&gt;&lt;code&gt;*os.File&lt;/code&gt;&lt;/a&gt;, and mmapfile just destroys it in most cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reads
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tiny stuff (1KB): &lt;strong&gt;50x faster&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Huge files (1GB): Still &lt;strong&gt;3x faster&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Parallel reads: &lt;strong&gt;10-12x faster&lt;/strong&gt; (no matter the size).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Writes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Small (1KB): &lt;strong&gt;51x faster&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Medium (100KB): &lt;strong&gt;6x faster&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Big sequential (500MB+): A &lt;em&gt;bit slower&lt;/em&gt; because the kernel's tricks win there.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other Stuff
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Seek&lt;/code&gt;: &lt;strong&gt;29x faster&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WriteTo&lt;/code&gt;: &lt;strong&gt;254x faster&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Overall: About &lt;strong&gt;6x faster&lt;/strong&gt; on average.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no system calls for most ops, just direct memory access. Fast, simple, no surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use It (and When Not To)
&lt;/h2&gt;

&lt;p&gt;mmapfile shines in these spots:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Big files with random access&lt;/strong&gt;: Like databases or parsing binary files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lots of reading&lt;/strong&gt;: Configs, static data, lookup tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory-mapped DBs&lt;/strong&gt;: Fixed-size stuff, logs that just append.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared memory between processes&lt;/strong&gt;: Multiple programs reading the same file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-frequency I/O&lt;/strong&gt;: Thousands of small ops per second.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Skip it for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Streaming data&lt;/strong&gt;: Like from networks or pipes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files that grow a lot&lt;/strong&gt;: Needs fixed size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Huge sequential writes&lt;/strong&gt;: Kernel buffering beats user-space copies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiny, rare files&lt;/strong&gt;: Setup cost isn't worth it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Gotchas and Limits
&lt;/h2&gt;

&lt;p&gt;Nothing is perfect. Watch out for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fixed size&lt;/strong&gt;: Can't grow files after opening. Set size when creating.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No truncate&lt;/strong&gt;: To change size, close and reopen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No append mode&lt;/strong&gt;: &lt;a href="https://pkg.go.dev/os#O_APPEND" rel="noopener noreferrer"&gt;&lt;code&gt;os.O_APPEND&lt;/code&gt;&lt;/a&gt; is not there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor ops are slower&lt;/strong&gt;: Stick to &lt;code&gt;ReadAt&lt;/code&gt;/&lt;code&gt;WriteAt&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;and &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Bytes" rel="noopener noreferrer"&gt;&lt;code&gt;Bytes()&lt;/code&gt;&lt;/a&gt; gives you a slice that's only good until &lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Close" rel="noopener noreferrer"&gt;&lt;code&gt;Close()&lt;/code&gt;&lt;/a&gt;. So if you mess with read-only files, you WILL crash.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thread Safety
&lt;/h2&gt;

&lt;p&gt;Built for concurrency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.ReadAt" rel="noopener noreferrer"&gt;&lt;code&gt;ReadAt&lt;/code&gt;&lt;/a&gt;/&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.WriteAt" rel="noopener noreferrer"&gt;&lt;code&gt;WriteAt&lt;/code&gt;&lt;/a&gt;: Safe to call from multiple goroutines.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Read" rel="noopener noreferrer"&gt;&lt;code&gt;Read&lt;/code&gt;&lt;/a&gt;/&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Write" rel="noopener noreferrer"&gt;&lt;code&gt;Write&lt;/code&gt;&lt;/a&gt;/&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Seek" rel="noopener noreferrer"&gt;&lt;code&gt;Seek&lt;/code&gt;&lt;/a&gt;: Share a cursor, so lock if concurrent.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pkg.go.dev/go.dw1.io/mmapfile#MmapFile.Close" rel="noopener noreferrer"&gt;&lt;code&gt;Close&lt;/code&gt;&lt;/a&gt;: Don't call while others are running.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Uses
&lt;/h2&gt;

&lt;p&gt;Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DB engines&lt;/strong&gt;: Quick jumps to data pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log munching&lt;/strong&gt;: Parsing giant log files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Config loading&lt;/strong&gt;: Fast parsing of big configs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File caches&lt;/strong&gt;: Persistent, memory-backed caches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Science stuff&lt;/strong&gt;: Working with binary datasets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;If you're hacking on Go apps with heavy file I/O, mmapfile could be your new best friend. The speedups for reads and random access are killer for modern apps.&lt;/p&gt;

&lt;p&gt;But hey, it's not for everything. Think about your use case; do you need growing files? Streaming? If not, give it a shot.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is pre-1.0, so things might change. Go check it out &lt;a href="https://github.com/dwisiswant0/mmapfile" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt;, try it, and let me know what you think!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>go</category>
      <category>performance</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
