DEV Community

Cover image for Introducing keyv-upstash: Seamless Key-Value Storage for Serverless Redis
Hamidreza Mahdavipanah
Hamidreza Mahdavipanah

Posted on • Originally published at hamidreza.tech on

Introducing keyv-upstash: Seamless Key-Value Storage for Serverless Redis

Github: https://github.com/mahdavipanah/keyv-upstash

keyv-upstash is a storage adapter for Keyv that connects it to Upstash Redis, a serverless Redis platform. With this adapter, you get a simple, efficient, and flexible solution for key-value storage in serverless applications.

What is Keyv?

Keyv is a versatile key-value storage library that supports multiple backends through adapters. It provides:

  • TTL-based Expiry: Ideal for caching or persistent storage.

  • Namespace Support: Avoids key collisions in shared environments.

  • Extensibility: Easy to build custom modules or add features like compression.

Keyv works with many adapters, such as Redis, SQLite, MongoDB, and now, keyv-upstash for Upstash Redis.


Why keyv-upstash?

keyv-upstash extends Keyv's capabilities by integrating it with Upstash Redis, offering:

  1. Serverless Compatibility: Upstash Redis works without managing connections, scaling automatically, perfect for serverless apps.

  2. Flexible: Compatible with Keyv’s ecosystem and supports third-party extensions.

  3. Cache Layering: Combine with Cacheable for multi-layered caching.

  4. No Vendor Lock-In: Is fully compatible with serverless-redis-http so you can setup your own serverless Redis and use this adapter with it.


Getting Started

Follow these steps to integrate keyv-upstash:

1. Install Keyv and keyv-upstash

Install Keyv and the Upstash adapter:

npm install keyv keyv-upstash
Enter fullscreen mode Exit fullscreen mode

Optional: Install Cacheable for layered caching:

npm install cacheable
Enter fullscreen mode Exit fullscreen mode

2. Set Up keyv-upstash

Make sure you have a Redis database created in Upstash. Here’s how to use keyv-upstash in your project:

Basic Usage

import Keyv from 'keyv';
import { KeyvUpstash } from 'keyv-upstash';

const keyv = new Keyv({
  store: new KeyvUpstash({
    url: 'your-upstash-redis-url',
    token: 'your-upstash-redis-token',
  }),
});

// Set a key-value pair
await keyv.set('foo', 'bar');

// Retrieve the value
const value = await keyv.get('foo');
console.log(value); // 'bar'
Enter fullscreen mode Exit fullscreen mode

Using Namespaces

Namespaces prevent key collisions and allow scoped clearing:

const keyv = new Keyv({
  store: new KeyvUpstash({
    url: 'your-upstash-redis-url',
    token: 'your-upstash-redis-token',
    namespace: 'my-namespace',
  }),
});

await keyv.set('foo', 'bar'); // Stored as 'my-namespace::foo'
Enter fullscreen mode Exit fullscreen mode

Cache Layering with Cacheable

Combine keyv-upstash with Cacheable for multi-layer caching:

import { Cacheable } from 'cacheable';

const redisStore = new KeyvUpstash({
  url: 'your-upstash-redis-url',
  token: 'your-upstash-redis-token',
});

const cache = new Cacheable({
  primary: new Map(), // Fast in-memory caching
  secondary: redisStore, // Persistent Redis caching
});

await cache.set('foo', 'bar', { ttl: 1000 }); // Stores in both layers
const value = await cache.get('foo'); // Fast lookup from memory or Redis
console.log(value); // 'bar'
Enter fullscreen mode Exit fullscreen mode

Advanced Features

Batch Operations

Improve performance with setMany and getMany:

await keyv.setMany([
  { key: 'key1', value: 'value1' },
  { key: 'key2', value: 'value2' },
]);

const values = await keyv.getMany(['key1', 'key2']);
console.log(values); // ['value1', 'value2']
Enter fullscreen mode Exit fullscreen mode

Custom Configuration

Customize your setup with options like defaultTtl, keyPrefixSeparator, and clearBatchSize.

Top comments (0)