A Redis-like in-memory key-value server written in modern C++.
This project was built as a hands-on study of how database servers work internally, including TCP networking, non-blocking sockets, event-driven programming, hash tables, AVL trees, sorted sets, TTL expiration, thread pools, and custom binary protocols.
Educational project: This is not a drop-in replacement for Redis and does not implement the Redis RESP protocol. Use the included client program to communicate with the server.
- In-memory key-value storage
- TCP client-server communication
- Non-blocking sockets
- Event-driven server loop using
poll() - Custom binary request and response protocol
- Hash-table-based key lookup
- String values
- Sorted sets with scores
- AVL-tree-backed sorted-set operations
- Key expiration with millisecond precision
- TTL inspection
- Idle connection timeout handling
- Thread pool for cleaning up large data structures
- Native C++ client
- Optional browser-based command console
- Automated command tests
The repository contains several progressive versions of the server. The latest implementation is located in the 14 directory.
.
├── 03/
├── 04/
├── 06/
├── 07/
├── 08/
├── 09/
├── 10/
├── 11/
├── 12/
├── 13/
└── 14/
├── 14_server.cpp
├── 14_client.cpp
├── common.h
├── hashtable.cpp
├── hashtable.h
├── avl.cpp
├── avl.h
├── zset.cpp
├── zset.h
├── heap.cpp
├── heap.h
├── list.h
├── thread_pool.cpp
├── thread_pool.h
├── test_cmds.py
├── web_api.py
├── Makefile
└── README.md
Each numbered directory represents a stage in the development of the project, with the latest and most complete version currently in 14.
Install the following tools:
- GNU C++ compiler
- GNU Make
- Python 3
- POSIX-compatible environment
On Ubuntu or Debian:
sudo apt update
sudo apt install g++ make python3The server uses POSIX APIs such as:
unistd.hpoll()- POSIX sockets
- pthreads
The recommended way to run it on Windows is through WSL:
wsl --install -d UbuntuAfter installing Ubuntu, open a WSL terminal and install the required packages:
sudo apt update
sudo apt install g++ make python3Clone the repository and move into the latest version:
git clone https://github.com/CoderNasim2023/Built-myownRedis_Server.git
cd Built-myownRedis_Server/14Build the server and client:
makeThis produces:
redis_server
redis_client
To remove compiled binaries:
make cleanStart the server:
./redis_serverThe server listens on:
127.0.0.1:1234
Keep the server running in one terminal.
Open a second terminal, move into the 14 directory, and run commands using the included client.
./redis_client set name redis
./redis_client get nameExpected output:
(nil)
(str) redis
./redis_client del name./redis_client keysSet a key to expire after five seconds:
./redis_client set temporary hello
./redis_client pexpire temporary 5000Check the remaining time-to-live:
./redis_client pttl temporaryA return value of:
-1
means the key exists without an expiration time.
A return value of:
-2
means the key does not exist.
Add members to a sorted set:
./redis_client zadd ranking 10 alice
./redis_client zadd ranking 20 bob
./redis_client zadd ranking 15 charlieRead a member's score:
./redis_client zscore ranking aliceRemove a member:
./redis_client zrem ranking aliceQuery members ordered by score:
./redis_client zquery ranking 0 "" 0 10| Command | Description |
|---|---|
set key value |
Store a string value |
get key |
Retrieve a string value |
del key |
Delete a key |
keys |
Return all stored keys |
pexpire key milliseconds |
Set or update a key expiration |
pttl key |
Return the remaining TTL |
zadd zset score member |
Add or update a sorted-set member |
zrem zset member |
Remove a sorted-set member |
zscore zset member |
Return a member's score |
zquery zset score member offset limit |
Query sorted-set members by score |
The project includes an automated test script that starts the server, executes commands, checks the responses, and shuts the server down.
From the 14 directory:
make testThe test suite currently verifies:
- Setting and retrieving string values
- Adding sorted-set members
- Reading sorted-set scores
- Querying sorted sets
- Deleting keys
- Confirming deleted keys no longer exist
A successful run prints:
All version 14 command tests passed.
The project also includes a small browser-based command console.
First, start the Redis-like server:
./redis_serverThen, in another terminal, start the web interface:
make webOpen the following address in your browser:
http://localhost:3000
The request flow is:
Browser
│
▼
HTTP bridge on port 3000
│
▼
Redis-like server on port 1234
Example commands that can be entered in the browser console:
set name redis
get name
keys
zadd ranking 10 alice
zscore ranking alice
The server creates a TCP listening socket on port 1234.
Client connections are configured as non-blocking sockets. The server uses poll() to monitor:
- New incoming connections
- Readable client sockets
- Writable client sockets
- Socket errors
This allows the server to handle multiple clients without blocking on a single connection.
Requests use a custom binary format:
message length
argument count
argument length
argument data
argument length
argument data
...
The server parses the request, executes the command, and serializes the response using typed values such as:
- Nil
- Error
- String
- Integer
- Double
- Array
Top-level keys are stored in a custom hash table.
String values are stored directly in the associated entry. Sorted sets use a separate data structure that supports lookup by member and ordered queries by score.
Expiring keys are stored in a min-heap ordered by expiration time.
During the event loop, the server checks the next timer and removes expired keys when their TTL has elapsed.
Sorted sets support:
- Member lookup
- Score lookup
- Insertion and updates
- Removal
- Ordered range-style queries
The implementation combines hash-table lookup with an AVL-tree-based ordered structure.
A small thread pool is used to clean up large data structures without blocking the main event loop for too long.
This project does not implement the Redis Serialization Protocol, also known as RESP.
Therefore, standard Redis tools such as the following will not work:
redis-cliUse the included client instead:
./redis_client get nameThe browser dashboard also communicates using the project's custom protocol through the Python HTTP bridge.
This project was created to explore the implementation details behind systems such as Redis.
The main learning areas include:
- TCP socket programming
- Non-blocking I/O
- Event-driven architecture
- Request pipelining
- Binary serialization
- Hash-table implementation
- AVL trees
- Sorted sets
- Priority heaps
- TTL management
- Connection timeouts
- Thread pools
- Client-server protocol design
- Automated integration testing
This project is intended for learning and experimentation.
It currently does not provide the full feature set of Redis, including:
- Redis RESP compatibility
- Persistence to disk
- Authentication
- Replication
- Transactions
- Pub/Sub
- Cluster support
- Production-level configuration
- Comprehensive concurrency guarantees
- Full Redis command compatibility
Do not use this project as a production database.
Potential future improvements include:
- RESP protocol support
- Persistent snapshots
- Append-only file persistence
- More Redis data types
- Better command parsing
- More extensive integration tests
- Improved concurrency control
- Configuration files
- Graceful shutdown support
- Performance benchmarks
- Docker support
- CI/CD automation
No license has currently been specified for this repository.
If you plan to allow others to use, modify, or distribute the project, consider adding an open-source license such as MIT or Apache-2.0.
Created by CoderNasim2023.
If you found this project useful, consider starring the repository.