Skip to main content

Overview

ValKeyper is configured entirely through command-line flags. Unlike Redis, there is no configuration file support - all settings are passed as arguments when starting the server.

Command-Line Flag Parsing

Flags are parsed at startup using a custom parser that looks for -- prefixed arguments:
func (kv *KVStore) ParseCommandLine() {
    flags := make(map[string]string)
    
    for i := 1; i < len(os.Args); i++ {
        if os.Args[i][:2] == "--" {
            flags[os.Args[i][2:]] = os.Args[i+1]
            i++  // Skip the value
        }
    }
}
Source: store.go:640-649 Flags are stored in a map and can be retrieved using the CONFIG GET command.

Available Flags

—port

Specifies the TCP port on which ValKeyper listens for client connections.
--port
string
default:"6379"
The port number for the ValKeyper server
Example:
./your_program.sh --port 7000
Source: store.go:650-653
port, ok := flags["port"]
if ok {
    kv.Info.Port = port
}
The server binds to 0.0.0.0 on the specified port:
addr := fmt.Sprintf("0.0.0.0:%s", kvStore.Info.Port)
l, err := net.Listen("tcp", addr)
Source: server.go:24-30

—replicaof

Configures the instance as a slave and specifies the master to replicate from.
--replicaof
string
Master address in the format "<ip> <port>" (space-separated)
Example:
./your_program.sh --port 6380 --replicaof "127.0.0.1 6379"
Source: store.go:654-659
replicaof, ok := flags["replicaof"]
if ok {
    kv.Info.Role = "slave"
    kv.Info.MasterIP = strings.Split(replicaof, " ")[0]
    kv.Info.MasterPort = strings.Split(replicaof, " ")[1]
}
The value must be a single quoted string with space-separated IP and port: "192.168.1.100 6379"
When configured as a slave, ValKeyper automatically initiates replication:
if kvStore.Info.Role == "slave" {
    fmt.Println("connecting to master by slave node")
    kvStore.HandleReplication()
}
Source: server.go:19-22

—dir

Specifies the directory where RDB persistence files are stored.
--dir
string
Directory path for RDB file storage
Example:
./your_program.sh --dir /var/lib/valkeyper
Source: store.go:661-677
The --dir flag has no effect unless paired with --dbfilename. Both must be provided for persistence.

—dbfilename

Specifies the name of the RDB file to load on startup.
--dbfilename
string
Filename of the RDB snapshot (typically dump.rdb)
Example:
./your_program.sh --dir /data --dbfilename backup.rdb
Source: store.go:661-677
dir, ok1 := flags["dir"]
dbfile, ok2 := flags["dbfilename"]

if ok1 && ok2 {
    rdb, err := rdb.NewRDB(path.Join(dir, dbfile))
    if err == nil {
        err = rdb.Parse()
        kv.LoadFromRDB(rdb)
    } else {
        fmt.Println(err)
    }
}
If the file doesn’t exist or parsing fails, ValKeyper starts with an empty dataset.

Default Values

When flags are not provided, ValKeyper uses these defaults:
func New() *KVStore {
    return &KVStore{
        Info: Info{
            Role:             "master",
            MasterReplId:     "8371b4fb1155b71f4a04d3e1bc3e18c4a990aeeb",
            MasterReplOffSet: 0,
            Port:             "6379",
        },
        // ...
    }
}
Source: store.go:64-79
SettingDefault Value
Port6379
Rolemaster
Replication ID8371b4fb1155b71f4a04d3e1bc3e18c4a990aeeb
Replication Offset0

CONFIG GET Command

Retrieve configuration values at runtime using the CONFIG GET command:
redis-cli CONFIG GET port
# Returns: ["port", "6379"]

redis-cli CONFIG GET dir
# Returns: ["dir", "/var/lib/valkeyper"]
Implementation:
case "CONFIG":
    if len(buff) > 2 && buff[1] == "GET" {
        key := buff[2]
        val, ok := kv.Info.flags[key]
        if ok {
            res = resp.ToArray([]string{key, val})
        }
    }
Source: store.go:229-238 The response is a RESP array containing the key and value.

Configuration Examples

Basic Master Setup

Start a standalone master on the default port:
./your_program.sh
This is equivalent to:
./your_program.sh --port 6379

Master with Persistence

Start a master with RDB persistence:
./your_program.sh --port 6379 --dir /data --dbfilename dump.rdb

Slave Configuration

Start a slave replicating from a remote master:
./your_program.sh --port 6380 --replicaof "192.168.1.100 6379"

Slave with Persistence

Combine replication and persistence:
./your_program.sh \
  --port 6380 \
  --replicaof "192.168.1.100 6379" \
  --dir /data \
  --dbfilename slave_backup.rdb

Internal Configuration Store

Configuration flags are stored in the Info struct:
type Info struct {
    Role             string
    MasterIP         string
    MasterPort       string
    MasterReplId     string
    MasterReplOffSet int
    MasterConn       net.Conn
    slaves           []net.Conn
    Port             string
    flags            map[string]string  // Raw command-line flags
}
Source: store.go:26-36 The flags map stores all parsed command-line arguments and is used by CONFIG GET.

Server Startup Sequence

1

Initialize Store

Create a new KVStore with default values:
kvStore := store.New()
Source: server.go:14
2

Parse Flags

Process command-line arguments:
kvStore.ParseCommandLine()
Source: server.go:15
3

Load RDB (if configured)

If --dir and --dbfilename are set, load the RDB file.Source: store.go:661-677
4

Initiate Replication (if slave)

If --replicaof is set, connect to the master:
if kvStore.Info.Role == "slave" {
    kvStore.HandleReplication()
}
Source: server.go:19-22
5

Bind to Port

Start listening for client connections:
addr := fmt.Sprintf("0.0.0.0:%s", kvStore.Info.Port)
l, err := net.Listen("tcp", addr)
Source: server.go:24-32
6

Accept Connections

Enter the main event loop to handle client requests:
for {
    conn, err := l.Accept()
    go kvStore.HandleConnection(connection, rdr)
}
Source: server.go:34-46

Network Binding

ValKeyper binds to all network interfaces (0.0.0.0) on the specified port:
addr := fmt.Sprintf("0.0.0.0:%s", kvStore.Info.Port)
l, err := net.Listen("tcp", addr)
if err != nil {
    fmt.Printf("Failed to bind to port %s\n", kvStore.Info.Port)
    os.Exit(1)
}
Source: server.go:24-30
ValKeyper listens on all network interfaces by default. In production, use firewall rules to restrict access.

Error Handling

If port binding fails, ValKeyper exits with code 1:
if err != nil {
    fmt.Printf("Failed to bind to port %s\n", kvStore.Info.Port)
    os.Exit(1)
}
Common causes:
  • Port already in use by another process
  • Insufficient privileges (ports < 1024 on Unix)
  • Invalid port number

Limitations

Unlike Redis, ValKeyper does not support redis.conf files. All configuration must be done via command-line flags.
Configuration changes require restarting the server. You cannot change settings while ValKeyper is running (except via commands like REPLCONF during replication).
The CONFIG SET command is not implemented. Configuration is read-only at runtime.
Invalid flag values may cause runtime errors. The parser does not validate port ranges or file paths.

Best Practices

Document Your Setup

Keep a record of command-line flags used in production. Consider using wrapper scripts or systemd unit files.

Use Absolute Paths

Always specify absolute paths for --dir to avoid confusion with working directories.

Quote Composite Values

Remember to quote the --replicaof value: --replicaof "host port"

Monitor Port Conflicts

Check that ports are available before starting, especially when running multiple instances.

Example Systemd Unit

For production deployments, use a systemd service file:
[Unit]
Description=ValKeyper Server
After=network.target

[Service]
Type=simple
User=valkeyper
WorkingDirectory=/opt/valkeyper
ExecStart=/opt/valkeyper/your_program.sh \
  --port 6379 \
  --dir /var/lib/valkeyper \
  --dbfilename dump.rdb
Restart=on-failure

[Install]
WantedBy=multi-user.target
This ensures consistent configuration and automatic restarts.

Build docs developers (and LLMs) love