# How Plane Uses Redis: Real-Time Collaboration, Caching, and Background Jobs

> Discover how Plane leverages Redis for real-time collaboration, efficient caching of tokens and codes, and robust background job processing with Celery workers.

- Repository: [Plane/plane](https://github.com/makeplane/plane)
- Tags: internals
- Published: 2026-08-22

---

**Plane uses Redis as a high-performance in-memory data store to enable real-time collaborative editing via pub/sub, cache authentication tokens and magic-link codes, and broker background jobs for Celery workers.**

Plane, the open-source project management platform from `makeplane/plane`, relies on Redis as the central nervous system connecting its Django API backend and real-time live-editing services. This **in-memory data structure store** acts as a low-latency message bus, caching layer, and task queue broker that allows the application to scale horizontally while maintaining sub-second response times.

## Real-Time Pub/Sub for Collaborative Editing

The live-editing service (`apps/live`) integrates the Hocuspocus collaborative-editing framework, which requires a fast messaging infrastructure to synchronize document updates across multiple server instances. Plane implements this through Redis pub/sub channels.

In [`apps/live/src/extensions/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/extensions/redis.ts), the application registers a Redis extension that subscribes to the `hocuspocus:admin` channel. When one server instance processes a document change, it publishes the update through this channel, ensuring that every connected user sees the same changes instantly regardless of which server instance handles their connection.

```typescript
// Broadcast a document change to every server via the Redis extension
await redisExtension.broadcastToDocument("my-doc", { ops: [...] });

```

This architecture decouples the individual server instances, allowing Plane to scale the live-editing service horizontally without requiring sticky sessions or complex inter-server communication protocols.

## Global State and Broadcast Messages

Redis serves as the control plane for administrative operations that must execute across all running server instances simultaneously. When operators need to perform global actions—such as force-closing a specific document or broadcasting maintenance notifications—Plane serializes these commands and publishes them through the admin channel.

The implementation in [`apps/live/src/extensions/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/extensions/redis.ts) exposes two critical methods:

- **`publishAdminCommand`**: Serializes and publishes administrative commands to the `hocuspocus:admin` channel
- **`broadcastToDocument`**: Dispatches document-specific messages to all subscribers

```typescript
// Publish an admin command to all servers (e.g., force-close a document)
await redisManager.getClient()?.publish(
  "hocuspocus:admin",
  JSON.stringify({ command: "FORCE_CLOSE", documentId: "doc-123" })
);

```

Each live server receives these messages via the same subscription channel and executes the corresponding handler, ensuring consistent state across the entire fleet.

## Caching and Session Management

The Django API backend (`apps/api`) leverages Redis to store transient data that requires fast access but does not need permanent persistence. This includes **authentication tokens**, **magic-link verification codes**, and **rate-limit counters**.

The Redis client initialization occurs in [`apps/api/plane/settings/redis.py`](https://github.com/makeplane/plane/blob/main/apps/api/plane/settings/redis.py), which creates a connection using the `REDIS_URL` environment variable:

```python

# Store a magic-link verification code in Redis (API auth flow)

await redis_manager.set(f"magic:{email}", token, ttl=300)

```

By storing magic-link codes with a 300-second TTL (time-to-live), Plane eliminates database writes for temporary authentication flows while preventing memory accumulation. The same client handles rate-limiting counts, protecting the API from brute-force attacks without adding query load to the primary PostgreSQL database.

## Background Job Broker

Plane's asynchronous task processing relies on Celery workers configured to use Redis as both the **message broker** and **result backend**. This configuration appears in the Docker Compose orchestration files ([`docker-compose.yml`](https://github.com/makeplane/plane/blob/main/docker-compose.yml) and [`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml)), which define the `REDIS_URL` environment variable for worker processes.

When the API enqueues background tasks—such as email notifications, data exports, or webhook deliveries—Celery serializes these tasks into Redis lists. Worker instances poll these lists, execute the tasks, and write results back to Redis, enabling reliable job queuing and result retrieval without blocking the main application threads.

## Connection Resilience and Health Management

To ensure production reliability, Plane wraps Redis connections in a singleton manager that handles connection failures gracefully. The `RedisManager` class defined in [`apps/live/src/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/redis.ts) implements exponential backoff strategies, connection event listeners, and convenience CRUD helpers.

```typescript
// Initialize the Redis manager (Live server)
await redisManager.initialize();

```

This abstraction provides **connection pooling**, automatic reconnection logic, and graceful shutdown handling, insulating application code from transient network failures or Redis node failover events.

## Summary

- **Pub/Sub Messaging**: Redis powers the `hocuspocus:admin` channel in [`apps/live/src/extensions/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/extensions/redis.ts) for real-time document synchronization across server instances.
- **Administrative Commands**: Global operations like force-closing documents use `publishAdminCommand` to reach all running servers simultaneously.
- **Session Storage**: The API layer stores magic-link codes and rate limits via the client defined in [`apps/api/plane/settings/redis.py`](https://github.com/makeplane/plane/blob/main/apps/api/plane/settings/redis.py) with configurable TTL values.
- **Task Queue**: Celery workers consume Redis-backed queues for asynchronous job processing, configured through Docker Compose environment variables.
- **Resilience**: The `RedisManager` singleton in [`apps/live/src/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/redis.ts) provides connection health monitoring and automatic retry logic.

## Frequently Asked Questions

### Does Plane require Redis to function?

Yes, Redis is mandatory for Plane's real-time collaboration features and background task processing. The live-editing service (`apps/live`) cannot synchronize document states across instances without the pub/sub capabilities provided by Redis, and the API relies on Redis for caching authentication flows and rate limiting.

### How does Plane handle Redis connection failures?

According to the source code in [`apps/live/src/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/redis.ts), Plane implements a `RedisManager` singleton that includes exponential backoff strategies and connection event listeners. This wrapper automatically attempts reconnection during network partitions and provides graceful degradation for transient Redis unavailability.

### What Redis commands does Plane use for collaborative editing?

The live server primarily utilizes the **PUBLISH** and **SUBSCRIBE** commands through the `hocuspocus:admin` channel. The `broadcastToDocument` method in [`apps/live/src/extensions/redis.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/extensions/redis.ts) publishes JSON-serialized operations, while each instance subscribes to receive and process incoming document updates from other servers.

### Can I use an external Redis provider with Plane?

Yes. Both `apps/live/.env.example` and `apps/api/.env.example` expose `REDIS_URL`, `REDIS_HOST`, and `REDIS_PORT` configuration variables. You can point these to external Redis clusters, AWS ElastiCache, or Redis Cloud instances rather than the containerized Redis services defined in the default [`docker-compose.yml`](https://github.com/makeplane/plane/blob/main/docker-compose.yml).