What I don't like about Supabase
There’s so much to love about Supabase - it’s very easy to get started, and it has most of the things you need from auth to storing vectors. We hear about all these great things all the time. But just like any other platform it has its own gotchas and nuances that could be annoying to some. We barely hear about these and I thought let me be that bad guy!
Migrations
Migrations in Supabase are great until they are not. It works well for adding new tables, columns, or modifications. But, when you start adding DB functions, it becomes a pain. Unlike table changes, functions are something you will iterate over many times. For each iteration, you will end up creating a new migration file and you will end up piling up a ton of them! You could squash your migrations later, but creating a new migration file for every little change is a bad developer experience. When I discussed this with my colleague Pruthvi, the hack he suggested was to use the Supabase interface to iterate over your function and create migration when ready!
Another nuance I encountered was, that my DB migration files were part of the frontend repo. Traditionally, you want to run db migrations along with backend deployment. This design choice is probably because most Supabase projects use only Supabase as their backend, thanks to their edge functions. Hence it probably makes sense in most cases to run DB migrations when you are running a frontend deployment pipeline, as frontend code is the only direct dependency for migrations. But if your application is complex and needs more compute power than what edge functions can offer, you end up having a backend hosted on AWS or something similar. In my case, I had my backend powered by AWS Lambda functions. In this case, you will end up with a dilemma of where to run migrations!
Unknown Limits
After a few weeks of development of my app, my auth randomly stopped working! After digging, I found out I had hit a limit on the number of emails that could be sent per hour, which was 3! Because of this Auth email confirmations were not going through. I was completely unaware of this limit until it stopped working. It was buried under some setting which I hadn’t gone to at all until this point. It would have been better to have this as a “note” or something in the Auth documentation. It broke the flow of my app development, instead of testing my features, I was now thrown into figuring out how to setup custom SMTP unexpectedly. Thankfully, this is the only “gotcha” I have seen so far, hope it stays that way.
Compute
Having only edge functions as compute is very limiting. Most apps need compute more powerful than this. I often find myself pairing Supabase with AWS Serverless stack to compensate for the lack of compute on Supabase. If I had an option to run full-runtime functions (like AWS Lambda) on Supabase, most of my use cases could be contained within Supabase.
Hidden Costs
Point in Time Recovery (PITR) is a very important feature for me in a production database. I have overcome two catastrophic incidents during early years of being CTO thanks to this feature. It allows you to recover database to a “point in time”, meaning if something bad happend at 5:15PM you can restore the database to the point as is at 5:14. This feature in Supabase costs whopping $100 a month, irrespective of size of your database! I’m ok to pay for this but single price irrespective of size seems unfair! Would have liked it if it was tiered or was based on how far can you go back! For example, NeonDB has PITR in their free plan but allows you to go back only 24hours, which I can live with!
I like everything else!
Don’t get me wrong, I like Supabase very much and the intent of this blog is to give feedback to make it better. At the beginning of my Serverless journey, I was a big fan of Firebase for its simplicity and lowering the entry barrier. Supabase has taken it even further, it feels so simple and approachable and allows you to build apps fast.