- Published on
Big App Update
- Authors
- Name
- Andrew Kallinikos
General Update
Hey everyone its been awhile since the last update. I've learned a lot since then, and the app has grown. While using and testing the live app, I've gained a better idea of the direction I want to take the project.
Due to an increase of work at my day job and my side job, progress has been pretty limited on this project. For the most part, I have been making small updates a fixing minor bugs on the frontend. That's all changed the past couple of weeks and I have some exciting updates to share.
Tech Update
Most of the big changes have been happening behind the scenes on the backend. This entire project lives on a little Raspberry Pi that sits on my desk, so I always have to be mindful of resource usage. I love this approach, as it naturally forces me to make decisions that will scale as the app grows (More on this in a minute).
Throughout my testing, I've been closely monitoring the performance of the app and it has been shaping some of the recent decisions I have made.
Server OS Upgrades
Raspberry Pi finally released a stable 64 Bit version of its Raspberry Pi OS. This is huge as it finally unlocks the full potential of the Pi's CPU. I have managed to successfully migrate everything to the new upgraded the server! Once I was done testing everything on the new server, I pointed the router to the upgraded server. Of the tests I ran, the results have been very exciting so far, especially when it came to heavier tasks like data analysis.
Backend Upgrades
Speeding Things Up
A few weeks ago I started playing around with the live data API, seeing where I could add performance. The current app uses the Flask Python framework to create a REST API for my live condition microservice. The code was a bit of a tangled mess so I spent some time refactoring and adding tests to ensure future changes wouldn't break anything and make future development faster.
I then implemented a caching system that would store the most recent live data in memory and serve that instead of hitting the database, only accessing the database when the data in the cache expired. The subsequent performance increase was exhilarating. That app was pretty quick before, but seeing the requests almost immediately populate on the frontend got the motivation flowing.
A Performance Dilemma
The app was now in a pretty good place, the code was cleaner, more maintainable, it was pretty fast. It was time to add more features. Before I jumped into adding anything new, I wanted to get a performance baseline of where we were at. I used the apache benchmarking tool to perform a load test and see what the limits of this app were in its current hosting environment. I chose to send 5000 requests with 350 requests being made concurrently as I thought this would be kind of the max traffic the app would see on the current hosting platform before I scale up. The results below quickly brought me down from my initial high.

Realistically, there will probably never be that much concurrent traffic on this server. However, Flask was just using too many resources even at lower loads. It would also not scale well as I add more features and needed to run some data analysis in the background. There's always trade-off between performance and development time and as a single dev, I'm no stranger to that while developing this project. Unfortunately, I had to make the decision to rewrite the API.
Go-ing Forward
These days there are an overwhelming amount of Languages and Frameworks to choose from, and I spent a good deal of time researching my options. I quickly narrowed down my languages to Rust and Golang, with their actix-web and Fiber frameworks, respectively. Rust is faster, has better error handling, and a more powerful type system, so naturally I chose Go.
Why did I go with Go? While Rust runs faster, the time to rewrite the API in it would be much longer would not outweigh the marginal performance increase over Go. The Fiber framework was inspired by Node’s Express framework, but contains all the performance of Go. Go seemed more than performant enough and I was already familiar with Express.
I was shocked at how easy Go was to pickup. Despite never having used Go before, I was able to completely rewrite the API in only a couple of days. If we’re being honest I didn't think the rewrite would be so quick and painless as it was. My only real issue was some corruption in the cache I wrote, but that didn't take too long to fix. The benchmark results on the server were night and day.

You can see we’ve achieved an almost 500% performance increase over Flask! What’s even better is that as the API grows and we add more features, the performance shouldn’t suffer as it would using Flask. The results are even more incredible as we scale up. Running the api’s locally on my desktop (i9-9900K CPU @ 3.60GHz × 8), I saw a 3300% increase in performance! This would mean our API would be even more efficient if we were to ever scale to a “real” server on a cloud platform.
What Now?
Planned Features
I feel that the application has a solid foundation to grow upon now and can get back to my original task of adding more features. I have decided for the time being that I will focus on the live reporting elements of the application before wading into the forecasting space. Thanks to your feedback, I am working on the following features:
Zones
I'm planning to release 4 general areas (zones) of live activity:
- Eastern LI
- Central LI
- Western LI
- Northern Jersey
These zones will contain all the info you generally look at when planning a spot to go to (Swell, Winds, Tides, etc).
Tides
I will be adding the current tide information. I’m looking into how much work a dot tracking along the forecast would be to implement, but will definitely release a simpler solution to display the data first.
Better Winds
If you have been using the app, you probably have noticed the Long Island Station's wind direction has been broken for almost a year now and that stations don't always send certain bits of data. I plan on leveraging other sources of wind data to supplement a broken or not reported live element.
Swell Analysis
I'm working on a system to let users know if a swell is building or fading. This will be a bit of a challenge, but we can start small and build from there.