# How to Configure Upstash for LunaTV Deployments: Complete Setup Guide

> Configure Upstash for LunaTV deployments by setting environment variables NEXT_PUBLIC_STORAGE_TYPE UPSTASH_URL and UPSTASH_TOKEN for managed Redis storage. Learn more now.

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

---

**Set `NEXT_PUBLIC_STORAGE_TYPE=upstash` and provide `UPSTASH_URL` and `UPSTASH_TOKEN` environment variables to enable managed Redis storage for user data, favorites, and playback history in LunaTV.**

LunaTV is an open-source media platform that supports multiple storage backends for persisting runtime data. Configuring Upstash provides a fully managed, serverless Redis experience ideal for cloud-native deployments where you want to avoid maintaining your own Redis infrastructure.

## Prerequisites for Upstash Integration

Before deploying, ensure you have:

- An active Upstash account with a Redis database provisioned
- The HTTPS endpoint URL (`UPSTASH_URL`) and authentication token (`UPSTASH_TOKEN`) from your Upstash console
- LunaTV source code that includes the Upstash storage implementation found in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts)

## Required Environment Variables

LunaTV reads three specific environment variables at runtime to initialize the Upstash connection. According to the source code in [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts), the factory function checks `process.env.NEXT_PUBLIC_STORAGE_TYPE` and instantiates `UpstashRedisStorage` when the value is `upstash`.

Configure these variables in your deployment environment:

1. **`NEXT_PUBLIC_STORAGE_TYPE`** – Must be set to `upstash` (defaults to `localstorage` if omitted).
2. **`UPSTASH_URL`** – The HTTPS endpoint provided by Upstash (e.g., `https://clever-duck-12345.upstash.io`).
3. **`UPSTASH_TOKEN`** – The read-write token for your Upstash Redis database.

If either `UPSTASH_URL` or `UPSTASH_TOKEN` is undefined, the constructor in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) throws an error, preventing the application from starting with invalid credentials.

## Docker Compose Configuration

For containerized deployments using Docker Compose, define the environment variables as follows:

```yaml
services:
  lunatv:
    image: ghcr.io/moontechlab/lunatv:latest
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_STORAGE_TYPE=upstash
      - UPSTASH_URL=https://your-endpoint.upstash.io
      - UPSTASH_TOKEN=your-upstash-token
      - USERNAME=admin
      - PASSWORD=your_secure_password

```

## How the Upstash Storage Layer Works

Understanding the implementation details in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) helps optimize your deployment and troubleshoot issues.

### Storage Selection Logic

The application uses a factory pattern in [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts) to select storage backends. The middleware ([`src/middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/middleware.ts)) and database layer read `process.env.NEXT_PUBLIC_STORAGE_TYPE` at runtime. When set to `upstash`, the factory creates an instance of `UpstashRedisStorage` rather than the default local storage or standard Redis implementations.

### Singleton Client Pattern

`UpstashRedisStorage` obtains a singleton Redis client via `getUpstashRedisClient()`. This function constructs the client using your `UPSTASH_URL` and `UPSTASH_TOKEN`, ensuring connection reuse across requests and preventing connection pool exhaustion in serverless environments.

### Automatic Retry Mechanism

All Redis operations wrap in a `withRetry()` utility defined in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts). This wrapper automatically retries transient connection failures (such as `ECONNREFUSED`) up to three times before throwing, providing resilience against temporary network interruptions.

### Data Model and Hash Keys

Upstash stores each user's data in separate **Hash** keys following the pattern `u:{user}:{type}`. The storage layer manages:

- `u:{user}:pr` – Playback records and watch history
- `u:{user}:fav` – Favorites and bookmarks
- `u:{user}:search` – Search query history

The `UpstashRedisStorage` class provides methods for CRUD operations on these hashes, password hashing, admin configuration, and data migration utilities.

## Programmatic Usage Examples

For custom scripts or server-side operations, import the storage class directly:

```typescript
import { UpstashRedisStorage } from '@/lib/upstash.db';

// The client automatically reads UPSTASH_URL and UPSTASH_TOKEN from process.env
const storage = new UpstashRedisStorage();

// Add a favorite movie for user "alice"
await storage.setFavorite('alice', 'movie:12345', {
  id: '12345',
  title: 'Inception',
  type: 'movie',
  ts: Date.now(),
});

```

To manually switch storage modes in code, use the factory pattern from [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts):

```typescript
export function createStorage(): IStorage {
  const type = process.env.NEXT_PUBLIC_STORAGE_TYPE as
    | 'redis' | 'kvrocks' | 'upstash' | undefined;

  if (type === 'upstash') return new UpstashRedisStorage();
  // Additional branches for other storage types...
}

```

## Summary

- Set `NEXT_PUBLIC_STORAGE_TYPE=upstash` to activate the Upstash storage backend in LunaTV.
- Provide `UPSTASH_URL` and `UPSTASH_TOKEN` environment variables; missing values trigger startup errors.
- The `UpstashRedisStorage` class in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) manages connection pooling, automatic retries, and data serialization.
- User data persists in Upstash Redis hashes using keys formatted as `u:{user}:{data_type}`.
- The middleware in [`src/middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/middleware.ts) reads the storage type early in the request pipeline to ensure consistent backend selection.

## Frequently Asked Questions

### What happens if UPSTASH_URL or UPSTASH_TOKEN is missing?

The application throws a configuration error during initialization. The constructor in [`src/lib/upstash.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/upstash.db.ts) validates these environment variables and prevents startup to avoid runtime failures in production.

### Can I migrate existing data from local storage to Upstash?

LunaTV includes data migration utilities within the storage layer, but you must manually export data from your current backend and import it into Upstash. The application does not automatically migrate existing local storage data to Redis on startup.

### Does the Upstash integration support Redis pub/sub features?

The current implementation focuses on Hash-based persistence for user records, favorites, and playback history. While the underlying Upstash client supports pub/sub capabilities, the core `UpstashRedisStorage` class does not implement real-time messaging features.

### How does the retry mechanism handle network failures?

All Redis operations wrap in `withRetry()`, which catches transient errors such as `ECONNREFUSED` and retries the operation up to three times. This ensures resilience against temporary network interruptions common in serverless and edge computing environments.