Skip to content

Field notes: running a self-hosted personal AI assistant

These are operational notes from six months of running a personal AI assistant as a resident process on my own hardware — a Telegram bot on top of an agent runtime, with persistent memory, a scheduler, and voice. They are not a tutorial and not a product pitch. They are the things I would have wanted to read before starting: sizing numbers, schema decisions, the failures that actually happened, and the parts where "self-hosted" turns out to mean less than the phrase suggests.

The build these notes describe is written up as it goes at avelina.ai — longer pieces live on the engineering blog.

Why a resident process instead of a chat window

A chatbot answers. An assistant persists. The moment you want the second property, four things appear that a stateless API call never needed:

  1. Storage that outlives the conversation — facts, corrections, the reason a plan was rejected last Tuesday.
  2. A clock — something has to run when nobody is typing.
  3. A boundary — the assistant reads mail and calendars, which is a security surface, not a feature list.
  4. A place to live — a laptop that sleeps is not a host.

Every page in these notes is a consequence of one of those four.

Component inventory

Part Choice Why it ended up that way
Process one long-lived daemon under systemd / launchd restart policy matters more than throughput
Datastore a single SQLite file atomic writes, backup by copy, no second daemon at single-user scale
Retrieval full-text index + local embeddings keeps working when an API key expires
Scheduler in-process jobs in a database table system cron cannot see application state
Transport Telegram the client already exists on every device, and handles voice and files for free
Host 2 vCPU / 4 GB VPS idle sits near 300 MB; the spikes are media work, not inference

What these notes cover

  • Memory layer — the schema that carries facts, lessons and state, and why retrieval quality is a chunking problem before it is a model problem.
  • VPS sizing — measured numbers for RAM, disk growth and the two things that actually cause outages.
  • Scheduling — why scheduled jobs that wake a language model are a different animal from cron entries running shell scripts.
  • What stays local — an honest split between the parts that never leave the machine and the parts that leave on every single turn.
  • Backups and recovery — what a restore drill exposes that a backup script never does.

A note on scope

Everything here is single-user scale: one owner, one assistant, one machine. Numbers scale badly in the interesting direction — the moment you have ten users, SQLite, in-process scheduling and "just copy the file" all stop being obviously right. I have not run this at that scale and do not pretend the notes transfer.