# How to Set Up LunaTV with Upstash: Complete Configuration Guide

> Learn how to set up LunaTV with Upstash by configuring essential environment variables. Persist user accounts, play records, and favorites seamlessly with this complete guide.

- Repository: [MoonTechLab/LunaTV](https://github.com/MoonTechLab/LunaTV)
- Tags: how-to-guide
- Published: 2026-09-09

---

**To set up LunaTV with Upstash, configure three environment variables—`NEXT_PUBLIC_STORAGE_TYPE=upstash`, `UPSTASH_URL`, and `UPSTASH_TOKEN`—and the application will automatically instantiate `UpstashRedisStorage` from [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) to persist user accounts, play records, and favorites.**

LunaTV, an open-source media streaming platform from **MoonTechLab/LunaTV**, uses a pluggable storage architecture defined by the `IStorage` interface. While the application defaults to local storage for development, production deployments require a persistent backend like **Upstash Redis** to handle user data, search history, and favorites across server restarts.

## Select Upstash as the Storage Backend

LunaTV determines which storage provider to use by reading the **`NEXT_PUBLIC_STORAGE_TYPE`** environment variable at runtime. In [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts), the application switches between `localstorage`, `redis`, `upstash`, and `kvrocks` implementations.

Set the variable to `upstash` to trigger instantiation of the `UpstashRedisStorage` class:

```typescript
// src/lib/db.ts – storage selection logic
const STORAGE_TYPE =
  (process.env.NEXT_PUBLIC_STORAGE_TYPE as
    | 'localstorage'
    | 'redis'
    | 'upstash'
    | 'kvrocks'
    | undefined) || 'localstorage';

// ... later in the factory function:
case 'upstash':
  return new UpstashRedisStorage();

```

The factory defaults to `localstorage` if the variable is undefined, making the explicit `upstash` value required for cloud deployments.

## Provide Upstash Connection Credentials

The **`UpstashRedisStorage`** class creates a singleton Redis client using the `@upstash/redis` package. This requires two sensitive environment variables consumed in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) (lines 511–526):

- **`UPSTASH_URL`** – The HTTP endpoint of your Upstash Redis instance.
- **`UPSTASH_TOKEN`** – The read/write authentication token.

```typescript
// src/lib/upstash.db.ts – client initialization (lines 511-526)
const upstashUrl = process.env.UPSTASH_URL;
const upstashToken = process.env.UPSTASH_TOKEN;

if (!upstashUrl || !upstashToken) {
  throw new Error('UPSTASH_URL and UPSTASH_TOKEN env variables must be set');
}

client = new Redis({
  url: upstashUrl,
  token: upstashToken,
  retry: { 
    retries: 3, 
    backoff: (c) => Math.min(1000 * Math.pow(2, c), 30000) 
  },
});

```

The client implements exponential backoff for resilience, retrying failed connections up to three times with a maximum delay of 30 seconds.

## Configure the Environment

Create a `.env.local` file in your project root with the three required variables. Replace the placeholder values with your actual Upstash credentials from the Upstash Console:

```dotenv

# Storage driver selection (src/lib/db.ts line 11)

NEXT_PUBLIC_STORAGE_TYPE=upstash

# Upstash Redis connection (src/lib/upstash.db.ts lines 511-516)

UPSTASH_URL=https://my-upstash-redis.upstash.io
UPSTASH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

```

LunaTV uses `NEXT_PUBLIC_STORAGE_TYPE` to route all database operations through the Upstash implementation rather than the default local storage fallback.

## Deploy and Verify the Integration

With the environment variables configured, start the Next.js application:

```bash
npm run dev

# or for production:

npm start

```

On first launch, the `UpstashRedisStorage` constructor lazily initializes the Redis client, and the `DbManager` automatically triggers data migrations (lines 447–464 in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts)). These migrations convert legacy flat-key structures into optimized Redis hashes. Watch the server console for migration logs indicating successful schema updates.

Confirm the setup by checking the server logs for the message *"Upstash Redis client created successfully"* (line 32 in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts)). Test persistence by registering a new user via the API:

```bash
curl -X POST https://your-domain.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"Secret123"}'

```

This request is handled by [`src/app/api/login/route.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/app/api/login/route.ts), which calls `db.registerUser()`. With Upstash configured, the user record persists in your Redis instance rather than in-memory storage. Verify the data exists by querying the `sys:users` set directly through the Upstash CLI or REST API:

```bash
curl -X GET "https://my-upstash-redis.upstash.io/smembers/sys:users" \
  -H "Authorization: Bearer $UPSTASH_TOKEN"

```

## Summary

- **Set `NEXT_PUBLIC_STORAGE_TYPE=upstash`** in [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts) to activate the Upstash storage driver.
- **Provide `UPSTASH_URL` and `UPSTASH_TOKEN`** to the singleton client initialized in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) (lines 511–526).
- **Automatic migrations** handle schema updates when the server boots, converting legacy data to Redis hashes.
- **Verify connectivity** through server logs and by querying the `sys:users` set via the Upstash REST API.

## Frequently Asked Questions

### What storage backends does LunaTV support besides Upstash?

According to the source code in [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts), LunaTV supports four storage implementations: `localstorage` (default for development), `redis` (standard Redis), `upstash` (Upstash Redis), and `kvrocks`. Each implements the `IStorage` interface, allowing seamless swapping without code changes.

### Why does LunaTV require both UPSTASH_URL and UPSTASH_TOKEN?

The `UpstashRedisStorage` class uses these variables to construct the `@upstash/redis` client with HTTP-based authentication. The URL identifies your specific Redis database endpoint, while the token provides authenticated access. Missing either variable triggers an explicit error throw at lines 514–516 in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts).

### How does LunaTV handle connection failures to Upstash?

The Redis client configuration in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) implements a retry strategy with exponential backoff. It attempts failed operations three times, using a backoff calculation of `Math.min(1000 * Math.pow(2, c), 30000)` where `c` is the attempt count, ensuring maximum retry intervals cap at 30 seconds.

### Where is user data stored when using Upstash with LunaTV?

User accounts are stored in the `sys:users` Redis set, while individual user profiles, play records, and favorites are maintained as Redis hashes. The [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) file handles these data structures, and the [`src/app/api/login/route.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/app/api/login/route.ts) endpoint writes authentication data through this layer.