Why We Capped Our Logs at 100MB (And You Should Too)

May 31, 2026
4 min read
58 reads
Why We Capped Our Logs at 100MB (And You Should Too)

There is a specific kind of dread that only a "Disk Full" alert at 3 AM can induce.

You know the drill. A rogue application starts spinning, an IMAP client gets stuck in a loop, or a high-traffic proxy decides to narrate every single packet it sees. Before you can even reach for your coffee, your server's disk space has been swallowed by a single, multi-gigabyte log file.

At ODAC, we believe infrastructure should be invisible. If you have to think about your log files, we have failed. That is why in our latest update, we have implemented a ruthless, system-wide log rotation policy: no single log file survives past 100MB.

Diagram showing ODAC log rotation mechanism where the Size Sentry monitors application logs and rotates them at 100MB to protect the host disk.

The Villain: Unbounded Growth

Historically, log rotation has been a "tomorrow" problem. Many self-hosted platforms rely on daily cron jobs to rotate files. But "daily" is an eternity when an app is spamming 50,000 errors per second. A disk can fill up in minutes, not days.

We decided to move the safety switch directly into the runtime. Whether it is the Node.js agent or our Go-based DNS, Mail, and Proxy services, every component now enforces a hard 100MB limit per file.

Here is how we implemented this in our Go services:

// logrotate.go enforces a 100MB limit per log file
func (w *rotateWriter) Write(p []byte) (int, error) {
    w.mu.Lock()
    defer w.mu.Unlock()

    // ... internal write logic ...

    w.sinceCheck += int64(n)
    if w.sinceCheck >= 4096 { // Check size every 4KB to minimize syscalls
        w.sinceCheck = 0
        if fi, e := w.f.Stat(); e == nil && fi.Size() > 100 * 1024 * 1024 {
            w.f.Close()
            os.Rename(w.path, w.path + ".1")
            // ... reopen fresh log file ...
        }
    }
    return n, err
}

By checking the file size every 4KB of writes, we maintain extreme performance while ensuring that even the most talkative application cannot outrun our safety measures. If a file hits the cap, it is immediately moved to a .1 backup and a fresh log begins. This gives you a safe 200MB window for debugging without ever risking host disk exhaustion.

Supercharging the Mail Experience

While one team was focused on disk safety, another was tackling the "N+1" problem in our IMAP engine.

If you have ever connected a mail client with thousands of messages, you might have noticed a slight lag. In previous versions, operations like FETCH required multiple database queries per message to reconstruct the mail headers and body parts. This was the classic architectural bottleneck: linear scaling of queries against message count.

We have completely refactored this flow. Our Go-based IMAP engine now utilizes Bulk UID Fetching. Instead of round-tripping to the SQLite database for every message, we pull exactly what is needed in a single, optimized transaction.

Comparison diagram showing the legacy N+1 IMAP fetch bottleneck vs the optimized ODAC Bulk UID fetch which provides instant sync and O(1) query performance.

The Performance Delta

  • Before: A request to fetch a folder with 500 messages triggered 500+ individual SELECT statements.
  • After: One single query retrieves all UIDs, followed by a targeted bulk fetch.

Combined with our move to Non-Blocking I/O and Go Concurrency Patterns, mail sync is now significantly faster. Your mobile clients will feel snappier, and folder refreshes that used to take seconds now happen in the blink of an eye.

How to Get the Update

As always, ODAC is zero-config. If you are using our cloud management at app.odac.run, these stability improvements are already rolling out to your nodes.

For those who prefer the terminal, your agent will automatically update to the latest version. You can check your application status by running odac app list in your terminal. You don't need to change a single configuration file. Just sit back and enjoy a more stable, more performant server.

No more 3 AM disk alerts. No more sluggish mail sync. Just ODAC, working exactly how it should.