Every investment tracking app I tried wanted the same thing: my brokerage credentials. Plaid connections, OAuth flows into my bank, screen-scraping logins — all so I could see a number I already knew, refreshed every fifteen seconds, wrapped in notifications engineered to make me check it again.
I didn’t want any of that. I wanted the opposite: a private investment tracker where I enter my portfolio value once a month, and the app does the thinking — trends, allocation, forecasts, goals. No broker login. No server. No account.
So I built Portfolio Journal, a native iOS app. This post covers why manual tracking is a feature (not a limitation), and some of the architecture decisions behind a local-first finance app.
The case for manual, monthly tracking
If you’re a long-term investor — index funds, ETFs, retirement accounts — real-time data is noise. Checking your portfolio daily correlates with worse decisions: panic selling, overtrading, chasing performance. The behavioral finance literature has been consistent on this for decades.
A monthly check-in flips the model. Once a month you open the app, type in what each account is worth, and close it. Thirty seconds. What you get in return:
- A deliberate ritual instead of anxious refreshing. You see your net worth evolve on a timescale where your decisions actually matter.
- Any asset class. Manual entry means the app doesn’t care whether it’s a brokerage account, a pension fund your employer manages, real estate, crypto in cold storage, or cash under the mattress. If it has a value, you can track it.
- No integration rot. Aggregator connections break constantly — banks change their APIs, scrapers get blocked, tokens expire. A manual app works identically forever.
Privacy as an architecture decision
“We take your privacy seriously” is what apps say when they upload your data to their servers with encryption. Portfolio Journal takes a different approach: there is no server.
- All data lives in Core Data on the device.
- Sync, if you enable it, goes through CloudKit’s private database — Apple’s infrastructure, your iCloud account, end-to-end within your devices. I never see a byte of your financial data. There is no backend I could be subpoenaed for, no database to breach, no analytics pipeline ingesting your net worth.
- Export is a CSV you own. Import is a CSV you control.
For a finance app, this is the only architecture I’d trust with my own data — so it’s the only one I’d ship to anyone else.
The interesting technical bits
A local-first iOS finance app sounds simple until you build one. A few things that turned out to be genuinely hard:
CloudKit sync without a backend
NSPersistentCloudKitContainer gives you Core Data ↔ CloudKit sync “for free,” but the free tier of understanding will hurt you. Records only export if they have persistent history; data created before history tracking was enabled silently never syncs. SQLite optimizes away no-op updates, so “touch the record to force an export” does nothing unless the value actually changes. Debugging partial-failure export errors (CKErrorPartialFailure) taught me more about CloudKit internals than any documentation.
Charts that respect a monthly cadence
With one data point per month per account, naive charting libraries produce garbage. Everything — evolution curves, drawdown analysis, year-over-year comparisons, contribution-vs-returns decomposition — is built on Swift Charts with explicit monthly bucketing, and a global range brush that filters every chart at once.
Forecasting without pretending to know the future
The prediction engine fits growth scenarios to your actual contribution and return history, then projects ranges — not a single line promising you’ll be a millionaire by Tuesday. It’s deliberately boring math, cached aggressively because users scrub through time ranges.
What it looks like in practice
You create your accounts once (brokerage, pension, savings — whatever you have). Each month, a notification nudges you; you enter current values in the quick-update sheet. The dashboard shows total net worth, streaks, milestones, allocation drift, and how much of your growth came from contributions versus market returns. Goals track progress toward targets. A journal captures what you were thinking each month — which, a year later, is the most valuable feature of all.
There’s a home screen widget, Face ID lock, multi-currency support, and share cards if you want to post a (privacy-filtered) snapshot of your progress.
Try it
Portfolio Journal is on the App Store — free to use, with an optional premium tier for advanced charts and unlimited accounts. More at portfoliojournal.app.
If you’re the kind of investor who checks their portfolio once a month on purpose — this was built for you. And if you’re an iOS developer curious about local-first CloudKit apps, the sync war stories alone are worth a follow-up post. Let me know in the comments which part you’d want to read about.