Commands
SET
Stores a key-value pair in ThermalKV. If the key already exists, its value is updated with the new value provided.
Syntax
SET <key> <value>
Parameters
key: The unique identifier used to store and retrieve the value.
value: The data associated with the key.
Example
SET username jenil
Response
OK :)
Notes
- Existing keys are overwritten when a new value is provided.
- Values are initially stored in memory for fast access.
- Inactive values may later be cooled to persistent storage by the Cooling background worker.
GET
Retrieves the value associated with a key.
When a key is present in memory, the value is returned immediately. If the key has been cooled to persistent storage, ThermalKV loads the value back into memory (melting it from the Ice Tray) before returning it. If the key does not exist in either memory or persistent storage, an error message is returned.
Syntax
GET <key>
Parameters
key: The key whose value should be retrieved.
Example
GET username
Response
jenil
Key Not Found
Key not found :(
Notes
- Keys stored in memory are returned with the lowest latency.
- If a key has been cooled to disk, ThermalKV automatically melts it back into memory before returning the value.
- A successful retrieval of a cooled key makes it active again.
- The melting process is handled transparently and requires no user intervention.
TTL
Sets an expiration time for a key. Once the specified duration has elapsed, the key is automatically removed from ThermalKV and can no longer be accessed.
ThermalKV manages expiring keys using a Min Heap, allowing expired entries to be identified and removed efficiently by the Expiration background worker.
Syntax
TTL <key> <seconds>
Parameters
key: The key to which the expiration time should be applied.
seconds: Time-to-live duration in seconds.
Example
TTL session_token 3600
Response
OK :)
Notes
- Expired keys are automatically removed from the database.
- Once a key expires, it behaves as if it never existed.
- Expiration metadata is maintained in a Min Heap for efficient processing.
- Command Time Complexity: O(log n).
- Applying TTL to an existing key updates its expiration time.
DEL
Deletes a key and its associated value from ThermalKV.
The command first checks whether the key is present in memory. If the key is not found in memory, ThermalKV checks the Cold Store and removes the persisted value if it exists. Once deleted, the key can no longer be retrieved using GET.
Syntax
DEL <key>
Parameters
key: The key to be deleted.
Example
DEL username
Response
OK :)
Notes
- Keys can be deleted regardless of whether they are currently hot (in memory) or cold (in persistent storage).
- Associated metadata, including expiration information, is removed along with the key.
- After deletion, any subsequent
GET request for the key will return Key not found :(.
COOL
Manually cools a key by moving its value from memory to persistent storage.
When a key is cooled, its value is written to the Cold Store and removed from active memory. ThermalKV then records the storage offset in the Cold Index, allowing the value to be located and restored efficiently when accessed later.
Syntax
COOL <key>
Parameters
key: The key to be moved to cold storage.
Example
COOL large_dataset
Response
OK :)
Notes
- The key remains accessible after cooling.
- Only the value is moved to persistent storage; lookup metadata remains available for fast access.
- ThermalKV stores the value's offset in the Cold Index to enable efficient retrieval.
- Accessing a cooled key through
GET automatically melts it back into memory.
- This command can be useful for manually freeing memory occupied by large or infrequently used values.
EXISTS
Checks whether a key exists in ThermalKV.
Syntax
EXISTS <key>
Parameters
key: The key to check.
Example
EXISTS username
Response
true
or
false
Notes
- Returns
true if the key exists.
- Returns
false if the key does not exist.
- The command checks both HOT memory and the Cold Store.
COUNT
Returns the total number of keys currently stored in HOT memory.
Syntax
COUNT
Example
COUNT
Response
42
Notes
- Only keys currently present in HOT memory are counted.
- Keys that have been cooled to persistent storage are not included.
KEYS
Returns a list of all keys currently stored in HOT memory.
Syntax
KEYS
Example
KEYS
Response
username
session_token
user_profile
Notes
- Only HOT keys are returned.
- Cooled keys stored in persistent storage are not included in the output.
INFO
Displays runtime statistics and storage information for the ThermalKV instance.
Syntax
INFO
Example
INFO
Sample Output
===== ThermalKV Info =====
HOT Keys : 125
COOL Keys : 478
HOT Memory Usage : 10485760 bytes
Max HOT Memory : 52428800 bytes
Cooling Threshold : 100
Cold File Size : 73400320 bytes
Metrics
HOT Keys: Number of keys currently stored in memory.
COOL Keys: Number of keys currently stored in cold storage.
HOT Memory Usage: Memory currently consumed by HOT data.
Max HOT Memory: Maximum memory allocated for HOT storage.
Cooling Threshold: Inactivity threshold used by the Cooling worker.
Cold File Size: Current size of the Cold Store file on disk.
Notes
- Useful for monitoring memory utilization and storage distribution.
- Provides a quick overview of the current state of the ThermalKV instance.
- Values are generated in real time when the command is executed.
Background Workers
Expiration Worker
The Expiration Worker is responsible for automatically removing keys whose TTL (Time-To-Live) has expired.
When a TTL is assigned to a key using the TTL command, ThermalKV calculates the expiration timestamp and inserts the entry into a Min Heap. The heap is ordered by expiration time, ensuring that the next key to expire is always available at the top of the heap.
Rather than continuously scanning all keys, the Expiration Worker follows an event-driven approach. It determines the time remaining until the next expiration and enters a sleep state for that duration. When the sleep period ends, the worker wakes up, removes the expired key, and processes any additional keys that have also reached their expiration time.
After all currently expired entries have been handled, the worker calculates the next expiration interval and returns to sleep.
Workflow
- A TTL is assigned to a key.
- The expiration timestamp is inserted into the Min Heap.
- The Expiration Worker determines the nearest expiration time.
- The worker sleeps until that expiration is reached.
- Expired keys are removed from ThermalKV.
- The worker repeats the process for the next scheduled expiration.
Benefits
- Eliminates the need for periodic full-database scans.
- Efficiently handles large numbers of TTL entries.
- Minimizes CPU usage by sleeping when no expirations are due.
- Processes expirations in chronological order using the Min Heap.
Data Structure
The Expiration Worker uses a Min Heap to maintain expiration events, allowing the next key to expire to be identified efficiently.
This design enables ThermalKV to scale to large numbers of expiring keys while keeping expiration processing lightweight and predictable.
Snapshot Worker
The Snapshot Worker is responsible for preserving HOT data across server restarts.
At regular intervals, the worker creates a snapshot of the current in-memory key-value store and writes it to a file named snapshot.dat. This snapshot serves as a persistent representation of the active HOT data, allowing ThermalKV to restore its state when the server starts again.
By periodically saving the contents of memory to disk, ThermalKV reduces the risk of data loss and provides persistence without requiring every write operation to be immediately written to storage.
Workflow
- The Snapshot Worker wakes up at a configured interval.
- The current HOT key-value map is read.
- A snapshot of the data is generated.
- The snapshot is written to
snapshot.dat.
- The worker returns to sleep until the next snapshot cycle.
Benefits
- Preserves HOT data across server restarts.
- Reduces recovery time during startup.
- Avoids the overhead of persisting every operation individually.
- Provides a lightweight persistence mechanism for active data.
Snapshot File
snapshot.dat
This file contains a serialized snapshot of the current in-memory key-value store and is used during startup to restore previously persisted HOT data.
Notes
- Only data currently present in HOT memory is included in the snapshot.
- Snapshots are created periodically rather than after every write operation.
- More recent snapshots provide a more up-to-date recovery point after an unexpected shutdown.
Cooling Worker
The Cooling Worker is responsible for managing memory usage by moving less valuable HOT data to persistent storage when memory pressure increases.
The worker is activated when the configured HOT memory limit is reached. Rather than cooling keys arbitrarily, ThermalKV calculates a Cooling Score for each key based on factors such as the size of the stored value and how recently it was accessed.
Keys with higher Cooling Scores are considered better candidates for cooling because they consume more memory while providing less immediate value in HOT storage.
The Cooling Worker continues moving keys from memory to the Cold Store until memory usage falls back within the configured limit.
Workflow
- HOT memory usage reaches the configured limit.
- The Cooling Worker evaluates eligible keys.
- A Cooling Score is calculated using factors such as:
- Data size
- Last access time
- Keys with the highest Cooling Scores are selected.
- Selected values are moved to the Cold Store.
- Cold Index entries are created for fast retrieval.
- The process continues until memory usage is back under control.
Cooling Score
The Cooling Score is designed to identify keys that provide the greatest memory savings with the least impact on performance.
In general:
- Larger values receive higher priority for cooling.
- Less recently accessed values receive higher priority for cooling.
- Frequently accessed or recently used values are more likely to remain HOT.
Benefits
- Prevents HOT memory from exceeding configured limits.
- Prioritizes cooling of large, inactive values.
- Maximizes effective memory utilization.
- Enables datasets larger than available RAM.
- Maintains transparent access through automatic melting during retrieval.
Notes
- Cooling is triggered only when memory usage reaches the configured HOT memory limit.
- Cooled keys remain accessible through the
GET command.
- Accessing a cooled key automatically melts it back into memory.
- The Cooling Worker operates continuously until memory usage falls below the configured threshold.
Compaction Worker
The Compaction Worker is responsible for maintaining the efficiency of the Cold Store.
As keys are cooled, melted, updated, and deleted over time, the cold.dat file can become fragmented. This fragmentation may leave unused regions within the file, causing its size to grow unnecessarily and reducing storage efficiency.
When the Cold Store becomes sufficiently large and fragmented, the Compaction Worker rebuilds the file using the current Cold Index and the existing Cold Store data. During this process, only active entries are preserved, and a new optimized file layout is generated.
The result is a smaller, more efficient Cold Store with updated offsets for all retained entries.
Workflow
- ThermalKV detects that the Cold Store has become large and heavily fragmented.
- The Compaction Worker begins a compaction cycle.
- Active entries are identified using the current Cold Index.
- Data is read from the existing
cold.dat file.
- A new compacted Cold Store is generated containing only valid entries.
- The Cold Index is updated with the new storage offsets.
- The old fragmented data is discarded.
Benefits
- Reduces wasted disk space.
- Eliminates fragmentation within the Cold Store.
- Improves storage efficiency.
- Keeps lookup offsets accurate and optimized.
- Prevents unbounded growth of the
cold.dat file.
Notes
- Compaction only affects data stored in the Cold Store.
- HOT data stored in memory is not involved in the compaction process.
- The process uses the current Cold Index as the source of truth for identifying active entries.
- After compaction, all active cooled keys remain accessible through normal
GET operations.
- Compaction is triggered only when the Cold Store reaches a level of size and fragmentation that justifies rebuilding the file.
The Story Behind ThermalKV
The idea behind ThermalKV did not come from databases, cache eviction policies, or distributed systems.
It came from my own experience as an artist.
While painting, I often found myself squeezing far more paint from a tube than I actually needed. After finishing a section, there would still be plenty of paint left on the palette.
At that point, I had two choices.
The first option was to throw the paint away and get fresh paint from the tube the next time I needed that color.
Technically, this works.
Practically, it is terrible.
Not only does it waste paint, but opening the same paint tube again and again is surprisingly annoying. Most artists will never admit it, but a significant amount of creative engineering happens simply because we are too lazy to repeat small tasks.
The second option is what many artists actually do.
Leave the paint on the palette.
Let it dry.
And when it's needed again, add a little water and bring it back to life.
The paint is no longer in its original state, but it is still there, still useful, and much cheaper than constantly starting over.
One day I realized that data has a very similar problem.
Traditional caches usually force you into one of two choices:
- Keep everything in RAM and pay the memory cost.
- Evict the data and fetch it again from the database later.
Neither option feels great when the data is large.
Consider an AI application storing chat histories. A single conversation can grow to thousands of tokens. Multiply that by thousands of users and suddenly keeping everything in RAM becomes extremely expensive.
But repeatedly fetching those large conversations from a database is expensive too.
The real cost is not just storage.
The real cost is repeatedly moving the same data back and forth.
So why not treat data the way artists treat paint?
Don't throw it away.
Cool it down.
When data becomes inactive, ThermalKV moves it from HOT memory into persistent storage. The value is preserved, its location is remembered, and RAM is freed for more important work.
The data has not been deleted.
It has simply cooled.
And when it is needed again, ThermalKV melts it back into memory automatically.
That single observation became the foundation of the entire system.
HOT data.
COOL data.
Cooling.
Melting.
Even the name ThermalKV comes from the idea that data does not have to be either fully alive in RAM or completely gone. It can change temperature.
Just like dried paint on an artist's palette, sometimes the smartest thing to do is let something cool down and bring it back only when you need it again.