
Should I self-host Todoist?
YESworth it
Vikunja does lists, projects, labels and sharing in one small container — the $84/yr was for the apps, and the web app plus third-party clients cover enough.
The math (nothing hidden, including your time)
| Todoist (Pro) | $7.00/mo |
| VPS share + storage | −$0.50/mo |
| Your maintenance: 10 min/mo at $20/h | −$3.33/mo |
| Net saving | $3.17/mo |
| Setup: 35 min measured (one-time) | $11.67 |
| Break-even | 3.7 months |
| Markup Index (price ÷ real self-host cost) | 1.8× |
Price: source, checked 2026-08-05. Inputs are stored in git; every number above is derived, never hand-written.
What you lose
- Todoist's polished native apps and natural-language capture
- Karma, if you liked being graded by your todo list
What you're paying Todoist for
- tasks & projects
- labels/filters/due dates
- sharing lists
- mobile capture

Ranked alternatives
One container holding every task, project and due date, with no project cap and no per-seat bill.
Hardware
Runs comfortably on Raspberry Pi.
The tested compose file (our evidence, CI-booted)
# Vikunja — self-hosted to-do lists and projects (replaces Todoist)
services:
vikunja:
image: vikunja/vikunja:latest
container_name: vikunja
restart: unless-stopped
# The image runs as uid 1000 but fresh named volumes initialize root-owned; without this
# the file handler crash-loops on "permission denied".
user: "0:0"
environment:
VIKUNJA_SERVICE_PUBLICURL: http://localhost:3456
VIKUNJA_DATABASE_TYPE: sqlite
VIKUNJA_DATABASE_PATH: /db/vikunja.db
VIKUNJA_SERVICE_ENABLEREGISTRATION: "true" # create your account, then flip to false
ports:
- "3456:3456"
volumes:
- vikunja-files:/app/vikunja/files
- vikunja-db:/db
# The vikunja image is distroless — no shell, no wget, nothing to self-probe with.
# This sidecar checks the API over the network so `compose up --wait` still proves
# the service actually serves, not just that the process exists.
vikunja-probe:
image: busybox:stable
restart: unless-stopped
depends_on:
- vikunja
command: sleep infinity
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://vikunja:3456/api/v1/info >/dev/null || exit 1"]
interval: 5s
timeout: 5s
retries: 24
start_period: 15s
volumes:
vikunja-files:
vikunja-db:
Want a guided install instead? caniselfhostit.com/todoist has AI-agent prompts that assume a bare machine — that's their half of the stool, and it's good.
Verification
Protocol v1 · verified by zernonia on 2026-08-10 · setup measured at 35 min · AI assistant: claude-code (allowed & stated)
What broke
- Fresh named volumes initialize root-owned while the image runs as uid 1000 — file handler crash-loops on permission denied until you set user: or chown
- The image is distroless (no shell, no wget) — the compose ships a busybox sidecar probe so the health gate still proves HTTP serves
- Registration ships open by default — create your account, then flip VIKUNJA_SERVICE_ENABLEREGISTRATION off
Full timed log
# Timed setup log: Todoist → vikunja **Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10 **Assistant:** claude-code · **Environment:** containerized runner, 2 vCPU class, Docker 29.3 / Compose v5.1 ## Timeline | Step | Time | |---|---| | Read upstream docs, draft compose with healthcheck | ~11 min | | **Boot: all services healthy in 11 s (measured, `compose up --wait`)** | — | | Endpoint-level workflow check (login/health/API serve) + re-run from clean volumes | ~11 min | | **Total: ~35 min** | | Boot and endpoint checks are machine-verified; `setup_min` is the wall-clock total for this session including authoring, diagnosis and re-runs. Endpoint-level ≠ full human UI workflow — dispute anything that doesn't reproduce (CONTRIBUTING.md). ## What broke - Fresh named volumes initialize root-owned while the image runs as uid 1000 — file handler crash-loops on permission denied until you set user: or chown - The image is distroless (no shell, no wget) — the compose ships a busybox sidecar probe so the health gate still proves HTTP serves - Registration ships open by default — create your account, then flip VIKUNJA_SERVICE_ENABLEREGISTRATION off ## Verdict-relevant notes - /api/v1/info endpoint makes the health gate clean.
Verdict history
- 2026-08-10: unscored → YES — Initial verdict: Vikunja does lists, projects, labels and sharing in one small container.