<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tameem Iftikhar</title>
    <description>The latest articles on Forem by Tameem Iftikhar (@tameem92).</description>
    <link>https://forem.com/tameem92</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F316519%2Fd45aed22-32ce-4fbe-840c-6038afda69ad.jpeg</url>
      <title>Forem: Tameem Iftikhar</title>
      <link>https://forem.com/tameem92</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tameem92"/>
    <language>en</language>
    <item>
      <title>Slick Like Ruby, Fast Like C — Does Such a Language Exist?</title>
      <dc:creator>Tameem Iftikhar</dc:creator>
      <pubDate>Tue, 25 Feb 2020 21:33:31 +0000</pubDate>
      <link>https://forem.com/tameem92/slick-like-ruby-fast-like-c-does-such-a-language-exist-4hfi</link>
      <guid>https://forem.com/tameem92/slick-like-ruby-fast-like-c-does-such-a-language-exist-4hfi</guid>
      <description>&lt;h4&gt;
  
  
  Yes, yes, it does
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VdPfhYq5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/11890/1%2ApfOreEtmEEbYo6Gmx8Ov1Q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VdPfhYq5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/11890/1%2ApfOreEtmEEbYo6Gmx8Ov1Q.jpeg" alt="Background vector created by rawpixel.com — [www.freepik.com](http://www.freepik.com)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my never-ending quest to find harmony between speed of doing things (development speed) and speed of the thing (performance), I came across a project in its incubation phases which had me thinking: “This could be the one language for me.”&lt;/p&gt;

&lt;p&gt;It was infatuation at first sight with &lt;a href="https://crystal-lang.org/"&gt;Crystal&lt;/a&gt;, a programming language built for humans and computers. What a noble cause. Having been a fan of the beauty of the Ruby syntax, the promise of Ruby-like syntax with the speed of C was intriguing — life-altering, even.&lt;/p&gt;

&lt;p&gt;Since that day, I’ve been closely following the progress of Crystal and today, I will make a case for why you should care. It’s quite honestly one of the most exciting languages with promise for great potential.&lt;/p&gt;

&lt;p&gt;Before we get into it, keep in mind that Crystal is not yet ready for production, but you can still find many projects already using it — like &lt;a href="https://github.com/mperham/sidekiq.cr"&gt;this version of Sidekiq&lt;/a&gt;, written in Crystal.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Crystal?
&lt;/h1&gt;

&lt;p&gt;So, why should anyone care about yet another programming language? Well, because Crystal has combined a concoction of incredibly compelling ingredients that you won’t find in many other languages.&lt;/p&gt;

&lt;h4&gt;
  
  
  Beautiful syntax
&lt;/h4&gt;

&lt;p&gt;One of the most appealing things about Crystal is the clean and readable Ruby-like syntax. The creators of the language understood the appeal of Ruby as one of the most visually appealing languages and they took it as the inspiration for Crystal.&lt;/p&gt;

&lt;p&gt;So, if you are coming from the Ruby world, transitioning to Crystal is going to be straightforward. Most of the time, you will be able to run Ruby code directly in Crystal, or run Crystal programs within a Ruby shell.&lt;/p&gt;

&lt;p&gt;To top it all off, you can even use Ruby syntax highlighting with Crystal. Similar to most interpreted languages, Crystal will let you build your wildest imaginations in a few lines of code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Blazing-fast performance
&lt;/h4&gt;

&lt;p&gt;Crystal is a statically compiled language built on top of the revered LLVM framework and can hold its own against the likes of C, &lt;a href="http://www.cplusplus.com/"&gt;C++&lt;/a&gt;, and &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just let that sink in a little bit… The development speed of Ruby syntax with speeds matching C…&lt;/p&gt;

&lt;p&gt;It’s incredibly compelling and hopefully has you as excited as I was when I first heard that claim. Don’t believe me? Just check out some of the latest benchmarks; &lt;a href="https://github.com/tbrand/which_is_the_fastest"&gt;this benchmark&lt;/a&gt; and &lt;a href="https://github.com/drujensen/fib"&gt;this benchmark&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hyper-performance with easy C bindings
&lt;/h4&gt;

&lt;p&gt;If a part of your application or algorithm requires extreme performance, one strategy is to offload the functionality to a C extension or library.&lt;/p&gt;

&lt;p&gt;With Crystal, binding to existing C libraries or your own C libraries can be done without writing a single line of C code.&lt;/p&gt;

&lt;p&gt;Consider a quick example of a C library &lt;code&gt;hello.c&lt;/code&gt; that we can build using the GCC compiler &lt;code&gt;gcc -c hello.c -o hello.o&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

void hello(const char * name){
  printf("Hello %s!\n", name);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After building the binary, you can easily link the binary using &lt;code&gt;Link&lt;/code&gt; and define the &lt;code&gt;lib&lt;/code&gt; declaration which groups the functions and types belonging to that library — followed by calling your function. Voila!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#hello.cr

@[Link(ldflags: "#{__DIR__}/hello.o")]
lib Say
  fun hello(name : LibC::Char*) : Void
end

Say.hello("your name")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Static typing
&lt;/h4&gt;

&lt;p&gt;Crystal is a statically-typed language, allowing it to rule out many type-related bugs at compile-time and setting the stage for optimizations that would not be possible in dynamically-typed languages like Ruby or Python.&lt;/p&gt;

&lt;p&gt;This directly contributes to the performance of Crystal and what’s even more impressive is that the compiler in Crystal only requires you to explicitly specify types in case of ambiguity — the rest of the time you can work with it like any dynamic language.&lt;/p&gt;

&lt;h4&gt;
  
  
  Macros
&lt;/h4&gt;

&lt;p&gt;Macros are a way to modify the abstract syntaxtTree created during a programming language’s tokenizing and parsing phase, allowing us to add methods at compile time or create and modify classes.&lt;/p&gt;

&lt;p&gt;The main advantage of this is speed — as you save a lot of time spent by the compiler for invoking/calling functions.&lt;/p&gt;

&lt;p&gt;Crystal lets you utilize the majority of the language when it comes to writing macros, which means you can do crazy wizardry that normally would be unheard of in a statically-compiled language.&lt;/p&gt;

&lt;h4&gt;
  
  
  Web frameworks
&lt;/h4&gt;

&lt;p&gt;Any comparison isn’t complete without talking about available web frameworks in the language and if you’ve already fallen in love with the likes of Rails and &lt;a href="https://github.com/phoenixframework/phoenix"&gt;Phoenix&lt;/a&gt; — you’ll feel right at home with Crystal’s web framework &lt;a href="https://amberframework.org/"&gt;Amber&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was designed from the ground up to follow Rails but is obviously an order of magnitude faster than Rails — with load times in microseconds not milliseconds.&lt;/p&gt;

&lt;p&gt;If you fall under the camp of &lt;a href="http://sinatrarb.com/"&gt;Sinatra&lt;/a&gt; lovers, fear not because you’ve got the simplicity of the &lt;a href="https://kemalcr.com/"&gt;Kemal&lt;/a&gt; framework.&lt;/p&gt;

&lt;p&gt;Did I mention that Crystal’s built-in HTTP server has been able to handle over &lt;a href="https://www.techempower.com/benchmarks/previews/round15/#section=data-r15&amp;amp;hw=ph&amp;amp;test=plaintext&amp;amp;l=zdk8an&amp;amp;c=3"&gt;2 million requests per second in benchmark testing&lt;/a&gt;? And most of the frameworks also deliver sub-millisecond response times for web applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Concurrency
&lt;/h4&gt;

&lt;p&gt;Crystal currently supports concurrency as a first-class citizen, while parallelism is making its way up the ranks — you can read about its progress &lt;a href="https://crystal-lang.org/2019/09/06/parallelism-in-crystal.html"&gt;on the Crystal website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Concurrency is supported in Crystal using &lt;em&gt;Fibers&lt;/em&gt; — a lighter-weight version of an operating system thread. Unlike threads, which are pre-emptive, Fibers explicitly tell the runtime scheduler when to switch context. This helps Crystal avoid unnecessary context switching.&lt;/p&gt;

&lt;p&gt;If you want to add concurrency, you’ll find the &lt;code&gt;spawn&lt;/code&gt; method in Crystal similar to the use of goroutines in &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt; — which I am personally a huge fan of.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Simple example
spawn do
  sleep 5.seconds
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Crystal also has support for channels inspired by &lt;a href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"&gt;CSP&lt;/a&gt; that allow communicating data between fibers without sharing memory and having to worry about locks or semaphores.&lt;/p&gt;




&lt;h1&gt;
  
  
  But Hold Up, What’s Not to Like?
&lt;/h1&gt;

&lt;p&gt;As software engineers, we are always making tradeoffs when choosing a programming language or framework and like any language, Crystal isn’t the answer to all your prayers and comes with its own limitations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crystal is still relatively young and immature which leads to a lack of community and packages at this particular point in time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This also results in a scarcity of development tools available even though they are readily becoming available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are aiming to do something incredibly specific, you’ll have trouble finding documentation but this just means we have an opportunity to be the first adopters and hack together cool projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even though concurrency is built into Crystal, work is still being done on parallelism being a first-class citizen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Due to the pre-production status of the language, there is a possibility of breaking changes until v1.0 is reached.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It also doesn’t have great Windows compatibility but quite honestly, that’s not a negative for me.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Takeaway
&lt;/h1&gt;

&lt;p&gt;It might still be a while until Crystal is ready for production use, with great tools and a thriving community behind it. But it’s comforting to know that a wonderful language like Crystal is in the works behind the scenes.&lt;/p&gt;

&lt;p&gt;Looking at all the features that Crystal brings together, it is deserving of a lot of attention and popularity. If I’ve piqued your interest, I would encourage you to check out Crystal and make your own decision.&lt;/p&gt;

&lt;p&gt;In the meanwhile, I will continue to evangelize Crytal and keep a keen eye on its progress.&lt;/p&gt;




&lt;h1&gt;
  
  
  Get Going With These Resources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/veelenga/awesome-crystal"&gt;Awesome Crystal — GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.reddit.com/r/crystal_programming/"&gt;Crystal programming — Reddit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://kemalcr.com/"&gt;Kemal&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://amberframework.org/"&gt;Amber framework&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>scaling</category>
      <category>programming</category>
      <category>coding</category>
      <category>codequality</category>
    </item>
    <item>
      <title>The Complete Guide to Blazing-Fast Performance in Rails</title>
      <dc:creator>Tameem Iftikhar</dc:creator>
      <pubDate>Wed, 05 Feb 2020 03:24:44 +0000</pubDate>
      <link>https://forem.com/tameem92/the-ultimate-guide-to-blazing-fast-performance-in-rails-1oh2</link>
      <guid>https://forem.com/tameem92/the-ultimate-guide-to-blazing-fast-performance-in-rails-1oh2</guid>
      <description>&lt;p&gt;Ruby on Rails is a tremendous framework when you want development speed for your project or startup. It’s useful right out of the box and comes with a plethora of behind-the-scenes magic to make your life easier. However, it’s not considered the fastest framework out there in terms of performance. You will find examples of individuals and companies drifting away from Rails in favor of something else. Despite this, there are many companies out there who have succeeded in scaling Rails and found success — just take a look at Airbnb, Github, Gitlab &amp;amp; Shopify. &lt;/p&gt;

&lt;p&gt;So before you jump ship, you should consider keeping performance at the forefront of your mind when working with Rails, and you can succeed too. This article aims to list the most important tips &amp;amp; tricks I’ve learned over the years to make Rails run at blazing fast speeds and scale to millions of requests per minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  General Tips
&lt;/h2&gt;

&lt;p&gt;First off, there are some general tips to implement in your Rails project to set yourself up for success. &lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up an APM
&lt;/h3&gt;

&lt;p&gt;You can’t improve performance if you don’t measure it first, making it necessary to have the right metrics tracked and monitored. You should be tracking load times, request times, and database query timings amongst other things. Personally, I’ve found &lt;a href="https://newrelic.com/"&gt;New Relic&lt;/a&gt; to be one of the best APM tools for Rails but it is a tad bit on the pricey side. A more affordable alternative is &lt;a href="https://www.skylight.io/"&gt;SkyLight&lt;/a&gt;’s free trial. &lt;/p&gt;

&lt;h3&gt;
  
  
  Stay Current
&lt;/h3&gt;

&lt;p&gt;I know personally how horrifying updating the Rails version for your project can be if you left it stale for too long, and I sympathize with anyone who had to go through this ordeal. So do yourself a favor and try to keep in sync with the newer versions of Ruby and Rails. This will help you skip the pain of jumping multiple versions and ensures that you have all the newer performance enhancements. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pareto Principle (the 80/20 rule)
&lt;/h3&gt;

&lt;p&gt;This is a well-known rule when it comes to developing software — The Pareto Principle. It’s also known as the ‘law of vital few’ and states that for most events, 80% of the effects are generated from 20% of causes. The idea behind this is to not waste time on micro-optimizations while you have bigger issues that need resolution. You won’t accomplish much by shaving off milliseconds in serialization if your database queries are extremely slow. So pick your battles carefully. &lt;/p&gt;

&lt;h3&gt;
  
  
  Keep it Lean
&lt;/h3&gt;

&lt;p&gt;Rails is backed by an amazing community behind it and a library of gems that can easily help you accomplish complicated tasks. But it’s easy to get carried away adding gems to your project, causing bloat. Be careful while selecting what gems to add to your project and try keeping your dependencies lean. &lt;/p&gt;

&lt;h3&gt;
  
  
  Be Lazy — Do it in a Background Job
&lt;/h3&gt;

&lt;p&gt;Whenever you need to do anything complicated or long-running, consider throwing it into a background worker — sending an email, push notifications, uploading pictures and the like. Minimizing work in the main thread will ensure a snappy response for users. The good thing for us is that Rails has multiple options to achieve this easily — &lt;a href="https://github.com/mperham/sidekiq"&gt;Sidekiq&lt;/a&gt;, &lt;a href="https://github.com/resque/resque"&gt;Rescue&lt;/a&gt; or &lt;a href="https://guides.rubyonrails.org/v4.2/active_job_basics.html"&gt;ActiveJob&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Change Your Serializer
&lt;/h3&gt;

&lt;p&gt;If you have an API in your project you are most likely using the ActiveModelSerializers gem for serializing your data. I would strongly suggest switching over to the &lt;a href="https://github.com/Netflix/fast_jsonapi"&gt;fast_jsonapi&lt;/a&gt; by Netflix. This gem is a whopping 25 times faster than the default ActiveModelSerializers and I can personally vouch for that from experience. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cache Me Outside
&lt;/h3&gt;

&lt;p&gt;Sometimes if you have a lot of static data or you can’t make things faster, another alternative is to use a cache. Rails makes this incredibly easy to do right out of the box. Here is an example of how easy it is to do a cache with an expiry time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# Lets say you have some categories you offer in your project.&lt;/span&gt;

  &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;expires_in: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
      &lt;span class="no"&gt;Categories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Active Record (Database)
&lt;/h2&gt;

&lt;p&gt;ActiveRecord is the magical ORM (one of the best ever to exist) offered by Rails. It’s easy to get caught up in the ease of use without understanding the details which can lead you to bottlenecks in the future. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use Thy Database&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is something that goes unnoticed or unimplemented by a lot of developers as they rush to do everything in code or maybe they are intimidated by writing raw SQL. But whenever possible or convenient, you should use thy database. Processing and sorting data structures in Ruby can chew up CPU time, while your database can do this without breaking a sweat. &lt;/p&gt;

&lt;h3&gt;
  
  
  Peek Behind the Curtain
&lt;/h3&gt;

&lt;p&gt;Don’t just get enamored by the magic of active record without worrying about what’s happening behind the scenes. In order for you to sweep out performance bottlenecks, you need to look at the actual queries that get triggered and understand them. In the development environment, Rails will print out all the queries getting run which allows you to notice any unnecessary queries. Also, here are a few tricks that will help you dig in a little deeper:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/tameem92/08579a3d2ac690fce395c21bedab4f11"&gt;https://gist.github.com/tameem92/08579a3d2ac690fce395c21bedab4f11&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  SQL Wizardry
&lt;/h3&gt;

&lt;p&gt;Don’t worry, I am not about to suggest you write everything in raw SQL queries. But learning the basics of SQL and database design will help you better understand what’s happening under the covers and allow you to optimize the queries as needed. It’s a valuable skill to have as a software developer and will go a long way in your career. &lt;/p&gt;

&lt;h3&gt;
  
  
  Be Stingy
&lt;/h3&gt;

&lt;p&gt;One way to make your queries more efficient is to only select what you really need. Instead of doing a SELECT * specify which columns you need the database to retrieve. By default ActiveRecord selects everything but you can leverage select or pluck to fix this problem. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/tameem92/d219ccc9745d4bd11a7f7da9f8d743f6"&gt;https://gist.github.com/tameem92/d219ccc9745d4bd11a7f7da9f8d743f6&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  N+1 Queries
&lt;/h3&gt;

&lt;p&gt;This is a classic problem. If you are loading a Blog from the database and then try to find all the comments for that blog by looping through the records, you are forcing Rails to run a query for each of the comments. This can be eliminated by preloading the comments Blog.includes(:comments) and helps avoid the N+1 query problem. &lt;strong&gt;Pro Tip:&lt;/strong&gt; take a look at &lt;a href="https://github.com/flyerhzm/bullet"&gt;Bullet&lt;/a&gt; gem to help you find any N+1 query problems. &lt;/p&gt;

&lt;h3&gt;
  
  
  Combining Queries
&lt;/h3&gt;

&lt;p&gt;When working with bigger teams with multiple developers on a project, sometimes you will notice every person touching the codebase might be adding queries throughout the code path. More often than not, these queries can be combined into fewer queries at the top of the code path. This ensures there are no duplicated queries and allows the database to strategically do the heavy lifting. &lt;/p&gt;

&lt;h3&gt;
  
  
  Index, Index, Index
&lt;/h3&gt;

&lt;p&gt;This is a database best practice that shouldn’t be ignored. If you don’t index properly you will negatively affect database performance and cause unnecessary table scans. When building a new feature think ahead to what will be queried in the project and attempt to add the correct indexes. If you have an existing project you can always use &lt;a href="https://github.com/gregnavis/active_record_doctor"&gt;Active Record Doctor&lt;/a&gt; or &lt;a href="https://github.com/plentz/lol_dba"&gt;LolDBA&lt;/a&gt; to sniff out missing indexes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Migrations
&lt;/h3&gt;

&lt;p&gt;When you are running at scale, and you have millions of records in your tables the normal way of running migrations in Rails will, unfortunately, fail you. They will either error out or lock tables for extended periods of time, taking your site down. Having dealt with this in the past there are two tools that will solve this pain point for you: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/github/gh-ost"&gt;Gh-ost&lt;/a&gt;: This is a triggerless online schema migration solution for MySQL and the only tool that worked for me at scale. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/soundcloud/lhm"&gt;LHM&lt;/a&gt;: This will migrate your tables while they are still online without locking your table.  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extreme Tip: Use Raw SQL if you dare
&lt;/h3&gt;

&lt;p&gt;If there is an endpoint where you desperately need performance, you can consider combining all the Active Record queries throughout your functionality to a single massive SQL query at the top to pull out any records you need to fulfill the use case. &lt;strong&gt;Disclaimer:&lt;/strong&gt; Yes, it’s hard to maintain a massive raw SQL query, and it’s also less readable. But I did mention this is only in case of desperation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Servers &amp;amp; Hardware
&lt;/h2&gt;

&lt;p&gt;When deploying a Rails project there are a few things to remember regarding the underlying infrastructure and architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose a Scalable Architecture
&lt;/h3&gt;

&lt;p&gt;With cloud infrastructure having come such a long way, gone are the days of having to build bare metal servers in order to scale your application. When deciding on your underlying architecture for a Rails project you should utilize a scalable cloud-based system. As an example, you can use AWS Fargate or Kubernetes to automatically scale your dockerized Rails application as needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brotli Compression
&lt;/h3&gt;

&lt;p&gt;Brotli is another compression algorithm based on gzip with multiple improvements and a better compression ratio. It is now supported with most web servers and adding it is an easy way to optimize the compression speed. And well, who doesn’t want free web performance improvement. (Reference: &lt;a href="http://www.instantshift.com/2018/03/02/gzip-vs-brotli-compression/"&gt;Brotli vs Gzip&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Give it More Juice
&lt;/h3&gt;

&lt;p&gt;Rails is notorious for using a lot of memory, especially if you have multiple puma workers running. So don’t let your application go thirsty, and give it some juice from the start. You can utilize memory-optimized instances on your cloud provider to set you up for success. And don’t forget to keep an eye on the swap usage on the server. &lt;/p&gt;

&lt;h3&gt;
  
  
  Tuning
&lt;/h3&gt;

&lt;p&gt;Since Rails 5 the webserver for Rails has been switched to Puma, and by default, it will only run one worker. As soon as you set up your Rails deployment make sure to increase the number of workers to the available cores on your machine or something more reasonable.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/2
&lt;/h3&gt;

&lt;p&gt;If you are utilizing a reverse proxy like Nginx make sure you have the HTTP/2 option turned on to give you all the performance advantages you get from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cherry on Top (Miscellaneous)
&lt;/h2&gt;

&lt;p&gt;We are almost at the finish line — this section is all about some extra tips for performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t Use Dynamic Methods
&lt;/h3&gt;

&lt;p&gt;Rails magic comes with a price. A few of these methods consume a lot of resources and it would be better to skip using them. As an example, the find_by() and find_all_by() are kind of slow because they need to run through method_missing and parse the name against the list of columns in the DB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Throttling
&lt;/h3&gt;

&lt;p&gt;As you scale you are bound to run into malicious attempts on various endpoints that can’t be cached and will cause expensive operations to chew up resources. To get around this, I would recommend adding a gem like &lt;a href="https://github.com/kickstarter/rack-attack"&gt;rack-attack&lt;/a&gt; to implement throttling on endpoints like login, reset password or sign up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Know your O(n) vs O(1)
&lt;/h3&gt;

&lt;p&gt;As the data set size increases we need to heed the impact of our code in terms of time complexity. In a scenario where lots of data needs to be processed or looped over, consider using a hash instead of defaulting to arrays.&lt;/p&gt;

&lt;h3&gt;
  
  
  Always use a CDN
&lt;/h3&gt;

&lt;p&gt;All your static assets should always be fronted by a CDN and make sure the cache policies are reasonable. If you want granular control over the cache invalidation, you can look into using e-tags and Cache-Control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced
&lt;/h2&gt;

&lt;p&gt;In extreme cases, you can consider some advanced optimizations. I would argue if you’ve reached this point it might be time to consider other languages for certain parts of your project that are computationally intensive, so I will keep this section brief.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brush up on C
&lt;/h3&gt;

&lt;p&gt;The main implementation of Ruby is written in C, which allows you to rewrite the slow part of your code in C as an alternative — e.g. if you are doing crypto algorithms for generating certificates. If you aren’t so excited about the idea of dwelling into C code, you can leverage third-party gems written in C bythe Rails community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faster Background Jobs
&lt;/h3&gt;

&lt;p&gt;With an increasing background workload, you can switch your background workers to a more performant language. By utilizing queues like Redis or Amazon SQS, the workers can be decoupled into their own microservice. Checkout this Sidekiq compatible &lt;a href="https://github.com/jrallison/go-workers"&gt;go-workers&lt;/a&gt; library or a version of sidekick written with &lt;a href="https://github.com/mperham/sidekiq.cr"&gt;Crystal&lt;/a&gt; as two options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try Faster Versions of Ruby
&lt;/h3&gt;

&lt;p&gt;There are a few implementations of Ruby aiming to increase the performance. If you are interested in these variations, take a quick look at &lt;a href="https://github.com/oracle/truffleruby"&gt;Truffle-Ruby&lt;/a&gt; or &lt;a href="https://www.jruby.org/"&gt;JRub&lt;/a&gt;y.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;If we look at companies using Rails we see that they were able to utilize the amazing development speed of Rails to put their customers first, and also managed to improve performance as they scaled. In this article, we talked about multiple tips &amp;amp; tricks for increasing performance. I hope you found this guide helpful. Till next time. &lt;/p&gt;

&lt;h2&gt;
  
  
  Love talking tech or startups?
&lt;/h2&gt;

&lt;p&gt;You’re in luck, me too! If you want to chat about cutting-edge technology, entrepreneurship or the perils of being a startup founder, find me on &lt;a href="https://twitter.com/TameemIftikhar"&gt;Twitter&lt;/a&gt; or on &lt;a href="https://www.linkedin.com/in/tameemiftikhar/"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>productivity</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
