2 Rules for Building Fast Functions with faastRuby

faastRuby is an entirely new way to develop APIs, integrations and web apps in Ruby & Crystal, and so it is our responsibility to educate the community on best practices.

One of the common benefits we hear from users of faastRuby is how fast the platform is. How quickly users can get a new project up and running, and how fast the functions perform. While speed was one of the major focuses we had when building faastRuby, overall performance is a shared responsibility. Success with functions requires you to rethink your application's design from the start.

If we think back to the original motivations for microservices over monoliths, the promise was that scale and availability of microservices were managed independently. Instead of adding more resources to an entire monolithic application, we could provide additional (or less) resources to an individual service as needed.

Building applications with functions is no different - we’re just breaking down the code even further into smaller pieces. Small units of logic are easier to test, and we can manage the scale and availability of those functions independently of one another.

The good news is that faastRuby Local was specifically designed to instill function development best practices, so that you can build performant applications quickly.

Let’s dig into 2 best practices for building fast, minimalist functions with faastRuby.

1. Fast functions are small in overall size and scope

With functions, the goal is to break down code into small pieces of logic. Each function should have a single responsibility. More smaller functions that work in parallel to make up the functionality of an application will perform and scale better than fewer larger functions which would take longer to run. Smaller functions will allow you to analyze and better understand how each piece of your app behaves over time, opening up opportunities for optimizations, but if they are too small you will end up with lots latency caused by network calls between functions. The sweet spot will depend on what you are trying to do

With faastRuby, runners execute functions as soon as they are triggered. The more lightweight your functions are, the faster they will be and the more requests per second you can serve with a single Runner.

2. Fast functions don't require many files.

Just as minimizing the amount of code in a function will improve function load times, the less files and libraries a function needs to instantiate, the better it will perform. This is where you may have to rethink how they organize their codebase in terms of file structures, and specifically how much you rely on existing libraries to implement the application logic.

While libraries traditionally have been seen as a way to save time coding, many developers have become used to turning to them when they need to implement specific functionality. With functions, this can be problematic. Libraries can quickly increase the size of functions resulting in the aforementioned performance issues.

Considering that individual functions should have a single responsibility, you should be thoughtful about using 3rd party libraries for simple tasks and consider if it would be cleaner to code the functionality yourself.

Wrapping up

Developing fast, minimalist functions with a single responsibility is the strategy that you should undertake for success with faastRuby. To sum up, here are 2 concepts you should to have in mind when designing your functions:

  • Fast functions are small in overall size and scope.
  • Fast functions don't require many files.

Stay tuned for more best practices and tutorials. If you’re interested in creating your own faastRuby tutorials feel free to reach out to the team.