LLM-assisted HDB Resale App Rewrite

After 20 minutes of spec-driven project initialisation + 20 hours of LLM-assisted manual review, I finally managed to fully rewrite and redeploy my web app on HDB resale pricing analytics.
You can see it here - https://apps.cheeyeelim.com/hdbresale
The underlying code is open-sourced here - https://github.com/cheeyeelim/hdb-resale-app-open-source
(It includes frontend, backend and infrastructure codes so it could be rebuilt and redeployed by anyone.)
(A) The tech stack
I have purposely kept the same functionality in the web app, but redesigned it using new technology. The goals are to lower costs and improve the efficiency of the backend stack.
-
Charting : Dash -> Next.js + Recharts
-
Database : Postgres -> duckdb + S3
-
IaaC : None -> Terraform
-
Cloud platform : DigitalOcean -> AWS
-
Cloud compute : Kubernetes -> AWS ECS + Lambda
-
Task orchestration : Airflow -> AWS Step Function + EventBridge
-
Observability : Prometheus + Loki -> AWS CloudWatch
(B) The results
The overall cost of hosting the website was reduced by around 50-75%, mainly because I could leverage AWS’s managed services for many non-core operations instead of rolling my own deployments. For example, using AWS CloudWatch instead of spinning up my own Prometheus.
The second major cost reduction factor is by using AWS spot instances to form the AWS ECS cluster. AWS provides early warning before reclaiming the spot instance, so it is possible to provision a new instance for services to run on to ensure there is no downtime.
The response speed of the website also improved drastically from taking 3-5 seconds to sub-1 second for initial result display. No caching is being used here, so the speed improvements came from the duckdb setup and leaner callback functions.
(C) The learnings
- AWS is cheaper than I thought
Everyone always talked about AWS being more expensive than DigitalOcean, because AWS is built for enterprise and DigitalOcean is built for solo developer or small team. This is true in service offering perspective, but not necessary true in terms of costing.
There is a big condition associated with this statement though. AWS is only cheaper IF AND ONLY IF you do not blindly follow the officially recommended ways of setting up the infrastructure. For example, AWS recommends serverless Fargate for ECS (instead of ECS on EC2 with spot instances) and fully private VPC (instead of public subnets). There are valid reasons for all these recommendations, but I care only about costs for my simple use cases.
Note that if you blindly let LLM builds the infrastructure for you, it is going to choose the most expensive setup by default. This is because the LLM follows the best practice recommendations from the documentations.
The second word of caution is that it is more important to set up proper account security and budget/cost alert warnings with AWS than DigitalOcean. There are more ways to go bankrupt in one night on AWS than DigitalOcean, just because of the sheer number and complexity of offerings on AWS.
- LLM helped me learn new frameworks like React and Terraform
As someone who comes from Python background, I have always been building web apps with Python (Dash, Django, Flask etc). For setting up infrastructure, I used to just keep a large README file and Bash scripts that document the steps that I took.
Going into another language/framework just for a part of my build felt counter-productive, as it tends to break my development flow and took up too much of the precious free time that I have.
I finally broke this barrier, partly because I am seeking for breakthroughs in my ways of workings, and partly because LLM has really made learning new languages/frameworks more fun.
How so, you asked? It is because the most painful part of learning a new language/framework in the past is about digging through pages of documentations/books/tutorials, skipping through all the parts that you know or do not need for now, just to find that one piece of relevant information that you do need. This can take up to hours depending on situations, but LLM cuts this step down to seconds/minutes.
My learning flow goes like this. I start with a problem that I want to solve. I asked LLM to propose several solutions. Then I picked the solution that works best for my use case and asked LLM to perform an initial implementation. I will then go through the implementation line by line, cross checking any unknown part with LLM and manual Googling. Then I will run the builds and do some tests to ensure that the output is as I intended. This learning flow lets me learn by doing, which I feel is the most effective way of learning.