Skip to main content

What is a Key-Value Store / Database and how do you use it? Tutorial with examples

Key-value stores power some of the world's most popular applications, handling millions of operations per second. This tutorial series shows you how to implement fast, scalable data storage using Codehooks' built-in key-value database. Whether you're building a high-performance cache, managing user sessions, or creating real-time counters, you'll learn how to leverage key-value storage for optimal results.

What is a Key-Value Store (Database)?โ€‹

A key-value store is one of the simplest yet most powerful types of NoSQL databases. Think of it like a giant dictionary where you can store any piece of data (the value) under a unique name (the key). Companies like Instagram use key-value stores to handle billions of operations per day, while Discord relies on them to manage real-time state for millions of concurrent users.

For example (keys on the left, value on the right):

// Storing user data
"user:123" -> { name: "John", email: "[email protected]" }

// Storing a simple counter
"pageviews" -> 42

// Storing a session
"session:abc" -> { userId: 123, lastActive: "2024-03-20" }

Popular examples of key-value databases include:

  • Redis (used by GitHub, Twitter, and Stack Overflow)
  • Amazon DynamoDB (powers Amazon's shopping cart)
  • Apache Cassandra (handles data at Meta/Facebook)
  • etcd (manages Kubernetes clusters)

Why Use a Key-Value Store?โ€‹

Key-value stores offer several advantages:

  • Lightning-fast performance: Data retrieval happens in near-constant time (typically milliseconds)
  • Simple to implement: No complex schemas or relationships needed - just store and retrieve data by its key
  • Highly scalable: Perfect for distributed systems and cloud applications
  • Flexible data storage: Store any type of data as values - strings, numbers, JSON objects, or even binary data

Common Use Casesโ€‹

Key-value stores are ideal for:

  • Session management (widely used in web applications)
  • Caching (significantly reduces database load)
  • Real-time counters
  • User preferences
  • Feature flags
  • Shopping carts
  • Game states

Lets dive into the simple but powerful world of key-value stores and how you can learn to use them.

Getting Started with Codehooks Key-Value Storeโ€‹

Codehooks.io has a built-in key-value store (in addition to a NoSQL document database) that can be accessed from serverless JavaScript functions via the import statement. The simple code example below shows how the fundamental get and set functions operates on the key-value Datastore API.

index.js
import { app, Datastore } from 'codehooks-js';

// Create an API endpoint that manages a counter
app.post('/counter', async (req, res) => {
// Connect to the key-value database
const kv = await Datastore.open();

// Increment a page view counter
const viewCount = (await kv.get('viewCount')) || 0;
await kv.set('viewCount', viewCount + 1);

// note that the two lines above could have been replaced by:
// const viewCount = await kv.incr('viewCount', 1)

res.json({ viewCount });
});

export default app.init();

The code example above is a complete serverless backend application that can be be deployed instantly with codehooks.io. Deployment and test with curl is shown in the example commands below.

Deploy and test the serverless app from the project directory
$ coho deploy
Project: keyval-xxxx Space: dev
Deployed Codehook successfully! ๐Ÿ™Œ


$ curl -X POST \
'https://keyval-xxxx.api.codehooks.io/dev/counter' \
--header 'Accept: */*' \
--header 'x-api-key: 07ae0bba-aaaa-437c-bbbbb-dfd0b991fa0b'

{"viewCount": 1}

Keys are unique and orderedโ€‹

In the key-value store, each key is a unique string.

A key can only point to one value, and using "set" will always overwrite any existing value.

The example below shows three unique keys with their associated values.

'My first Key'  => 'My first value'
'My second Key' => 'My second value'
'Another key' => 'Another value'

Another important feature of the key-value store is how the keys are inserted into the key-value store. Each key string is inserted in a ascending sorted order. When retrieving a single key-value pair the sort order is not relevant. However, as we will cover in another part of this tutorial, when streaming multiple key-value pairs, the sorted stream order can be used to solve many important problems.

Values are stringsโ€‹

Just as with keys, values are also plain strings. The content of the value-string can be anything, but is must be encoded to a string before inserted into the key-value store, and (if needed) decoded when retrieving. The example below shows a variation of string values and encoded string values.

'my_url_key'  => 'https://codehooks.io/docs/'
'my_json_key' => '{"foo": "bar"}'
'my_num_key' => '42'
'my_buf_key' => '7b 22 66 6f 6f 22 3a 20 22 62 61 72 22 7d'
'my_user_key' => '4f90d13a42'

Tutorial overviewโ€‹

Summaryโ€‹

Key-value stores are a powerful yet simple way to manage data efficiently, making them ideal for high-performance applications. In this introduction, we've covered the fundamentals of key-value databases, their advantages, and common use cases. We've also demonstrated how easy it is to get started with Codehooks.io's built-in key-value store, showing a practical example of a serverless API that tracks views.

As you progress through this tutorial series, you'll learn how to perform essential operations, work with advanced features like TTL and multiple key spaces, and integrate the key-value store into real-world applications.

This concludes our brief introduction to key-value stores in codehooks.io.

Continue to Part-2 to learn how to master the basic operations of the key-value store.


Key-Value Store Tutorial FAQ

Common questions about key-value databases, operations, and advanced features covered in this 7-part tutorial series

What is a key-value store and why should I use it?
A key-value store is a simple yet powerful NoSQL database where you store data (values) under unique names (keys). Companies like Instagram and Discord use them because they offer lightning-fast performance (milliseconds), simple implementation, high scalability, and flexible data storage. They're ideal for sessions, caching, counters, user preferences, and real-time data.
What are the basic operations in a key-value database?
There are three fundamental operations: get (retrieve a value by key), set (store or update a value), and delete (remove a key-value pair). You can work with various data types including strings, numbers, JSON objects (by serializing/deserializing), and binary data (by encoding to strings). You can also perform batch operations to set or get multiple key-value pairs at once for better efficiency.
How do increment and decrement operations work?
Increment (incr) and decrement (decr) are atomic operations that update numerical values without reading first. They start at 0 by default and are perfect for counters, API usage tracking, inventory management, and analytics. For example, db.incr('pageviews', 1) increments a counter atomically, which is more efficient than get-update-set operations.
How can I work with multiple values and create time series data?
Keys are stored in sorted order, enabling powerful streaming capabilities with getAll(). By creating smart keys like /region/location/device/timestamp, you can build time series databases for IoT sensors or analytics. The getAll() method streams matching keys, perfect for retrieving data ranges or segments efficiently.
What is TTL and when should I use it?
TTL (Time-To-Live) automatically removes key-value pairs after a specified time period. Common use cases include: cache expiration (removing stale data), session management (auto-deleting expired sessions), temporary data storage (shopping carts), logging (keeping recent logs only), and rate limiting (resetting counters automatically). Set TTL in milliseconds: db.set('key', 'value', {ttl: 86400000}) for 24 hours.
What are key spaces (namespaces) and why use them?
Key spaces provide isolated namespaces within the same database, allowing you to have identical key names in different spaces without conflicts. They're essential for: organizing related data, preventing key collisions, achieving data isolation in multi-tenant applications, simplifying access control, and enhancing scalability. Use the keyspace option: db.set('key', 'value', {keyspace: 'users'}).
Can I manage the key-value store from the command line?
Yes, the Codehooks CLI provides three main commands: coho set (create/update), coho get (retrieve), and coho del (delete). You can use wildcards for pattern matching (coho get 'user-*' to get all user keys) and set TTL values (coho set 'key' 'value' --ttl 60000). The CLI is perfect for database administration and debugging.
What's the difference between Codehooks key-value store and Redis?
Codehooks provides a built-in key-value store alongside a NoSQL document database in a serverless environment, with no infrastructure to manage. It supports essential operations like get, set, delete, atomic counters (incr/decr), TTL, sorted keys, and namespaces. However, it offers only a small subset of Redis's extensive features - Redis has advanced data structures (lists, sets, hashes, streams) and hundreds of commands that Codehooks doesn't support. Codehooks is best for straightforward key-value needs within a fully managed backend platform.

Key-Value Store API documentation

You can find the documentation for the key-value store API here.