Please disable your adblock and script blockers to view this page

How Shopify Reduced Storefront Response Times with a Rewrite

The Storefront Renderer
Rhone Apparel

Legacy implementationSince
Damian Polan

No matching tags

No matching tags

Old Storefront Implementation


No matching tags

Positivity     33.00%   
   Negativity   67.00%
The New York Times
Write a review: Hacker News

As a result, the new implementation always reads from dedicated read replicas, improving performance and reducing load on the primary writers.Similarly, by rebuilding and extracting the storefront-related code in a dedicated application, we took the opportunity to think about building the best developer experience possible: great debugging tools, simple onboarding setup, welcoming documentation, and so on.Finally, with improving performance as a priority, we work to increase resilience and capacity in high load scenarios (think flash sales: events where a large number of buyers suddenly start shopping on a specific online storefront), and invest in the future of storefront development at Shopify. The end result is a fast, resilient, single-purpose application that serves high-throughput online storefront traffic for merchants on the Shopify platform as quickly as possible.Once we clearly outlined the problem we’re trying to solve and scoped out the project, we defined three main success criteria:Before building the new implementation, we needed a way to make sure that whatever we built would behave the same way as the existing implementation. The verifier service uses a fixed time value during the comparison process and sets any random values to a known value so we reliably compare the outputs containing time-based and randomness-based differences.The verifier service sends comparison result back to the Lua moduleThe verifier service sends the outcome of the comparison back to the Lua module, which keeps track of that comparison outcome for subsequent requests of the same kind.Once we had verified our new approach, we tested rendering a page using the new implementation instead of the legacy one. The comparison result is sent back to the Lua routing module, which keeps track of it for future requests.When a subsequent storefront request arrives from a buyer and reaches the Lua routing module, it decides where to send it based on the previous verification results for requests similar to the current one (based on the request attributesFor subsequent storefront requests, the Lua routing module decides where to send itIf the request was verified multiple times in the past, and nearly all outcomes from the verifier service were “Pass”, then we consider the request safe to be served by the new implementation.If most verifier service results are “Pass”, then it uses the new implementationIf, on the other hand, some verifications failed for this kind of request, we’ll play it safe and send the request to the legacy implementation.If most verifier service results are “Fail”, then it uses the old implementationWith the verifier mechanism and the dynamic router in place, our first goal was to render one of the simplest storefront pages that exists on the Shopify platform: the password page that protects a storefront before the merchant makes it available to the public.Once we reached full parity for a single shop’s password page, we tested our implementation in production (for the first time) by routing traffic for this password page to the new implementation for a couple of minutes to test it out.Success! Conversely, whenever we shipped a change to the new implementation that would fix a gap in feature parity, the verifier service starts to report verification successes, and our custom routing module in nginx automatically starts sending traffic to the new implementation after a predetermined time threshold.We collected Apdex (Application Performance Index) scores on server-side processing time for both the new and legacy implementations to compare them.To calculate Apdex scores, we defined a parameter for a satisfactory threshold response time (this is the Apdex’s “T” parameter).

As said here by