Plane: The Open-Source Jira/Linear Alternative — What Actually Happens When You Self-Host a 61k-Star Project Management Platform
You use Jira. Or Linear. Or ClickUp. Every day. Click "Create Issue," drag cards across a Kanban board, run a sprint retrospective. It works. Mostly.
But have you ever wondered what it takes to run one of these things yourself? Not the SaaS version — the actual software, on your own infrastructure, your own data, zero vendor lock-in.
Plane is a 61.9k-star open-source project management platform that replaces Jira, Linear, Monday, and ClickUp. Not a toy. A production-grade system with real-time collaboration, AI-powered workflows, a native MCP server for AI agents, and a microservice architecture running on PostgreSQL, Redis, RabbitMQ, and MinIO.
Here's what happens under the hood when you self-host it.
The Architecture: 10 Services, One Platform
Plane isn't a monolith. It's a distributed system disguised as a project management tool. Run docker-compose up and you're spinning up ten distinct services:
| Service | Role | Tech |
|---|---|---|
| web | Main React frontend — work items, cycles, pages, analytics | React 19, React Router 7, MobX, Tailwind, Vite |
| api | Core Django REST API — all data operations | Django 5.2, DRF, Celery, Channels |
| worker | Async background jobs (imports, exports, notifications) | Celery + RabbitMQ |
| beat-worker | Scheduled tasks (cleanup, reports, reminders) | Celery Beat |
| migrator | Schema migrations on deploy (runs once, exits) | Django migrations |
| live | Real-time WebSocket server (cursors, presence, live updates) | Node.js, WebSockets |
| proxy | SSL termination, routing, cert management (Caddy) | Caddy |
| space | Public sharing — publish projects/views without login | React |
| admin | Instance administration (billing, licensing, SSO) | React |
| silo | Third-party integrations (GitHub, GitLab, Slack OAuth/webhooks) | Python |
Plus five infrastructure dependencies:
-
PostgreSQL 15.7+ — primary data store (
max_connections=1000) - Valkey 7.2 (Redis-compatible) — cache, sessions, real-time collab state
- RabbitMQ 3.13 — message queue for all async work
-
MinIO/S3 (via
pgsty/silo) — file uploads, attachments, exports - OpenSearch (optional) — full-text search indexing
This isn't "Django + React." This is a platform.
What Happens When You Create a Work Item
Click "New Issue" in the React frontend. Here's the path:
- Frontend (MobX store) → optimistic UI update, instant feedback
-
REST API call →
POST /api/v1/workspaces/{slug}/projects/{project_id}/work-items/ - Django viewset → validation, permissions, business logic
-
PostgreSQL →
INSERTintowork_itemswith all relations (project, assignee, state, cycle, module) - Redis cache invalidation → affected queries purged
-
RabbitMQ message →
work_item.createdevent published - Worker picks up → sends notifications, updates search index (OpenSearch), triggers webhooks (Silo)
- Live service → WebSocket broadcast to all connected clients in that workspace → real-time UI update for collaborators
Zero polling. Zero manual refresh. The WebSocket connection stays open. When your teammate moves a card, you see it move instantly.
Real-Time Collaboration: The live Service
Most "real-time" tools fake it with long-polling or frequent AJAX. Plane runs a dedicated Node.js WebSocket server (apps/live).
┌────────────────────────────────────────────────────────────────────────────────────────────│
│ Browser A │◄──────────────────────────────────────────────────────────────────────────────────────││ live svc │
└──────────────────────────────────────────────────────────────────────────────────────────────│└────│
───────────────────────────────────────────────────────────────────────────────────────────────────────────────│ Redis Pub/Sub
┌─────────────────────────────────────────────────────────────────────────────────────────────────────│
│ Browser B │◄──────────────────────────────────────────────────────────────────────────────────││ live svc │
└──────────────────────────────────────────────────────────────────────────────────────│└────│
- Presence: Who's online, where their cursor is, what they're viewing
- Optimistic sync: Local changes broadcast immediately; server resolves conflicts
-
Scalability: Multiple
livereplicas behind Redis Pub/Sub — horizontal scaling works
The live service doesn't touch PostgreSQL. Pure real-time layer. Django handles persistence; live handles now.
Background Jobs: Celery + RabbitMQ Done Right
Import 10,000 issues from Jira. You don't wait. The API returns 202 Accepted immediately.
What happens next:
- API enqueues
jira_import_jobto RabbitMQ - Worker (Celery) picks it up — runs in isolation, no request timeout
- Chunks the import, processes batches, updates progress in Redis
- Each created work item emits
work_item.created→ RabbitMQ → other workers → notifications, search indexing, webhooks - Beat worker runs nightly cleanup: expired sessions, stale locks, old audit logs
This is durable execution. Worker crashes mid-import? RabbitMQ requeues. The job completes. No lost work.
Self-Hosting: Data Sovereignty Without the DevOps Nightmare
Plane's Docker Compose file is 177 lines. One command brings up the entire stack:
# docker-compose.yml (simplified)
services:
api:
build: ./apps/api
depends_on: [plane-db, plane-redis]
env_file: ./apps/api/.env
worker:
build: ./apps/api
command: ./bin/docker-entrypoint-worker.sh
depends_on: [api, plane-db, plane-redis, plane-mq]
beat-worker:
command: ./bin/docker-entrypoint-beat.sh
migrator:
restart: "no" # runs once, exits
command: ./bin/docker-entrypoint-migrator.sh
live:
build: ./apps/live
proxy:
build: ./apps/proxy
ports: ["80:80", "443:443"]
plane-db:
image: postgres:15.7-alpine
command: postgres -c 'max_connections=1000'
plane-redis:
image: valkey/valkey:7.2.11-alpine
plane-mq:
image: rabbitmq:3.13.6-management-alpine
plane-minio:
image: docker.io/pgsty/silo:RELEASE.2026-09-16T00-00-00Z
Details that matter:
-
Caddy handles automatic Let's Encrypt certificates — set
CERT_EMAILand it works -
Migrator runs
restart: no— applies schema changes on deploy, then exits cleanly - Valkey (not Redis) — drop-in replacement, better memory efficiency, same protocol
- pgsty/silo — MinIO fork optimized for single-node deployments, lighter resource usage
-
PostgreSQL
max_connections=1000— tuned for connection pooling under load
Air-gapped deployment supported. No internet required after initial pull. Helm charts for Kubernetes. Prime CLI for multi-instance management.
The Tech Stack: Battle-Tested, Not Trendy
| Layer | Choice | Why It Matters |
|---|---|---|
| Backend | Django 5.2 LTS | Mature ORM, admin, auth, migrations, security built-in |
| Async | Celery 5.5 + RabbitMQ | Durable queues, retries, dead-letter, monitoring |
| Realtime | Node.js + WebSockets | Separate service = no blocking Django workers |
| Frontend | React 19 + React Router 7 | Modern, fast, MobX for fine-grained reactivity |
| Database | PostgreSQL 15/16 | ACID, JSONB, full-text search, proven at scale |
| Cache | Valkey 7.2 | Redis API, better memory, active development |
| Storage | S3/MinIO | Object storage standard, any provider |
| Monorepo | Turborepo + pnpm | Shared types, incremental builds, cached tasks |
No custom consensus algorithms. No exotic databases. Just solid engineering with the right tool for each job.
AI & Extensibility: Not an Afterthought
Plane has a native MCP (Model Context Protocol) server built in. AI agents can:
- Create/update work items
- Query projects, cycles, analytics
- Run workflows
- Access docs and pages
// MCP tool example
{
"name": "create_work_item",
"description": "Create a new work item in Plane",
"parameters": {
"type": "object",
"properties": {
"project_id": {"type": "string"},
"name": {"type": "string"},
"type": {"type": "string", "enum": ["issue", "task", "epic"]},
"state_id": {"type": "string"}
}
}
}
Plus Slack @Plane mentions — type @Plane create issue "Fix login bug" in Project X and it happens. GitHub/GitLab two-way sync. Webhook framework for custom integrations.
Migration: You're Not Trapped
Jira → Plane importer: issues, sprints, epics, attachments, comments, users.
Linear → Plane importer: preserves cycles, labels, relations.
GitHub → Plane: bidirectional issue sync.
One-way door? No. Export your data anytime. PostgreSQL dump. S3 bucket. You own it.
What You're Signing Up For
| Reality | Detail |
|---|---|
| Resource baseline | ~4 GB RAM minimum (Postgres + Redis + RabbitMQ + 4 API workers + live + frontend) |
| Maintenance |
docker-compose pull && docker-compose up -d for updates. Migrator handles schema. |
| Backups |
pg_dump + S3 sync + Redis RDB + MinIO bucket versioning |
| Scaling | Add API workers, live replicas, RabbitMQ consumers. Postgres read replicas for heavy read workloads. |
| License | AGPL-3.0 — if you modify and expose publicly, share changes. Self-hosted internal use: no obligation. |
Why This Matters for Developers
You spend years learning React, Django, PostgreSQL, Redis, RabbitMQ, WebSockets, Docker, CI/CD. Plane is the reference architecture for a modern full-stack application.
- How to structure a Turborepo monorepo with shared TypeScript types across frontend/backend
- How to separate real-time concerns from transactional API
- How to design durable background job processing
- How to run PostgreSQL at
max_connections=1000with connection pooling - How to do zero-downtime migrations with a dedicated migrator service
- How to build a plugin/integration system (Silo) that doesn't couple to core
Studying Plane's codebase teaches you more about systems engineering than most tutorials.
TL;DR
Plane replaces Jira/Linear/ClickUp with a self-hosted, open-source platform that:
- Runs on standard infrastructure (Postgres, Redis, RabbitMQ, S3)
- Uses a microservice architecture (10 services, each with a clear responsibility)
- Delivers true real-time collaboration via a dedicated WebSocket service
- Handles durable async execution via Celery + RabbitMQ
- Includes AI/agent readiness via native MCP server
- Gives you full data ownership — AGPL-3.0, air-gapped ready, one-command deploy
Next time you drag a card in Jira, remember: there's a whole distributed system making that feel instant. Plane lets you own that system.
Repository: makeplane/plane (61.9k ⭐, AGPL-3.0)
Docs: developers.plane.so/self-hosting/overview
Try it: docker-compose up — 2 minutes to a running instance
Top comments (0)