The important thing in here is how many requests per second the server can process, which are ~143. Not bad to start with, but let's get our hands dirty. By the end of the reading you will process a bit more than 1000 requests per second, so stick with me.

ActiveModelSerializers

The only thing in here we are going to change is that we will use ActiveModelSerializers to process the json output.

We are still increasing the performance, but it is not good enough, yet.

Metal

ActionController::Metal is the simplest possible controller, providing a valid Rack interface without the additional niceties provided by ActionController::Base.

We will use Metal which should be a good boost:

class Api::V1::UsersController < ActionController::Metal
include AbstractController::Callbacks
include AbstractController::Rendering
include ActionController::Renderers::All
include ActionController::UrlFor
include Rails.application.routes.url_helpers
include ActionController::Serialization
include ActionController::RackDelegation
include ActionController::StrongParameters
def index
render json: User.all
end
end

class Api::V1::UsersController < ActionController::Metal
include AbstractController::Callbacks
include AbstractController::Rendering
include ActionController::Renderers::All
include ActionController::UrlFor
include Rails.application.routes.url_helpers
include ActionController::Serialization
include ActionController::RackDelegation
include ActionController::StrongParameters
include Api
def index
render json: User.all
end
end

And last thing, but the most important one is to actually cache the response for the index action: