# About Name: Sai Krishna Description: I’m Sai Krishna – coder, foodie, movie lover. I love to build new stuff. Sometimes not really useful but cool stuff. URL: https://saikrishna.me/blog # Navigation Menu - Home: https://saikrishna.me - Portfolio: https://saikrishna.me/portfolio - Github: https://github.com/s-kris - Contact: https://saikrishna.me/contact - Blog: https://saikrishna.superblog.cloud - See My Journey: https://saikrishna.me/journey # Blog Posts ## Press Author: Sai Krishna Published: 2025-01-28 Category: Press URL: https://saikrishna.me/blog/press Title Type Link Uğur KILCI Youtube Story [https://www.youtube.com/watch?v=HaGSCvXP1Is](https://www.youtube.com/watch?v=HaGSCvXP1Is) Mircofounder Text Interview [https://microfounder.com/startups/superblog/launch/r6axcbkyhi](https://microfounder.com/startups/superblog/launch/r6axcbkyhi) Startup Tales Podcast [https://www.youtube.com/watch?v=07JLkWPa\_fI](https://www.youtube.com/watch?v=07JLkWPa_fI) Founderbeats Text Interview [https://founderbeats.com/micro-saas-nocode-seo-blogging-superblog](https://founderbeats.com/micro-saas-nocode-seo-blogging-superblog) SaaSbites Text Interview [https://saasbites.substack.com/p/issue-9-interview-with-sai-krishna](https://saasbites.substack.com/p/issue-9-interview-with-sai-krishna) Entrepreneur Cafe Podcast [https://www.youtube.com/watch?v=mSsMI0z0NzM&t=2302s](https://www.youtube.com/watch?v=mSsMI0z0NzM&t=2302s) Entrepreneur Cafe Text Interview [https://entrepreneurs.cafe/blog/building-a-successful-saas-as-a-solopreneur-insights-from-sai-krishna-founder-of-superblog/](https://entrepreneurs.cafe/blog/building-a-successful-saas-as-a-solopreneur-insights-from-sai-krishna-founder-of-superblog/) Equip Text Interview [https://equip.co/blog/founder-stories-sai-krishna-superblog/](https://equip.co/blog/founder-stories-sai-krishna-superblog/) bytesizedbets Text Interview [https://bytesizedbets.com/p/how-to-build-a-profitable-lifestyle?triedRedirect=true](https://bytesizedbets.com/p/how-to-build-a-profitable-lifestyle?triedRedirect=true) The road to save planet Podcast [https://open.spotify.com/episode/6E8Tz5cskdrKwC66lb5EMA?si=xt\_TepKzRdmDybL\_YFNnMg&nd=1&dlsi=4d14ca931301417a](https://open.spotify.com/episode/6E8Tz5cskdrKwC66lb5EMA?si=xt_TepKzRdmDybL_YFNnMg&nd=1&dlsi=4d14ca931301417a) Website Planet Interview Text Interview [https://www.websiteplanet.com/blog/superblog-interview/](https://www.websiteplanet.com/blog/superblog-interview/) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Superblog: 3 year Journey Author: Sai Krishna Published: 2023-12-31 Tags: superblog, saas URL: https://saikrishna.me/blog/null It’s been three years since [Superblog](https://superblog.ai) was launched as a solo indiehacker product. Currently at $4.5K MRR. Random experiences, learnings, and thoughts: \- Building a b2b product is more valuable for the effort you put into it. My reference point is having built multiple B2C products that scaled to millions of users \- Customers are more supportive \- Purchase power is much better than a B2C product. Can easily charge $29/mo from businesses \- Less churn than b2c if value offering is good \- Choosing the right tech stack made a lot of difference. The balance between comfort and productivity matters a lot \- Having a clear idea of the product and business roadmap proved to be immensely helpful \- Received 5, 6, 7 figure acquisition/acquihire offers (cash + equity) \- Took small money from Adobe design fund. Yes, THE Adobe \- If you are solving a real problem, even billion-dollar brands will use your product. No matter how small or big you are. Superblog is used by Swiggy, Sezzle(India), Juspay, Aisle, Drivelah, SALT etc \- Setting up automations is very important when you are a solo indiehacker. I was in the USA for a six-month vacation. Yes, six months. I had to take this vacation due to my decade of constant grind, personal trauma, and work hours. I was still working on Superblog but very very minimal number of hours. The automation, goals, and clarity helped me very much \- Almost 5x MRR growth this year, even with vacation \- Don’t be lazy with the quality of the product. Design, performance, support. Everything compounds. Customers deserve that. It is our way of showing them respect when they pay their hard-earned money. That’s why I take extreme care while building the product. It has to give a wow experience for users. But at the same time make sure your time is spent on the right things to optimize for success \- Picking the right positioning, branding, messaging, and customer profiles is very important for product growth and success \- Building in public turned out to be very helpful for me. Shared some, received a lot. People started following superblog, talking about superblog, questioning superblog, and then loving superblog. Received immense support from strangers (who became friends). People, literally, found typos in random places and sent me screenshots to fix them. People referred superblog as if it’s their friend’s product, as if it’s their own product. Send me DMs of copycats, and helpful resources. All with ZERO expectation in return. Some humans are amazing. I’m grateful to all of you! Superblog as a brand has been established now. We are not going anywhere. I have some interesting thought experiments to run next year, will superblog remain a solo indiehacker product, or join the big boys league remains a question. Even for me. One thing for sure is that the product will be loved by as many users as possible. I think that’s the best way to build a company. Thank you so much, everyone - customers, family, friends, well-wishers, kind strangers, and copycats for the love and support. Just extending my heart-felt gratitude to a few people who are with me on this journey: Mohit Vivek Ram Ryan Kundavai Nikhil Shreekant Santosh Bimlesh Harnidh Bhanu Santosh Jibin Antony Able Ahaan Anupma Kindly forgive me if I forgot anyone. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Migrating Superblog from Render to Hetzner with CapRover + Cloudflare Proxy Author: Sai Krishna Published: 2023-09-21 Tags: nextjs, caprover, web-development, cloud URL: https://saikrishna.me/blog/null I have been building apps since 2011. Worked with multiple cloud providers and architecture paradigms over the years.  This is what my current approach looks like: 1. JAMStack + Cloudflare whenever possible 2. SSG with NextJS 3. Netlify, Vercel, Render, and Caprover for deployment 4. Docker Containers, Serverless Functions (rare) 5. Hetzner, Digital Ocean, AWS clouds 6. React, Svelte, Prisma, Postgres, Typescript I'm mentioning all these because I don't want to hear "BuT WHy YOU do ThIS?". Please read the entire article and linked resources. Context ------- I've been building Superblog (a JAMStack blogging platform focused on SEO and Speed) for the last 2 years and 10 months as a solo indiehacker. The dashboard where customers login and write posts is built with NextJS and deployed as a node-express app. You can read why I did this instead of deploying it like a serverless app [here](https://superblog.ai/blog/using-prisma-with-nextjs-at-scale-ckpld2icd05251yo0mjow4fmi).  In short, due to: 1. Connection pooling issues 2. Cold start times But since then Prisma released data proxy and reduced cold start times by 5x. Anyway, I could not deploy to Netlify or Vercel back then and used my favorite/love [Caprover](https://caprover.com) as always.  How does Caprover work? ----------------------- Caprover is similar to Dokku (if you are familiar) but also with a GUI. Install caprover on any server with a minimum of 1GB and we can connect our GitHub repo to setup CI/CD. Caprover uses docker swarm to auto-scale the deployed app. It involves setting up a wildcard A record for automatic SSL (with lets encrypt). You can also deploy apps via CLI, tar-ball, docker images, and one-click apps! The Catch --------- We cannot use Cloudflare to mask it because the free plan doesn't support masking wildcard records. It requires $200/mo. Using caprover alone gives away the IP address of the server. Which can be used to launch a DDoS attack. But who does that? Who would want to attack a poor indiehacker earning less than $5K MRR, right? Right? ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/screenshot-2023-09-28-at-2-1695892712114-compressed.png) Initial Setup ------------- Due to the above reason, I skipped Cloudflare and just installed Caprover on the Digital Ocean droplet and deployed the Superblog dashboard during the launch. Digital Ocean because I used the managed Postgres from them. Just wanted to keep everything in one place (Hetzner doesn't offer managed databases.). $12/mo for VPS (2GB, 1vCPU) and $15/mo for the Postgres database. Everything was good.  Migration to AWS ---------------- I got free AWS credits with 2 years of validity. So, I migrated everything to AWS. Lightsail VPS (16GB, 4vCPU :P) and RDS Postgres Database (2GB RAM, 20GB Storage). Again, using Caprover without Cloudflare proxy. Why migrate to Render? ---------------------- Those were the days of DDoS attacks. DDoS attacks on indiehackers. Many indiehackers that I know personally were attacked. I had a hunch that I'll be next. However, I researched, tried, and tested an alternative in case of an attack. That alternative was [Render](https://render.com). ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/screenshot-2023-09-28-at-3-1695895626057-compressed.png) I was traveling to the USA from India in April 2023 but not anyone outside of my immediate circle knew this. Well, except for one cute girl I started talking to 4 days ago. I'm pretty sure she is sweet, kind, and a good person. She didn't have anything to do with what happened next. When I was close to Dubai, I received a downtime alert for the dashboard. I knew this was an attack because AWS typically doesn't go down (lol). I decided to add Cloudflare Shield but the inflight WiFi wasn't so great. I planned every single step to do after getting out of the flight beforehand. I had around 2 hours of time in layover where I could get the airport WiFi to do this. But I also have to help my sister with my nephew during transit. Additionally, the airline staff messed up my boarding passes. I had to get that fixed AND take care of Superblog. It was like a high-tense thriller. I usually like such situations. My brain goes into overdrive mode. Love it! So, moving to Cloudflare could be a bad idea with such less time especially since it involves changing nameservers. There would be downtime and I'd be over the Atlantic Ocean. What's the next best thing? Render.  Render because they use Cloudflare internally. It means I can deploy the Superblog dashboard to Render and let their Cloudflare protection act as my shield. it barely took a few minutes. I deployed the Superblog dashboard by connecting the Github repo to Render and added a simple CNAME in DNS records. In a few minutes, propagation was done and SSL was generated. The attack died down over the next few days! Why migrate from Render to Hetzner? ----------------------------------- It turns out that using 2GB RAM, 1vCPU ($25/mo) plan wasn't enough for the superblog dashboard. So, I upgraded to the next plan which is $85/mo (such a jump) which gives 4GB RAM, 2vCPU. Turned out, I had $500 credits in my render account because I listed superblog on Betalist the previous year. Win! :D So, I've been using Superblog on Render since April 2023. My AWS credits ran out in May. Render credits exhaust in September. So, I started looking towards my good old buddy - Hetzner. I did not choose Digital Ocean because their SMS 2FA sucks. I've been locked out because their SMSes never arrive most of the time. I have to use recovery codes to login. This means no more managed database on Digital Ocean as well.  I'm using the AWS Lightsail Postgres database for $15/mo. And the Hetzner VPS of $8/mo with 8GB RAM, 4vCPU. Obviously, build time is much much lesser when compared to Render. This time, I'm using Cloudflare Proxy in front of my Hetzner.  Using Caprover with Cloudflare Proxy ------------------------------------ Generally, you setup a wildcard record like **\*.something.example.com** in your DNS. Then **captain.something.example.com** will be your caprover dashboard. **app1.something.example.com, app2.something.example.com** will be the domains for your apps. You can then map a custom domain to your apps on caprover. For more detailed explanation of regular usage, read the [caprover docs](https://caprover.com/docs/get-started.html). This approach doesn't work because Cloudflare doesn't mask wildcard records in the free plan. Steps to make it work --------------------- 1\. Migrate your domain to Cloudflare. 2\. Disable domain verification in caprover. echo "{\\"skipVerifyingDomains\\":\\"true\\"}" > /captain/data/config-override.json docker service update captain-captain --force 3\. In Cloudflare, Add A Record => captain.example.com => Server IP address (disable proxy). Enable SSL in caprover. After some time, enable the Cloudflare proxy.  4\. Run caprover serversetup in your local machine. 5\. Enter the root domain as **example.com.** This is mandatory because Cloudflare doesn't do SSL for 4-level deep in the free plan.  6\. Use the desired subdomain name as the app name when deploying because you can't add the same custom domain later (which is part of the root domain) due to caprover restrictions. Caprover then generates **myapp.example.com** as the subdomain. If you want to avoid this situation, deploy caprover on a different root domain than your app's actual domain.  For example:  Root domain: example.net Caprover dashboard: captain.example.net App deployment URL: myapp.example.net Custom domain: dashboard.example.com 7\. In Cloudflare, Add A Record => dashboard.example.com => Server IP address (disable proxy). Enable SSL in caprover. After some time, enable the Cloudflare proxy.  8\. Set SSL encryption to "Full" in Cloudflare. 8\. That's it, you now have your own Render/Heroku at a super low cost with Cloudflare Protection.  ![How I felt after figuring out Caprover + Cloudflare](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/f6jaxgrwwaaarq-1695898937721-compressed.jpeg) Me after figuring out how to make caprover work with cloudflare (proxy enabled) You can [follow me on Twitter](https://twitter.com/_skris) for such in-depth tech takes.  Caution: you might also see some random memes and useless thought experiments.  Also, people might think, why all this hassle to save a couple of hundred dollars? The current major cost to run [Superblog](https://superblog.ai) is $23/mo (VPS and Database). How cool is it that a $5000 MRR SaaS is run with a $23/mo stack? How cool is it that we can run a $25000 MRR SaaS with the same $25/mo stack? Isn't it cool?  ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/breaking-bad-walter-white-1695900768591-original.gif) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## WhatsApp ServiceExtension consumes a high CPU usage (96%) on M1 pro Author: Sai Krishna Published: 2023-05-11 Category: Glitch Alert URL: https://saikrishna.me/blog/null ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/screenshot-2023-05-10-at-8-1683771049018-compressed.png) I started noticing my Macbook Pro M1 Pro's battery depleting faster and faster. And then noticed it is getting hot which I thought was okay because I'm a hardcore developer and run a heavy workload locally.  But this kept happening when I wasn't running any coding workloads. That's when I realized damn it, there must be some bad actor jacking the CPU usage. Coming from an Intel Macbook Air to a Macbook Pro M1 Pro chip made me forget about performance issues and battery issues. How spoilt was I? ![whatsapp service extension consuming high cpu usage](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/screenshot-2023-05-10-at-8-1683771023558-compressed.png) Turns out, one "Service Extension" is the culprit. Digging deeper revealed it was the WhatsApp Native App for MacOS (beta) hogging on the CPU (96%) consistently for hours and hours. WhatsApp has a desktop App but the generally available version is not native, it is just an electron wrapper. They are building a native Mac app, the one which I was using. The beta version has this massive bug (I'm on the latest version). Interestingly, WhatsApp was closed (not quit), but still, the bug occurred. In fact, my Macbook's lid was closed - it should have gone to sleep! So, I promptly deleted the application and data folders from Library/Containers. Everything looks good!! ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/screenshot-2023-05-10-at-8-1683771036279-compressed.png) This is so so strange to find after seeing this recent Tweet about WhatsApp using Mic in the background on Android devices. ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/screenshot-2023-05-10-at-9-1683773672452-compressed.png) I wish developers are a bit more aware while developing large-scale applications. On this note, I decided to write more frequently about the product issues I find commonly in day-to-day usage. This has been on my mind for quite some time, but today's the day. I won't be sending out a newsletter (not a fan). You can [follow me on Twitter](https://twitter.com/_skris) to know about the latest Glitches that I keep finding. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Over-thinking the cost of Javascript Author: Sai Krishna Published: 2022-02-04 Tags: nextjs, remix, javascript, svelte, chakra-ui URL: https://saikrishna.me/blog/over-thinking-the-cost-of-javascript-e66012841c4b I love to over-engineer. Most of the time it is bad but sometimes we get to build cool things. Ever since I saw GatsbyJS, I wanted to re-write everything to JAMStack whenever possible. [I did save $400/year](https://skris.medium.com/how-i-saved-400-year-by-switching-from-bluehost-vps-to-netlify-migadu-dbcc7d9e9d58) by doing so. Next, I was able to run a programmatic SEO property with over 165,000 pageviews/mo on a $5 digital ocean droplet + Cloudflare CDN using JAMStack. Then came the problem of shipping too much JS. GatsbyJS was notorious for it. I tried to use the gatsby build plugin to remove unused javascript on the page. In the meantime, I loved using Nextjs to build dynamic web apps which shipped lesser javascript. Nextjs introduced automatic static optimization with v9, basically JAMStack. I wanted to build a JAMStack blogging platform with all the best practices that I used for my previous SEO-focused blogs and sites. The goal was to hit a 95+ score in web.dev audit. Thus, [superblog](https://superblog.ai/) was born. As usual, I chose Nextjs to build the dashboard and Nextjs (static export) to build the client- blog saas. The biggest problem with nextjs was that the build-time was too high for building client blogs. I need to make sure that users get the best SaaS blogging platform experience instead of waiting for the build + deployment to be completed. I tried eleventy, Hugo, [and a few others](https://twitter.com/_skris/status/1388259901080621056). Finally decided to use elderjs (svelte-SSG) because of the super-fast build times and Zero-JS pages by default for client blogs. We can hydrate individual components if we require interactivity on the page (e.g: auto-complete search box). No CSS frameworks were used, that’s right! Lesser page size! I really loved shipping ZERO-JS and decided to build the landing page of superblog with elderjs. The result is amazing! Go ahead and visit the page: [https://superblog.ai](https://superblog.ai/) ![](https://cdn-images-1.medium.com/max/1024/1*i3xvISC-UWQbLRoa931g7A.png) elderjs + ssg + almost zero js ### Obessesion over Zero-JS As you can see from the above picture, the superblog landing page and client superblogs built with elderjs + SSG + zero js are blazing fast and score really high in google audit. I became really obsessed with zero-js. So much that elderjs’ DX was not good but I still stuck to it. It takes 3-secs to refresh when I make a small change in my landing page. All this endurance when I already tasted ViteJS. NextJS finally switched to SWC from babel. But I refused to leave elderjs due to zero-js + partial hydration. I realized a slight mental barrier when I needed to work on my elderjs codebase which I believe is slowing down my dev. Elderjs introduced esbuild for dev but it wasn’t too reliable. Then I came across Astro. All the beauty of elderjs’ zero-js and partial hydration + near-instant HMR. Cherry on the top: framework agnostic (choose react/vue/svelte). But their build times are higher. Astro is working to fix the slow build process. So Astro is ruled out for client superblogs but I can still consider it for superblog.ai’s landing page. This time, I decided to use a UI framework — Chakra-UI(react) because I loved using it for superblog’s dashboard. Sadly, it doesn't work well with Astro and I don't want to use Tailwind CSS (fight me!). ### Moving past Zero-JS I want to use Chakra-UI for building my landing page because there are many ready-made components that are beautiful. I can easily build the landing page and the programmatic SEO pages. In the meantime I came across Remix — it is a pure SSR framework that ships zero-js by default. Their HMR is as good as ViteJS’. I tried to re-write superblog’s internal admin dashboard in Remix but I scrapped the idea (that is beyond the scope of this article). So, I didn't care about shipping Zero-JS for the landing page and started building a portion of the landing page with NextJS. This is what the page looked like: ![](https://cdn-images-1.medium.com/max/1024/1*g2Jw3uEfBaosj_uQcKz3tA.png) ### ChakraUI + Nextjs ![](https://cdn-images-1.medium.com/max/1024/1*3wc0RSPodieaHXqzK078TA.png) nextjs + chakra-ui My heart broke. I immediately deployed the nextjs+chakra starter template and found similarly disappointing results. ChakraUI + nextjs tree-shaking is not well optimized. So, I rebuilt the same in Remix. ### ChakraUI + Remix ![](https://cdn-images-1.medium.com/max/1024/1*T3QIe6wywneZbiZi6pGfqg.png) remix + chakra-ui Remix version is better but not at all comparable to the elderjs version of the [fully-loaded landing page](https://superblog.ai/). I tweeted the findings but later deleted them as I wasn’t well back then to answer the many questions I received. ### ChakraUI + Nextjs + DisableJS So, I thought of testing the nextjs version by removing the javascript completely. We need to add the following to the routes to disable js. > _export_ const config = { > unstable\_runtimeJS: false > }; ![](https://cdn-images-1.medium.com/max/1024/1*dnSjoUG2nW_EJW-9qzCegw.png) nextjs + chakra-ui (js-disabled) The web.dev audit score is much better now! I can simply switch to a lightweight UI framework and NOT disable the JS to score very high in web.dev using NextJS. But then again, due to the obsession with ZeroJS, I’m overthinking about shipping extra js which essentially means the browser has to download more content, parse more js and render the UI => more compute. However, I will try to stick to NextJS + ChakraUI and optimize the JS version to score high. ### Wishlist for a JS framework NextJS + SSG + Zero JS + Partial Hydration + ViteJS-like HMR speed ### Links chakra+ nextjs: [https://chakra-nextjs-test.vercel.app/](https://chakra-nextjs-test.vercel.app/) chakra+ nextjs + js disabled: [https://chakra-nextjs-test-no-js.vercel.app/](https://chakra-nextjs-test-no-js.vercel.app/) chakra + remix: [https://chakra-remix-test.vercel.app/](https://chakra-remix-test.vercel.app/) ### Source code * [GitHub - s-kris/chakra-nextjs-test: repo to compare nextjs vs remix](https://github.com/s-kris/chakra-nextjs-test) * [GitHub - s-kris/chakra-remix-test: repo to compare nextjs vs remix](https://github.com/s-kris/chakra-remix-test) P.S: I got exhausted after writing half of the article. Please excuse or ask me if I missed something :D ![](https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e66012841c4b) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Using Prisma with Nextjs at scale Author: Sai Krishna Published: 2021-09-04 Tags: nextjs, prisma, web-development URL: https://saikrishna.me/blog/null ![](https://superblog.supercdn.cloud/site_cuid_ckox4in4f002nl8lhcib41g2u/images/photo-1595864706735-b8af61a279f6-1630852576108-compressed.jpeg) Prisma ------ ​[Prisma](https://prisma.io/) is a type-safe and easy-to-use ORM. It started garnering a lot of interest and developers are flocking to use Prisma 2 in their applications. Prisma offers schema-based client-SDK generation, easy migrations, and most of all, type-safety out of the box. Prisma Studio lets you view and modify your database right from the browser. To top the dev experience, they recently announced "Prisma Cloud", a neat cloud-dev environment. > This article assumes that you have general knowledge about using ORMs, Prisma and Nextjs Superblog ------------ ​[Superblog](https://superblog.ai/) is a JAMStack blogging platform. And so, your blogs are [blazing fast](https://superblog.ai/blog/superblog-a-static-love-story-ckj36105v000717jnk01ke7ne), auto-scalable, have zero server maintenance.  There are multiple modules in Superblog: 1. Marketing website (landing page) 2. Dashboard (where clients log in and write their posts) 3. Clients' blogs 4. Superblog admin panel (to manage customers) 5. Misc code bases for maintenance and research As you can probably notice, managing the data layer for all these applications will be not so easy. All the codebases should be in sync with the data schema all the time. Add typescript types to that!  Single source of truth ------------------------- What I love about Prisma is that it generates the entire SDK that you need to CRUD the database from a single schema file.  ![](https://superblog.supercdn.cloud/site_cuid_ckox4in4f002nl8lhcib41g2u/images/supershot-1630856819887-compressed.png) schema.prisma Prisma generates types, functions that are needed to perform your business logic. However, the SDK is generated in the node\_modules folder and some may think, it's an anti-pattern. But hey, if it works, it works! Everything is type-safe. And, you can use those types in your front-end. Superblog's dashboard is built entirely with REST API (I do dream of switching to GraphQL, which by the way can be auto-generated using Prisma + Nexus). It is a pleasure to use the same auto-generated types on the front-end and backend! > Lot of time can be saved and code works in a predictable way  ### Reusing the source schema Prisma's tooling supports analyzing an existing database to generate the client SDK. This is called [introspection](https://www.prisma.io/docs/concepts/components/introspection).  ![](https://superblog.supercdn.cloud/site_cuid_ckox4in4f002nl8lhcib41g2u/images/supershot-2-1630857934025-compressed.png) I defined the schema in one codebase and the same is introspected from all other codebases. This way, my data layer is consistent across all my applications - both internal and external. The amount of effort that I have to put in to achieve this is little to minimal. > number of types \* functions \* REST APIs \*  number of codebases would've been overwhelming without this approach Nextjs ------ Superblog's [dashboard](https://write.superblog.ai/) is built with Nextjs. There are a number of tutorials on how to use Prisma in Nextjs' API routes. But the thing is, Nextjs is serverless-first and so it converts all the API routes into lambda functions. Generally, this is very good for scalability. We can simply deploy the application to Vercel or Netlify and focus on business logic instead of DevOps. Except it is not that _straightforward_. ### Cold starts This is not specific to Nextjs but to the concept of Serverless architecture. The functions aka routes aka underlying hardware go to sleep when there is no activity for a certain period of time. When a new request hits the endpoint, the serverless functions i.e in this case Nextjs API route functions are invoked, and Prisma Client is initialized. The total time taken for this depends on the platform where you deploy but mostly everybody is catching up.  To fix this: 1. ​We can keep the functions warm. 2. Prisma can be initialized outside of the function (route) handler to keep the DB connection alive. For some time. However, there's still a delay in starting the function + connecting to DB. I want to give a blazing fast experience throughout the Superblog's workflow. So, this _is_ a major problem for Superblog! ### Connection Hell -> Pool What we achieved with serverless, the infinite auto-scaling will now cause another issue. As the number of requests to our serverless application increases, new instances are spun on-demand. Which means more connections to the database. If you are using any of the managed databases (you should) from AWS, Azure, or Digital Ocean, etc. the number of simultaneous connections will get exhausted pretty quick. This _can_ be solved by:   1. Upgrading the database capacity 2. Using a connection pooler 3. Switching to a serverless-first database   4. API-first databases (http(s)-only CRUD) But we want to use Postgres for Superblog's data. Using a connection pooler is a no-brainer and I think it should be a default for all scenarios anyway. At the time of writing his article, Prisma teased a data proxy to solve this exact problem.  However, I had to find a way to overcome both of these problems for better UX and scalability.  Custom server in Nextjs -------------------------- Nextjs app can be converted into a pure nodejs app with just a few lines of code. And when I say nodejs app it should obviously be an express server app.  By defining a [custom server](https://nextjs.org/docs/advanced-features/custom-server) for superblog's dashboard, I was able to initialize Prisma once only 1 connection call to the database, (however, Prisma maintains a pool that can be controlled). Next, the prisma object is passed on to all the routes of the application via Express' _req_ object. Business logic can be performed in the REST endpoints (routes) with the same Prisma object. Suddenly, our capacity to handle requests shot up drastically! Phew! We just solved the problem of cold starts and connection hell (connection pooling can still be used).  ### What about auto-scaling the dashboard? A spike in traffic can take down our nextjs app (which is nothing but an express node app) because both Vercel and Netlify don't support this approach. One obvious way is to deploy our node app on EC2 and set up load balancer + auto-scaling groups.  I'm not a huge fan of this either. So, I containerized the entire nodejs app and deployed it using [caprover](https://caprover.com/). Caprover is basically an open-source Heroku using docker (you can use dokku too). So, with docker-swarm, I'm able to auto-scale the nodejs app. However, there are other easy and cheap solutions like [render.com](https://render.com/) and AWS AppRunner. As a matter of fact, I did deploy Superblog to render but moved to AWS (because of credits). If AWS App runner wants to be taken seriously, they should beat the DX of render. Sorry, I digress. Conclusion ---------- > What goes around, comes around We have kind of come full circle - taking a serverless-first framework and making it a server-app and then containerizing the whole app to auto-scale (serverless yay!). But it works! Works fantastically. Now, depending on the number of requests, compute (and ram) load, new containers will be spun to maintain the performance of superblog's dashboard. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Fix Calendly not including Google Meet link with meeting Author: Sai Krishna Published: 2021-06-17 Tags: fix URL: https://saikrishna.me/blog/null One _fine_ day I noticed that Calendly wasn't including a Google Meet link for my meetings. Not sure what changed or why it happened. I disconnected my Google Meet/ Calendar connection and reconnected to my calendly account. But still, the meeting links weren't being added to the meetings automatically. I did a quick search but didn't really find anything. So, today I was casually reading Calendly's docs and checked the event type's settings to finally fix it. ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/Screenshot 2021-06-17 at 11-1623910124749-compressed.png) 1. Edit the event type you want to add the Google Meet link automatically. 2. Click on the 'Event Type'. 3. Now you can see the **Location** field in the expanded section. Select Google Meet or any other meeting solution that you want. That's it! --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Fix for AWS beanstalk failing to create a new app Author: Sai Krishna Published: 2021-05-03 Tags: fix, aws URL: https://saikrishna.me/blog/null ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/photo-1573164713988-8665fc963095-1621688072787-compressed.jpeg) Sometimes when you are creating a new app in AWS Beanstalk, the environment fails to be created or launched because of missing permissions for the service role. The health status might also be shown as a warning with a similar error. You need to head to **IAM Roles** and assign new permission to "aws-elasticbeanstalk-service-role".  Attach "**AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy**" policy to the service role for the error to be fixed. **Note: **The "AWSElasticBeanstalkFullAccess" policy has been removed by AWS. So the above-mentioned policy needs to be attached. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## How to disable Netflix autoplaying trailers on homepage Author: Sai Krishna Published: 2021-04-05 Tags: tutorial, netflix URL: https://saikrishna.me/blog/null > It's so annoying! > > \- Every Netlifx user ever, probably. ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/photo-1574375927938-d5a98e8ffe85-1617630460549-compressed.jpeg) Image credits: Unsplash I'm pretty sure you landed here because you want to turn off and stop auto-previews of trailers that Netflix plays automatically. The solution is very simple and works for all your devices like android, iPhone, Browser, TV. 1. Go to your Netflix [account settings](https://www.netflix.com/YourAccount). 2. Under **PROFILE & PARENTAL CONTROLS**, expand the profile you want to apply the change. 3.  In **Play back** section, click **change**. 4.  Now you'll be in playback settings. Uncheck **Autoplay previews while browsing on all devices**. Hit save! ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/Screenshot%202021-04-05%20at%206-1617630580548-compressed.png) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## How not to build a music streaming app: Learn from Gaana.com Author: Sai Krishna Published: 2020-07-05 Tags: user-interface, spotify, app-development, user-experience, music URL: https://saikrishna.me/blog/how-not-to-build-a-music-streaming-app-learn-from-gaana-com-c4a9f544c47 Before I start, have a look at these screenshots: ![](https://cdn-images-1.medium.com/max/1024/1*7VhmF8jE76xBxJDRP-Am0g.jpeg) ![](https://cdn-images-1.medium.com/max/1024/1*DQzf2wSsWazQkTFwUndcFw.jpeg) Gaana vs Spotify ### **Preface** > I have been using Gaana since 2016. I switched from Saavn to Gaana solely because of their UI and dark mode. Parineeti Chopra being their brand ambassador and me loving her (for totally different reasons) had nothing to do with the switch. Really. Slowly, their UI started to bloat up with unnecessary features and elements causing eye sore. But I was using their service anyways because I primarily listen to Telugu songs and they have fantastic collection overall. Things changed when Spotify came to India and started offering Telugu collection. And that’s when I switched to Spotify. I had quit my job recently and so decided to cancel my Spotify premium subscription because I already have a yearly Gaana premium subscription. That’s when I realised even more, how much terrible Gaana is. At everything. Okay to be fair — not everything, they have a superior offline mode. I don’t want to talk about how Spotify is better at everything — UI, UX, **Personalised** **Mixes**, so I won’t be doing a comparison post. ### **Why is it so bad?** ### Home tabs ![](https://cdn-images-1.medium.com/max/810/1*uou-5a4yJt0P3A63MvQSIg.jpeg) Why are there 32 unnecessary sections? Why are there 64 tabs in the top? Why are there 128 moods & collections? (Sarcasm). **_Prioritise the information on screen._** Why is the most important section **‘Uniquely yours’** aka **Mixes** buried deep down? I had to scroll twice to see it on my S10 Lite which itself is a tall phone. You have huge collection, we get it. But just don’t throw it on user at once. Read: **Actionable Information.** ### **Player Screen** ![](https://cdn-images-1.medium.com/max/1024/1*yZEwFx3Xr2GxaCXJ1RlNqA.jpeg) **Rule no. 1:** Nobody gives a \*\*\*\* about those numbers — How many people downloaded it or liked it. **Rule no. 2:** ![](https://cdn-images-1.medium.com/max/600/1*1iOR_e6aFOc8J9Sx2zeyzg.jpeg) Seriously, at least not at the cost of immediate actionable elements like — let me remind you — Repeat/Shuffle options. Where are they by the way? ![](https://cdn-images-1.medium.com/max/1024/1*Rw4SJOGL0qVmuVuXJCBLXQ.jpeg) That’s right, hide them. I was listening to the same song for 15 minutes until I realised that I had turned on ‘Repeat one’ and closed the app previously. Give an option to hide the lyrics — A simple tap toggle? If you are gonna take half of the screen for queue (which has no way to be collapsed) what’s the point of that 2–3 line lyrics making that area clumsy? A small **side request —** remove the hashtag from artist name and album name under the song title on player screen. There are 10 unnecessary elements (12, if you count the stats for download and heart icons) which can be removed in the queue component. ![](https://cdn-images-1.medium.com/max/1024/1*ezK5oYRdpD6qsQ-rx5SqJA.png) 1. Use a swipe left gesture to remove a song from queue 2. Hold the song for rearranging the queue _Or simply change the colour for these two icons to a dull one._ ### **Radio Tab** I don’t care. Haven’t used it, probably won’t. ### Hotshots Tab ![](https://cdn-images-1.medium.com/max/1024/1*3diUYlcdAAsE6TzxRiYmFQ.jpeg) Okay, seriously this new **“tiktok-like”** feature gave me the final push to write this post. Come on Gaana, we don’t need another tiktok which was banned recently, for good. But if you insist about increasing user base, app usage I don’t really care as long as it is not visible to my eyes. ### **Buzz Tab** Zero \*\*\*\*\* ### **Gaana Plus Tab** I’d like to believe this should be a tab for My Account, My Music, Settings, Misc. Preferences etc. But could I be any more wrong? Why are you spamming your app with your own content? Don’t throw everything at user everywhere. Sorry for the very lengthy screenshot below but I had to embed it to show you how deep the **‘Listening history’** section was buried. ![](https://cdn-images-1.medium.com/max/810/1*QPbz4GNfMu_A4CkGtpsBoQ.jpeg) ### Web App Don’t even get me started on the web app. I’ll just mention a couple of my problems. ![](https://cdn-images-1.medium.com/max/1024/1*ruhu-YnQSAzWBQVzJvNypw.png) Who thought it was a good idea to place progress bar on top edge of the component? To seek a song, I have to carefully hover the mouse on that tiny element in order not to click on a song above which will start playing by accident. It’s stressful. **_1st world problems._** _(I actually live in India, so..)_ And that volume icon — to my mind — having built several desktop, mobile and web apps including a music player, it means the volume is set to a lower level. Kindly use different icons like below to indicate volume level. ![](https://cdn-images-1.medium.com/max/390/1*wPUMMT2qEJL7kOO2RB7IoQ.jpeg) ### Conclusion 1. Reduce clutter in UI 2. Improve UX (cc: Spotify) 3. Improve Mixes, vastly (cc: Spotify) 4. Show information on screen based on actionable importance 5. Have a consistent UX between web and mobile apps ### Who am I? I’m a huge music and movie lover. I’m also a techie and serial entrepreneur who had build multiple desktop, mobile and web apps with millions of downloads. Long shot, y_ou \*might\* have known_ [_mhotspot_](https://mhotspot.com/) _(A windows software to turn your laptop into wifi hotspot)._ I take so much care in building my products. You can know more about me here: [https://saikrishna.me](https://saikrishna.me/) ### Why I was so serious on UI & UX of Gaana? As I said above, I love music and elegant apps. I had built an open-source music player app, **_Rey_**, which acts as a beautiful front-end for Youtube. ![](https://cdn-images-1.medium.com/max/1024/1*T_3t5MVnZSXJw6VSqb_PYg.png) ![](https://cdn-images-1.medium.com/max/1024/1*PGGZAlVpLHL_HDewVwYCdA.png) **Reason to build:** [https://www.reddit.com/r/Music/comments/8sxjxo/rey\_reimagined\_youtube\_music\_player\_for\_desktop\_i/](https://www.reddit.com/r/Music/comments/8sxjxo/rey_reimagined_youtube_music_player_for_desktop_i/) **For developers:** [https://www.reddit.com/r/javascript/comments/9fjflv/reimagined\_youtube\_music\_player\_for\_web\_opensource/](https://www.reddit.com/r/javascript/comments/9fjflv/reimagined_youtube_music_player_for_web_opensource/) The app’s API quota is revoked by Google because I didn’t want to enter certain information in a certain form. You can download the app’s [source code](https://github.com/s-kris/rey) and run it locally with your own credentials. I just don’t want my favourite music app (especially for telugu collection) to become horrible. Dear Gaana, please don’t take this post in a negative way. Thank you! ![](https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c4a9f544c47) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## fix gatsby build getting stuck at source and transform nodes Author: Sai Krishna Published: 2019-11-10 Tags: bug, fix, gatsby URL: https://saikrishna.me/blog/null ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/photo-1583002158450-a748b8e07d52-1614445138722-compressed.jpeg) Sometimes, gatsby build process is stuck at source and transform nodes phase or may be at createPages etc. There is a very weird fix to it.  Trust me, this is going to sound very weird, _but it works_. > Just resize the terminal the window, the build process should resume. [Source](https://github.com/gatsbyjs/gatsby/issues/9706#issuecomment-527519075) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## fix error: 413 Request Entity Too Large on deploy with caprover Author: Sai Krishna Published: 2019-11-09 Tags: bug, fix, caprover URL: https://saikrishna.me/blog/null ![](https://superblog.supercdn.cloud/site_cuid_ckox4j3st002zl8lhgptt9yg2/images/photo-1614597388646-fea96377eb91-1614666041949-compressed.jpeg) What is it? ----------- When you are deploying a tar file with large size, you will see this error message. This is caused due to the nginx.conf which sets default max file size limit to 200MB. How to fix it? -------------- 1. In your captain dashboard, go to settings. 2. Edit the file `/etc/nginx/conf.d/captain-root.conf` and update `client_max_body_size 300m` as per your requirement. 3. Click 'Save and Update' for captain to reload nginx. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## How to fix frequent nodemon error: address in use Author: Sai Krishna Published: 2019-08-08 Tags: bug, fix URL: https://saikrishna.me/blog/null nodemon throws 'address already in use' after few file changes/restarts. Simple solution is to kill the port with kill -9 3000 (use the appr. port number). But we wouldn't stop at that, would we?create a nodemon.json file in the root with the below config. {     "events": {         "restart": "kill -9 $(lsof -t -i:3000)",         "crash": "kill -9 $(lsof -t -i:3000)"     },    "delay": 100} _change the port number accordingly._ we are hooking kill -9 $(lsof -t -i:3000) command to restart/crash events of nodemon which finds the process id running on the given port number and kills it. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Published a fully opiniated nextjs starter Author: Sai Krishna Published: 2019-05-08 Tags: portfolio, nextjs, opensource URL: https://saikrishna.me/blog/null It is a basic and fully opiniated template that consists of the essential elements that are required to start building a NextJs application. Why? ---- I end up doing the same setup, config for my projects repeatedly even for my personal projects which I code when I am bored or not. And it is way too often. So I decided to template all those things suiting for my personal approach. Feel free to give it a try here: [https://github.com/s-kris/skris-next-starter](https://github.com/s-kris/skris-next-starter)​ The template consists of: * a typcial project layout structure for [nextjs](https://github.com/zeit/next.js) * eslint setup and configuration * the main React components to get started * SEO via next-head * css-in-js via [emotion](https://github.com/emotion-js/emotion) * theming * global state managment via [react-easy-state](https://github.com/solkimicreb/react-easy-state) * typography.js --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## How I saved $400/year by switching from Bluehost VPS to Netlify + Migadu Author: Sai Krishna Published: 2019-01-01 Tags: gatsbyjs, react, web-development, migadu, netlify URL: https://saikrishna.me/blog/how-i-saved-400-year-by-switching-from-bluehost-vps-to-netlify-migadu-dbcc7d9e9d58 ![](https://cdn-images-1.medium.com/max/1024/1*dB7Ab0p7EN6GHYBLYtGM3w.png) Bluehost VPS Standard Plan I’ve been using Bluehost VPS for over 5 years. I purchased the **standard** plan for a year which was $24.99/month and then I kept on renewing it for 3 months at $28.99/month with the hope of moving to a cheaper hosting plan. Yes, I’ve been procrastinating this task for \*drum roll\* more than 4 years!! **What websites do I host?** [mhotspot.co](https://mhotspot.com/)m — mhotspot turns your windows laptop into wifi hotspot [saikrishna.me](https://saikrishna.me/) — my personal website [spotplay.co](https://spotplay.co/) — spotplay aims to be the offline netflix for travel (I was the co-founder & CTO) **mhotspot.com** mhotspot is a windows software to turn a laptop into wifi hotspot which I developed when I was in college (2011) and the website has over 50,000 page views daily. The other two websites draw very minimal traffic. This website, over years, was upgraded from a lay static html site to dynamic wordpress site with a blog. Due to wordpress, the performance was not top class but Bluehost VPS combined with **wp-static** plugin provided fairly decent page load times. The bandwidth consumption was around 100GB/month (which includes download of the installer executable). So, shared hosting plans are not ideal. Due to various reasons including me quitting from my startup(spotplay), decline of ad revenue from mhotspot and my side project [reymusic.co](https://reymusic.co/) (A Simple & Beautiful Music Player for Youtube) not performing as expected, I decided it’s time to reduce if not save those hosting fees I was paying to Bluehost. ### The Quest 1. Static WordPress Alternative 2. Cheap/Free Web Hosting 3. Cheap/Free Email Hosting Let me start by saying this — _I’m a huge fan of React & Serverless._ I’ve been building few projects with react and hosting them on firebase & heroku. So, I am fully aware of the new static-hosting providers with their generous hosting plans and static site generators to build awesome and cool web projects. **Website Framework** I played with Hugo, Jekyll and naturally due to my love for **React**, I had chosen **GatsbyJS**. This is easily one of the best decisions I’ve made in 2018. I’ve re-built mhotspot.com and saikrishna.me with GatsbyJS. **Website Hosting** For static hosting, I considered the usual suspects Firebase, Netlify, zeit/now, & Surge. **Netlify** with their Gitlab integration for CI/CD and 100GB monthly bandwith was my go to choice. Free CDN and Free SSL were a bonus (Most of the others provide them too). **Email Hosting** Finding a cheap (if not free) & reliable email host for custom domain is a challenge. Startups can’t afford to miss an email from clients or investors. [migadu.com](http://migadu.com/) found to be the best one in my research. Mail delivery times and uptime were reliable in the free plan so far. ### Conclusion ![](https://cdn-images-1.medium.com/max/888/1*4xHYs0WeDtriBTDmHnPu2Q.png) Netlify’s Static Hosting is 🔥🔥 ![](https://cdn-images-1.medium.com/max/440/1*HWTO508YOy8wA0AizNHo3A.png) Lighthouse Audit Score. Isn’t this what we all want? mhotspot.com built with GatsbyJS hosted on Netlify with migadu.com as email host is operated at practically free of cost with monthly bandwidth consumption of around 60–70 GB. Page load times and Performance are top class when compared with previous setup of Wordpress + Bluehost VPS which would normally cost me ~400 USD. **Updates:** 1. My monthly bandwidth usage exceeded netlify’s 100 GB, so switched to a $5 Digital Ocean droplet with [Caprover](http://caprover.com/). 2. There was a steep drop in adsense revenue further in mhotspot.com after building with GatsbyJS and there was a white page bug. Temporarily removed all ads on mhotspot.com 3. I deployed multiple apps on the same $5 digital ocean droplet and quickly ran into out of memory issue due to Gatsby build process consuming more ram. So switched to a EUR 4.9 plan on hetzner.com (The same would cost $20 on Digital Ocean), super reliable cloud provider but the only problem is the server locations — only present in Germany and Norway). 4. I subscribed to Micro Plan on Migadu. It’s only fair considering how long and well their free plan worked. ![](https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dbcc7d9e9d58) --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## How to migrate wordpress blog posts to gatsby Author: Sai Krishna Published: 2018-11-30 Tags: tutorial, gatsby, wordpress URL: https://saikrishna.me/blog/null Recently, mHotspot and blog were switched from two seperate wordpress installations to gatsby. The process, however, was easier than it should be. For mHotspot, I had to build additional templates for website pages and blog posts and make code changes to gatsby-config.js and gatsby-node.js. But the process for any wordpress blog (hosted at root directory) is pretty straight forward. 1. Create a new gatsby site from gatsby starter blog. 2. All the wordpress posts should be exported to markdown files using wordpress to jekyll plugin. 3. Copy the downloaded .md files to ./pages directory. That's it! Your site should now display those posts. This is not a full-length tutorial. You will need to make changes to the default gatsby-config.js, gatsby-node.js and graphql query for the post slug to appear the way you want. By default, post url will be the www.example.com/name-of-the-markdown-file/ --- This blog is powered by Superblog. Visit https://superblog.ai to know more. --- ## Set LDAC as default bluetooth codec in Android Oreo Author: Sai Krishna Published: 2018-10-09 Tags: tutorial, android URL: https://saikrishna.me/blog/null I enabled and chose LDAC as bluetooth code from developer settings menu. But after disconnecting and reconnecting my phone, the codec switches back to aptX. The solution is to go to **bluetooth settings** and **enable LDAC for paired** headphones. --- This blog is powered by Superblog. Visit https://superblog.ai to know more. ---