← back to the office

The Google Exit: calendar and tasks, self-hosted

Aug 2026 · data migration, CalDAV, self-hosting

I left Google Calendar and Tasks without losing anything. Divorce by stages: first the furniture, then the keys. This post is the receipts.

The plan

Every piece of data is exported, migrated to Radicale on jacinto (my Raspberry Pi CalDAV server), verified, and only then is Google retired. Tasks first, then Calendar, then the kanban sync; contacts, Drive, photos and mail are next.

Takeout is the slow way

Direct export beats Takeout for Calendar: Settings → Import & Export is instant, Takeout takes hours. Use Takeout only when you want everything at once.

The migration

The migration is the same pipeline instinct as adtech: idempotent by key, dry-run first, verify after:

Google Exit migration flow
Export, migrate, verify, retire.

Live numbers today: 4,531 events in eve/work/, 608 tasks in eve/tasks/.

  • Tasks: Takeout Tasks.json → one VTODO each, Google list id as CATEGORIES, task id as UID (idempotent re-runs).
  • Calendar: export → eve/work/ (laburo) + eve/calendar/ (personal).
  • Kanban: Obsidian ↔ CalDAV sync, timer every 30 min.

Bugs that almost ate the calendar:

  • RFC 5545 line folding: Google folds lines over 75 chars, and a folded UID makes Radicale return 400. Unfold before parsing.
  • Recurrence: master event and RECURRENCE-ID exceptions must live in the same resource, or clients break the series.
  • XML namespaces: <D:href> matches nothing; use a flexible regex. Count with a REPORT query, never PROPFIND.
# RFC 5545: folded lines start with a space, so unfold before parsing
raw = re.sub(r"\n[ \t]", "", raw)

The phone

DAVx5 on the phone speaks CalDAV to the Pi: Tasks app for todos, Etar for the calendar. All 4,531 work events on the phone, and everything syncs back.

What's left

Contacts → vCard, Drive → rclone, Photos → Immich, Mail → himalaya. Not done yet; each one gets the same treatment: export, migrate, verify, retire.

What it taught me

  • The advertised export path (Takeout) is the slow one. Check the direct export first.
  • Personal data migration is a data pipeline: idempotency, dry-run, real verification.
  • The format is the contract. RFC 5545 folds lines, and the contract breaks quietly.
  • Owning your data is a server with your own htpasswd, not a slogan.

The reliable choice, again

Google will be fine without my calendar. The question was whether I would be fine without theirs: the answer was a 4,531-event export and a Raspberry Pi named jacinto.