Blog

nFolyo MVP Postmortem - What We Learned Building a Portfolio Tracker

Posted by Thibaut Flat-Patrick
10 min read
Table of Contents

Interested in tracking and analyzing your portfolio with nFólyo?

We do not learn from experience… we learn from reflecting on experience. — John Dewey

Introduction

nFolyo is a portfolio tracking and analysis tool built for long-term investors like us — with global portfolios invested across equities and ETFs, not just limited to US and EU markets.

It started as a collection of Python scripts and spreadsheets we used to manage our own portfolios. Over time, it evolved into a full-featured tool and became our learning ground for modern web development and microservice architectures.

We released our MVP in November 2024 after eight months of intense development. After iterating on early user feedback, we released version 0.4.0 in March 2025 with several improvements. Now, we’re at a turning point that requires us to rethink our approach and make some difficult decisions.

To do that well, we need to pause and reflect.

This postmortem marks the start of the next chapter — a chance to look back on over a year of development, two releases, what worked, what didn’t, and where we go from here.

History of Development

Our Tech Stack

nFolyo is made up of a frontend app (nfolyo-client) and two backend services:

  • nfolyo-core: handles account and portfolio updates.
  • nfolyo-finance: responsible for fetching pricing and historical data.

We’ll dig into our architecture in a future post, but here’s an overview of our current stack:

  • Next.js: For the frontend, we chose Next.js as it’s a mature and powerful framework that supports full-stack development and server-side rendering.
  • Python and Flask: For the nfolyo-core and nfolyo-finance background services, we went with Python and Flask. Flask makes it easy to build APIs quickly, and Python is particularly strong for data processing.
  • MongoDB: We selected MongoDB as our database due to its scalability and our prior experience working with it.
  • Azure: We’re deploying on Azure, using Docker containers and GitHub Actions for continuous deployment.

The Road to MVP

We set a minimum feature set before nFolyo was ready to be shared with other investors. Our original roadmap targeted a September 2024 release, but as you can see in our revised roadmap (pointing to October/November 2024), we underestimated the work involved!

nFolyo MVP Roadmap (Sep 2024)
MVP roadmap (target release date Sep 2024)
nFolyo Revised MVP Roadmap (Nov 2024)
Revised MVP Roadmap (target release date Nov 2024)

MVP Launch, User Feedback & Iteration

We released the MVP in November 2024 to a closed group of beta users. It wasn’t polished, and while we extensively tested our broker activity importers (Interactive Brokers and Freetrade), we couldn’t guarantee it would parse every user’s data.

We were fortunate to have extremely patient beta testers who not only helped us fix major bugs but also provided crucial feedback to improve our user experience. Their support was invaluable.

Over the next few months, we focused on the most critical bugs and usability issues:

  • Fixed price inaccuracies and broker importer errors.
  • Improved TWRR performance calculations.
  • Added clearer feedback during statement import and account updates.

v0.4.0 launched in March 2025, incorporating those changes. Check out the release notes nFolyo v0.4.0 – Improved Import and Account Status Updates for more details.

Where Are We Now? Pausing and Reflecting

Despite all the progress and great user feedback, we’re now at a crossroads. Some of our early tech and architectural decisions, made to speed up MVP development, are starting to catch up with us. It’s becoming clear that our current infrastructure won’t scale up easily.

Without a more maintainable foundation, adding new features will only get harder and more expensive over time. We have a long list of ideas that could make nFolyo truly powerful and unique; however, without rethinking and refactoring our core architecture, those ideas risk remaining just ideas.

So what do we do?

We decided to pause the closed beta while we focus on the next major release. (You can still sign up to register your interest and we’ll notify you as soon as the next version is out). This gives us the freedom to break things without the pressure of maintaining backward compatibility and continuous live operations.

Reflections

The Good

It’s been a great learning experience — diving deep into Next.js, Python, Flask, and Azure with real hands-on challenges.

We’ve implemented many features in a short time, all while holding down full-time jobs.

We’ve had highly engaged users testing the app, providing valuable feedback, helping us uncover bugs we couldn’t have found alone. Their time and support have been invaluable.

The Bad

1. Burnout
Balancing full-time jobs with late nights and weekends on a side project isn’t sustainable. Passion keeps things going for a while, but long-term time management and maintaining a healthy work-life(-side-project) balance is essential.

2. Building in Isolation
We didn’t engage publicly early enough. No community, no dev blog, no social presence. All these factors slowed down feedback and iteration loops significantly. Building nFolyo in public from day one could have helped us course-correct faster and save development time.

3. Poor UI Component Library Choices, Failure to Explore Alternatives
We started with Radix UI, but hit limitations when customizing components. We ended up creating many of our own, which introduced styling inconsistencies and duplicated effort (e.g., building an editable/sortable table).

In hindsight, switching to shadcn/ui early would’ve saved loads of time and given us more consistent styling out of the box. This decision alone added months of unnecessary frontend work.

4. No Broker API Auto-Sync
We assumed most users would be fine uploading broker statements manually. But feedback shows otherwise. Around 80% of users (ourselves included) want automatic sync via broker APIs to make their lives easier.

We avoided this to keep development simple, but going forward we need to support it to stay competitive. The challenge will be balancing automation with privacy. We’re hesitant to rely on third-party aggregators like Yodlee or Plaid, but that’s something we need to explore more.

5. Underinvesting in a Pricing API
We chose Yahoo Finance’s public API because it was cheap and provided global coverage for equities and ETFs — perfect for proving out the MVP. But it’s slow. Really slow. Historical pricing queries in particular introduce major latency, which affects calculations like TWRR performance charts. We’ve had to build a whole layer of caching and data cleanup just to make it performant enough, costing us weeks of effort. For serious use, we’ll need a more robust solution.

6. No Async/Message Queue Architecture
To keep things simple early on, we built a monolithic background service that updates a user’s account in one big API call. That was fine for launch, but on accounts with long trade histories and many holdings, it now takes up to 10 minutes. The processing isn’t parallelized and quickly becomes a bottleneck, affecting the user experience.

What we really need is an asynchronous, distributed system using a message queue (e.g., RabbitMQ or Redis) and a task processor like Celery. That would let us split jobs into smaller tasks (units of work), process them in parallel, and give real-time progress updates using something like Server-Sent Events (SSE).

Not doing this is now our biggest architectural limitation. It made sense for the MVP, but it’s blocking future progress.

7. Azure Deployment Pain Points
This was our first time deploying such a complex app on Azure. While getting things up and running wasn’t too painful, we ran into real performance issues:

Our Flask services run as App Services; on low-tier plans, performance is poor, while high-tier plans are expensive. Additionally, the lack of async mechanisms means we’re paying for idle services much of the time.

The Next.js frontend is deployed as a Static Web App using Azure Functions for APIs. Cold starts can cause 15 - 30 second delays, and Azure Functions 45-second timeout complicates long-polling and SSE.

We’re rethinking our deployment strategy to better suit the performance demands of a scalable application.

Learnings

Here are the key takeaways from our journey so far.

1. Manage your Time Wisely
It’s better to make consistent, small progress than to go all-in, burn out, and need a long break — or worse, lose all motivation and abandon the project. Sustainability > speed.

2. Build in Public Early
Share progress openly and engage users from the start. It might feel like you’re moving slower, but early feedback helps you avoid building the wrong things — saving time in the long run.

3. Use Mature, Customizable UI Component Libraries
Don’t reinvent the wheel. Component libraries like shadcn/ui are tried and tested and can save you weeks of work. Building our own sortable, editable table from scratch wasn’t very wise and cost us precious development time, we should have just used TanStack Table. Don’t make the same mistake.

4. Lay Solid Architectural Foundations (When it Matters)
If you’re just validating an idea, quick-and-dirty is fine. But if, like us, you know this is something you want to build for the long term, invest early in scalable architecture. It’ll save you months of technical debt later.

5. Choose Your APIs Carefully
Don’t default to the cheapest solution. While it’s fine to start lean, poor APIs can introduce major delays and reliability issues. At the very least, build abstraction layers (e.g., interfaces or base classes) so you can easily swap out the API later without a full rewrite.

Next Steps

To wrap things up, here’s a quick overview of what’s next for nFolyo. We’ll go into more detail — including our roadmap to v0.5.0 — in future posts.

1. We’re Intentionally Slowing Down Development
This is a marathon, not a sprint. To build something great — for ourselves and our users — we need to manage our time better and avoid burnout.

2. We’re Building in Public and Sharing More
This blog is a big part of that. Expect more updates, learnings, and technical deep-dives as we go.

3. We’re Refactoring Our Backend for Scalability
We’re migrating to an architecture based on Celery with RabbitMQ (or Redis) for better performance and scalability. We plan to document this process, as most tutorials out there only scratch the surface and rarely cover real-world use cases.

4. We’re Investing in Better Financial APIs and Exploring Broker API Integrations
We’re currently evaluating APIs like Financial Modeling Prep and EODHD, and looking into direct broker integrations for trade syncing. Our goal is to offer automation and convenience — without compromising user privacy or relying on third-party aggregators like Yodlee and Plaid. That said, we’re keeping our options open if they offer the best balance of utility and privacy.

In Conclusion

Thanks for reading. We hope you found something useful in our journey — whether you’re building your own tool, considering a side project, or just curious about the inner workings of portfolio tracking apps.

Let us know what you think, we’d love to hear from you. You can find us on X and Reddit.