Tech Digest

Productivity

Actual Budget

Local-first envelope budgeting with an optional sync server you can encrypt end to end

ProductivityMITStablearm64 buildsNative OIDC
Last reviewed Profile maintained against the project's own documentation
Operational load
2 / 5
Light
Idle memory
120 MB
typical use ~250 MB
Moving parts
1
containers in a normal deployment
Backup shape
SQLite backup
needs a dump or a stop

Actual is a zero-based envelope budgeting app where the budget lives on your device as a local database and the server exists only to relay changes between your devices. It replaces YNAB or Mint for people who want the app to keep working when the server does not.

Our verdict on Actual Budget#

Actual is local-first in a way that changes what your server is actually for. The budget lives in your browser or desktop app and every edit applies locally first; the sync server on port 5006 holds server-files/account.sqlite (hashed passwords, the budget file list, session tokens) and your budgets as opaque blobs in user-files/, then relays changes. Turn on end-to-end encryption and it keeps relaying but can no longer read anything. That is the tradeoff people get backwards. The server login password can be reset without data loss; the encryption password cannot be reset, recovered or brute-forced. Lose it and your last local copy, and the blobs on the server are noise. Encryption is also one-way, you cannot switch it off, and bank sync tokens sit on the server outside it. Releases are monthly and date-versioned: 26.9.0 landed 1 September 2026 and moved images to Node 24.

Who Actual Budget is for#

Choose it if

  • A YNAB refugee who wants envelope budgeting and is content to reconcile by hand
  • Anyone who wants the app to keep working offline or with the server down, which it genuinely does
  • People who want the server to hold nothing readable, since encryption is per budget file and per password
  • A household sharing one budget across a laptop and two phones

Look elsewhere if

  • You expect automatic bank feeds everywhere: GoCardless and SimpleFIN cover parts of Europe and North America and need their own credentials
  • You cannot commit to storing an encryption password somewhere you will still have it in five years
  • You want a double-entry ledger, multi-currency accounts or business-grade reporting, which is Firefly III territory

What running it actually looks like#

One container, no database service. Pull ghcr.io/actualbudget/actual or actualbudget/actual-server from Docker Hub, publish 5006, and mount one volume at /data; the server creates server-files/ and user-files/ under it on first start. Setup is setting a server password on first visit. ACTUAL_DATA_DIR, ACTUAL_SERVER_FILES and ACTUAL_USER_FILES relocate those paths if you need them elsewhere. Watch the upload ceilings, because they bite later rather than on day one: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB defaults to 20 and the encrypted equivalent to 50, and a long-lived budget can reach them, which presents as sync failures and not as a size warning. 26.9.0 moved container images to Node 24 and dropped 32-bit ARM from the Ubuntu images; use the -alpine tag on those boards.

Resource profile#

Memory
120 MB idle, around 250 MB in ordinary use. A small Express server that mostly moves blobs, so the number tracks concurrent syncing clients rather than budget size. The heavy lifting happens in your browser or desktop app, not here.
CPU and acceleration
Almost nothing at rest. Syncing is short bursts of encode and decode; the reports and budget math all run client-side, so a bigger budget slows your laptop, not the server.
Storage growth
Small and slow-growing, except that Actual stores every mutation in the budget file, so files grow steadily even when transaction count does not. A sync reset compacts that history back down.
Operational load
2 of 5, Light. One container, one volume, no database service, and the app survives the server being down because every device holds a full copy. It is a 2 rather than a 1 because restores need a sync reset in the right order, and end-to-end encryption adds a secret that is not on the disk you are backing up.

Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.

Data and backup surface#

Back up /data, which is two things: server-files/account.sqlite holding hashed passwords, the file list and session tokens, and user-files/ holding each budget as a binary object. If end-to-end encryption is on, those objects are unreadable without the password, so the password is part of the backup whether you treat it that way or not. Also export from the app itself (Settings, Export Data) on a schedule: that produces a readable archive independent of the server, and it is the only artifact that survives losing both the server and the encryption password. After restoring server data, expect to run a sync reset so devices stop reconciling against newer history.

Derived backup shape

SQLite backup. sqlite3 <db> ".backup out.db" while running, or stop the container and copy. A live cp of a WAL-mode SQLite file can restore corrupt.

Traps and surprises#

A lost encryption password is a lost budget

End-to-end encryption is a second password on top of the server login, and the key is derived from it on your device. The server cannot read the data, cannot reset the key and cannot help. If you still hold a local copy you can reset the key, which forces a sync reset and re-uploads from that device. If you hold neither, the files in user-files/ are unrecoverable. People confuse this with the server login password, which can be reset with no data loss at all.

Encryption is one-way and bank tokens sit outside it

You cannot turn end-to-end encryption back off. Getting to an unencrypted file means exporting from the app and importing into a fresh file. Separately, bank sync credentials for GoCardless or SimpleFIN are stored on the server and are explicitly not covered by the encryption, so an encrypted budget still leaves live banking connections on that disk in a form the server can use.

Budget files grow until you reset sync

Actual stores every mutation in the budget file by default, so the file grows steadily even when the number of transactions does not. Eventually it collides with the 20 MB sync upload limit and large restores start failing. The fix is Settings, advanced, Reset Sync, which compacts the history into one version and issues a new sync id. Every other device then has to revert, which deletes its local copy and re-downloads.

Restoring without a sync reset undoes the restore

Because the server holds change history, restoring an older local file and letting it sync will pull you straight back to where you were before. The documented order is: restore, then reset sync from the restored device so it becomes the authoritative version, then revert every other device. Do it from the device with the most complete data, because a reset discards unsynced changes held anywhere else.

The edge Docker tag was renamed to nightly

26.6.0 renamed the pre-release image tags: edge became nightly and edge-alpine became nightly-alpine. If you were tracking edge, your image quietly stopped receiving updates rather than failing in any visible way, and you can sit months behind without noticing. The same release deprecated rule action templating in favor of formulae, which will be removed in a later version.

Specifications#

Category
Tasks, recipes and personal finance
Licence
MIT (Permissive)
Written in
TypeScript / JavaScript (React and Node.js)
First release
2022
Maturity
Stable
Datastore
SQLite on the client; the server keeps account.sqlite plus per-budget binary files
Default ports
5006
Ships as
docker, docker compose, node source install, desktop app with embedded server
arm64 builds
Yes
Identity
Native OIDC. OpenID or OAuth2 login is built in and marked preview, configured in `config.json` or the admin UI; it is also the prerequisite for multi-user.
Replaces
YNAB, Mint, Quicken, Monarch Money
Project site
actualbudget.org
Source
github.com/actualbudget/actual
Documentation
actualbudget.org/docs

Alternatives to Actual Budget#

Everything else in tasks, recipes and personal finance, closest in operational weight first.

ToolOps loadIdle RAMLicence
Mealie2, Light300 MBAGPL-3.0-or-later
Vikunja2, Light70 MBAGPL-3.0-or-later
Firefly III3, Moderate250 MBAGPL-3.0-or-later
PLANKA3, Moderate220 MBPLANKA Community License (Fair Use License 1.1)
grocy1, Set and forget40 MBMIT

Where Actual Budget comes up elsewhere#

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.