Tech stack for my apps
I started developing iOS apps during the pandemic, and one of the best things I did was to learn SwiftUI. It cut down development time considerably for me. I found UIKit to be very verbose and setting up apps was truly a lot of pain. That being said, due to standardization on SwiftUI components, it does make new apps look very similar. I’ve learned to live with these trade-offs as I continue to learn more design and product from these side-projects.
My earlier tech stack relied on these:
- Firebase for Auth
- Firebase functions for serverless API authenticated via rules again from Firebase itself
- App done natively in SwiftUI.
- Firestore for storage needs (I regret this!)
- GCS for cloud storage especially images
I’ve since then reverted to removing serverless completely from my tech stack. I think there’s a place to use serveless, but it doesn’t seem right for my apps in the long run. Because most apps tend to receive traffic sporadically, while serverless lets you save money — it also makes you pay the price from latency issues you get. I can explain more with an example.
Drone Trails
Drone trails is a fairly trivial app that I started my iOS journey at. You can find the landing page here or download it from the app store directly here. The goal of the app is to let folks find recreational spots to fly. Nothing fancy, but when you hit landing screen for the app — my logic to show trails near you was absolutely crap!!
Lets say each post in Drone Trails had some metadata and location captured via longitude and latitude. We begin by geohashing this. The app asks for the user’s base location and geohashes that to find posts nearby — solving the issue for trails near you!
In more simpler terms, Let’s say you’re using a food delivery app and want to find restaurants near you. If your location’s geohash is “9q8yyk”, the app can quickly find all restaurants whose geohashes start with “9q8yy” - these will all be within a few blocks of you.
I ended up using Firestore a document store to help build this functionality. Built the indexes so the lookup would be fast, but with these query patterns, Firestore doesn’t really do a good job. Further, because the traffic was so sporadic, I sometimes needed to wait for the server to spin up and then begin taking the traffic to get the spots. The p50 latency for my home screen to load trails near you was at 30 seconds. So bad, that most people churned at the start itself or would review saying spots didn’t load at all.
I’ve since then moved to Postgres to bring these below a second in latency. Mostly swapping over the serverless to a dedicated machine running the API and Postgres being the DB of choice.
My Current Tech Stack
FWIW I spend more than the Firebase solution for sure, but I end up using the same box for multiple other API calls. In the long run, it does save me even more money. The choice of stack now is:
- Firebase for Auth (they have a great free tier)
- Firebase for push notifications using FCM
- Postgres for db
- Fast API (python) on a Hetzner box for serving all my traffic
The Hetzner box runs behind a load balancer and is pretty neat to scale up the workload as needed. I use docker to push my images through and deploy using Docker swarm.
I think using docker and swarm was the best decision I could do. Pretty much all of my deployment gets taken care of using one Makefile. I largely use local only mode in most of my apps, so I can avoid a server altogether but that’s been more harder to do in my household series of apps.