Rolling deployment adds an overhead of testing and longer deployment times but removes downtime altogether.

Rendering and SEO

We were using a hybrid render where the Django application would serve a partly rendered HTML and that would run the AngularJS application on the client. This caused many problems:

Our rendering was slow and choked our dev team and our servers. Our servers required a lot of processing power to be able to render and was an unavoidable bottleneck with our response times. Even development became difficult because we needed to code a change multiple times. At some point even changing a single tracking event was a hardship.

Poor build system resulting in high load times. We were using our own build system since there was no AngularJS build manager for a hybrid render, and our own system had a lot of bundling inconsistencies and caching issues that resulted in unoptimized builds and high load times. This was also a hassle to change and improve.

Website would occasionally hang for 5–10 minutes. When we get a spike of requests from users or bots the server would open too many connections with the database, causing the database to hang. This happened every week at the end of 2019 after our Series A brought Meddy more business. The reason was because Django opens a database connection and keeps it open until the rendering of the HTML is over! Due to too many database connections the server would hang and eventually serve a 504.

Solution

Soon after our Series A we embarked on switching our code from a Hybrid Render to a purely Client Side Render. For this to work we had to work on making a lot of changes to the way the backend serves requests.

We decided to use an S3 bucket as a static hosting for our frontend with CloudFront distributing the responses. CloudFront also gave us the option to attach Lambda functions to have very granular control over the requests we needed.

One of the main reasons that we did a hybrid render was a worry that SEO would be tarnished with a dynamic render; and one of the main reasons that our website was hanging was due to request spikes caused by bots. Both these problems would be solved by a pre-rendering our pages and serving the pre-rendered pages to bots which is perfect for SEO.

To do so we used a service called prerender.io which pre-rendered requested pages, cached those pages and served those pages to bots. We added a bot detection mechanism based on User-agent of the HTTP request in a Lambda Edge function used by our CloudFront distribution. Whenever a bot is detected, they’re redirected to prerender.io to get their cached pages.