Skip to content

joserafaelSH/redis-clone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

codecrafters-redis-go — Toy Redis clone (Go)

This repository is a small, educational implementation of a Redis-like server in Go. It's based on the "Build Your Own Redis" challenge and implements a subset of the Redis command set with the RESP protocol so you can connect using the official redis-cli for basic interactions.

This file documents the project, its structure, which Redis commands are implemented, how to run the server locally, and example usage with redis-cli.

Quick summary

  • Language: Go
  • Entry point: app/main.go (server listens on 0.0.0.0:6379 by default)
  • Local run helper: ./your_program.sh (builds and runs the binary)
  • RESP compatibility: implemented for the commands listed below — redis-cli can connect to this server for those commands.

Repository structure

  • app/ — application sources
    • main.go — program entrypoint, accepts TCP connections on port 6379
    • resp/ — RESP parsing and command dispatch
      • resp.go — RESP reader, parser and CommandsMap
      • commands/ — implemented command handlers
        • basic.goPING, ECHO, COMMAND, TYPE
        • hash_map.goSET, GET (string key/value with optional TTL)
        • list.go — list commands: RPUSH, LPUSH, LRANGE, LLEN, LPOP, BLPOP
        • stream.goXADD (basic stream add behavior)
    • connection/ — connection manager utilities
    • context/ — connection context passed to command handlers
    • memory/ — in-memory data structures (hash map, lists, streams)
    • resp/commands/ — implementations referenced above
  • your_program.sh — helper script to build and run the server locally
  • README.md — original challenge README
  • README2.md — this file (detailed project README)

Implemented Redis commands

The server registers the following commands in resp.CommandsMap and provides basic behavior for them:

  • PING

    • Usage: PING
    • Response: PONG (+PONG\r\n in RESP)
  • ECHO

    • Usage: ECHO <message>
    • Response: bulk string containing the message
  • COMMAND

    • Usage: COMMAND
    • Response: empty array (*0) — placeholder (not full COMMAND support)
  • SET

    • Usage: SET <key> <value> [EX <seconds>|PX <milliseconds>]
    • Supported options: EX and PX for expirations.
    • Response: +OK on success
  • GET

    • Usage: GET <key>
    • Behavior: returns the stored value or $-1 if not found. If a TTL was set at SET time and the key has expired it will be removed and treated as missing.
  • TYPE

    • Usage: TYPE <key>
    • Response: string, list, stream or none depending on what holds the key
  • RPUSH

    • Usage: RPUSH <key> <element> [element ...]
    • Response: integer (the new length of the list)
  • LPUSH

    • Usage: LPUSH <key> <element> [element ...]
    • Response: integer (the new length of the list)
  • LRANGE

    • Usage: LRANGE <key> <start> <stop>
    • Response: array of elements in the given range
  • LLEN

    • Usage: LLEN <key>
    • Response: integer (length of the list)
  • LPOP

    • Usage: LPOP <key> or LPOP <key> <count>
    • Response: single bulk string when popping one element, or array when popping count.
    • If the key does not exist, returns a nil bulk ($-1) or *-1 in some multi-return cases
  • BLPOP

    • Usage: BLPOP <key> <key> ... <timeout>
    • Behavior: basic blocking pop implementation. The server blocks for the timeout duration and returns *-1 on timeout.
  • XADD

    • Usage: XADD <stream> <id> <field> <value> [<field> <value> ...]
    • Implementation: basic append behavior — stores pairs (field/value) under a stream key and returns the provided id or added item identifier in a simplified form.

Note: This is a toy subset. The server implements the RESP format for these commands well enough to interoperate with redis-cli for the examples shown below, but does not offer full command parity with upstream Redis.

How to build and run locally

Requirements:

  • Go toolchain (the project currently uses Go modules). Go 1.24 or later is recommended (match your local setup with go version).

Build + run (recommended — uses the provided helper script):

./your_program.sh

This will build the program and run the server on port 6379. You can also build and run directly with the Go toolchain:

go build -o /tmp/codecrafters-build-redis-go app/*.go
/tmp/codecrafters-build-redis-go

When running, the server listens on 0.0.0.0:6379 (see app/main.go).

Connect with the official redis-cli

Because the server speaks the RESP protocol, you can use the official redis-cli to connect to it. From another terminal run:

# Connect to localhost on default Redis port
redis-cli -p 6379

# Or specify host and port explicitly
redis-cli -h 127.0.0.1 -p 6379

Inside the redis-cli prompt you can issue the implemented commands. Examples:

$ redis-cli -p 6379
127.0.0.1:6379> PING
PONG

127.0.0.1:6379> SET mykey hello
OK

127.0.0.1:6379> GET mykey
"hello"

127.0.0.1:6379> RPUSH mylist a b c
(integer) 3

127.0.0.1:6379> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"

127.0.0.1:6379> TYPE mykey
"string"

If you prefer to test single commands without an interactive prompt, you can also pipe or pass commands directly to redis-cli:

redis-cli -p 6379 PING
redis-cli -p 6379 SET foo bar
redis-cli -p 6379 GET foo

Example: SET with expiration

redis-cli -p 6379 SET tempkey 123 EX 1
OK
# Wait >1 second
redis-cli -p 6379 GET tempkey
(nil)

Limitations and notes

  • Not all Redis commands or options are implemented. COMMAND returns an empty array and some advanced behaviors are simplified.
  • Persistence is not included — the data lives only in memory while the server process is running.
  • Concurrency and performance are suitable for learning and tests but not for production use.
  • The RESP parser in app/resp/resp.go reads from the connection in a single large buffer — large requests or streaming corner cases may need additional handling in a complete implementation.

Contributing / extending

If you want to add commands:

  1. Implement the handler function in app/resp/commands/ (follow existing examples).
  2. Register the command name and handler in app/resp/resp.go CommandsMap.
  3. Add unit tests (not included here) and run the server to verify.

Final notes

This project is meant for learning and the challenge environment. The server is RESP-compatible for the implemented commands and works with the official redis-cli for interactive testing.

About

Golang Redis Clone

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages