Tuning Dgraph / Badger for HDDs instead of SSDs?

I am one of the unlucky few who isn’t running Dgraph on SSDs (although I do have lots of RAM).

Is there a way to tune Badger via Dgraph, or does that require a recompile? Besides setting GOMAXPROCS to something lower, I’m also interested in tuning some parameters at badger/options.go at 1496af939d8533779f7b6b3f3a6cd251abf5c598 · dgraph-io/badger · GitHub.

What are some recommendations? Generally, because of the HDDs, I believe I should “prefer a large number of sequential writes to reduce later random reads”.

P.S. I don’t mind sending a PR if pointed in the right direction. :smiley:

package main

import (
    "context"
    "flag"
    "log"

    "github.com/dgraph-io/badger/v4"
    "github.com/dgraph-io/dgraph/x"
    "github.com/dgraph-io/dgraph/worker"
)

func main() {
    // Command-line flags
    lruMb := flag.Int("lru_mb", 16384, "Size of LRU cache in MB (high for HDDs)")
    dataDir := flag.String("p", "data", "Directory for data storage")
    flag.Parse()

    // Custom Badger options optimized for HDDs
    badgerOpts := badger.DefaultOptions(*dataDir).
        WithValueLogFileSize(1 << 30).         // 1GB value log files (large sequential writes)
        WithNumMemtables(10).                  // More in-memory tables
        WithBaseTableSize(64 << 20).           // 64MB LSM tables (fewer compactions)
        WithValueThreshold(1024).              // 1KB threshold (more inline values)
        WithNumLevelZeroTables(10).            // Buffer more L0 tables
        WithNumLevelZeroTablesStall(15).       // Delay compaction
        WithMaxCacheSize(int64(*lruMb) << 20). // Use lots of RAM for cache
        WithSyncWrites(false)                  // Trade durability for speed (optional)

    // Disable value log GC (can be enabled manually during low load)
    badgerOpts.ValueLogMaxEntries = 1000000 // Large value to delay GC

    // Setup Dgraph worker configuration
    conf := worker.Config{
        PostingDir: *dataDir,
        Badger:     badgerOpts,
        NumPendingProposals: 256,
        ExportPath:          "export",
    }

    // Initialize Dgraph
    log.Printf("Starting Dgraph with HDD-optimized Badger config...")
    x.SetConf(&x.Config{
        LimitMutationsNquad: 1000000,
        LimitQueryEdge:      1000000,
    })

    // Run Dgraph Alpha (simplified single-node setup)
    if err := worker.Run(conf, nil); err != nil {
        log.Fatalf("Dgraph failed: %v", err)
    }
}