How My Plant Project Made Me a Better Engineer

In The Begining

Initial rough sketch of my pi garden
This rough sketch is my most prized posession in America

Months into my full stack web dev journey (spring 2024 ish), what I wanted was a hardware project that watered my plants, logged data, and visualized the data. I started off with a rudimentary stack: Flask API, CSV based storage, Python parsing scripts, and a vanilla JavaScript frontend.

As time passed, the environment data appended countless (about 10k) rows to the dataset. Weaknesses of the original design manifested into a project so slow that I was a bit embarrassed to show anyone. The poor speed was caused by the following aspects:

  • CSV storage becoming slower to query
  • the API was sending more data than the frontend actually needed
  • The client was doing unnecessary work to render the data.

Iteration 2

From here, my main goal was building something I could proudly show off. Here’s how I improved the system’s preformance bottlenecks to be proud enough to share the project to strangers on the internet.

My first improvement was to migrate from CSV storage to SQLite. I chose it because it gave me structured querying with low resource overhead. This is one example of where I match the tool for the constraints rather than prematurely over engineer a solution.

My second improvement was to reduce the average network message size. Rather than sending full records when the frontend only needed specific fields, I narrowed responses to the columns required for visualization.

My third improvement was to avoid un nessasary data fetching by caching previously fetched data and only requesting newer records. That introduced practical constraints of browser storage, including localStorage limits, and pushed me to think more carefully about persistence, query boundaries, and the lifecycle of frontend data. These changes improved responsiveness, rendering behavior, and overall usability.

Implementing naive data patterns in Iteration 1 taught me the UX impact of not knowing about how data is stored, queried, transmitted, and rendered across the entire system. As the project matured, I kept raising the bar on the architecture to go from a prototype I can proudly share online to something I can passionately chat about to other engineers across the stack. Here’s what I then did.

Iteration 3

First, I migrated from Flask to FastAPI to get autogenerated API documentation, and a better path for real-time features such as support for web sockets.

Second, I adopted React to speed up frontend iteration and support a more scalable UI.

Third, I separated data related concerns more deliberately by using the Raspberry Pi for sensor reads and device control while offloading heavier storage and query work to a more capable machine (my mac mini). The shift in offloading heavy work from the Raspberry Pi to the Mac Mini led me into containerization and messaging infrastructure. I learned Docker to package services consistently across hardware, and picked up MQTT to better support lightweight telemetry. Another side benefit of MQTT that will pay dividends is decoupling communication with a pub/sub architecture.

Reflection

What I’m most proud of in this project is that I kept refining the system as new constraints appeared. I like building quickly, but I also like revisiting my assumptions, identifying annoying bottlenecks, and redesigning around them.

I’m so excited to grow this project and see where it takes me as I chip away at the last bit of my Computer Science degree. I hope you enjoyed my ted talk on how I iterated over the project that landed me 2 internships, and got me back into college after dropping out of college as a biology student.

// want to read where I’m taking this project as of April 2026? Check out the questions under the "Where I'm Heading" section