00:00:14.000
hi everyone I came here today to you
00:00:16.640
from a place far far
00:00:18.800
away it's called gayang and I literally
00:00:21.840
had to travel through half of the
00:00:23.400
country 30 minutes by taxi because of
00:00:25.920
the traffic and I came here to tell you
00:00:29.759
that your API is too slow and I want to
00:00:34.640
give you this one weird trick that will
00:00:37.960
change everything and make your API
00:00:39.960
super
00:00:41.039
fast careful this is the trick your API
00:00:44.840
is already fast enough now this might
00:00:48.440
sound like a joke but I really mean it I
00:00:52.480
feel that as developers we're very often
00:00:55.840
so uh so careful about speed of our
00:00:59.440
application
00:01:00.680
that we miss the fact that out there in
00:01:04.600
the world there our users who do not
00:01:07.200
really care about it so much I mean
00:01:09.799
there are people who open the Bloomberg
00:01:12.080
or Forbes page that takes like 20
00:01:14.479
megabytes and a minute or more to load
00:01:17.360
and they still read the articles there
00:01:19.000
right so if your API renders some result
00:01:22.360
within 300 milliseconds like come on
00:01:25.079
it's not even a second and people wait
00:01:26.799
minutes to load to load websites so this
00:01:30.320
is my real message to you that your API
00:01:32.399
is probably already fast enough but who
00:01:34.759
would accept a presentation with such
00:01:36.240
thatle you know I needed to work on
00:01:38.720
marketing my name is gregorek I work for
00:01:41.640
a company called cigo where we're
00:01:43.240
building a hotel booking platform I'm
00:01:45.560
responsible for building API that powers
00:01:48.200
some websites and Powers mobile
00:01:50.360
application before I spent quite some
00:01:52.840
time working for company called fiber
00:01:55.719
where we had also a web API that was
00:01:58.719
built in Ruby and we scaled it up to
00:02:01.200
around half a million requests per
00:02:03.000
minute so when I think about speeding up
00:02:06.119
apis I always ask myself if speed is a
00:02:10.959
feature and if not then if lack of speed
00:02:16.200
is a
00:02:17.560
bug so you might thinking that one
00:02:21.440
excludes another but in my opinion it's
00:02:25.599
the the truth is somewhere in the middle
00:02:27.680
so depending on your product depending
00:02:30.080
on how you promote your application
00:02:32.480
speed might be a feature and if your
00:02:36.160
application is extremely slow it might
00:02:37.920
be considered a bug if you work for a
00:02:40.519
clients that deliver you the functional
00:02:42.640
and nonfunctional requirements often in
00:02:45.239
the letter ones you will see that the
00:02:48.519
application must respond within certain
00:02:50.800
amount of time and then of course if
00:02:52.920
your application is slower then it's a
00:02:54.920
bug right it doesn't fulfill the
00:02:56.959
requirement that you got from your
00:02:58.319
client
00:03:00.400
and let's consider two different
00:03:02.720
products here first is GitHub I use
00:03:05.720
GitHub API on daily basis and it's fast
00:03:10.040
and even if it was way slower like four
00:03:12.879
or five times slower I would still be
00:03:15.000
using GitHub because the speed is not
00:03:17.760
something that made me choose that
00:03:20.560
product over the competitors GitHub
00:03:22.879
doesn't say hey choose us over over
00:03:25.200
other applications because we are fast
00:03:27.400
no their features the stuff that they
00:03:29.840
deliver uh is something else is there
00:03:32.959
there are different qualities of their
00:03:34.439
product that may me choose them over
00:03:36.640
over other applications on the other
00:03:39.000
hand we've got algolia which is a search
00:03:43.120
as a service they've got API that takes
00:03:45.959
your data and returns results uh as you
00:03:49.159
type we use it for example for uh
00:03:51.480
autocomplete for the destinations so as
00:03:54.239
soon as I type n it shows me New York
00:03:57.040
New Delhi and other cities on my website
00:03:59.799
and algolia promotes themselves as an
00:04:02.720
application that delivers results
00:04:04.599
instantly so if their API was twice
00:04:07.760
slower I would probably choose another
00:04:10.239
application that that offers the same
00:04:12.560
functionality but is faster so whenever
00:04:15.519
you think about speed of your API the
00:04:17.680
speed of your web application you need
00:04:19.759
to think what is the strength of my
00:04:21.919
product am I more like agolia do I
00:04:24.840
promote the speed of my application and
00:04:27.280
if yes then you should definitely focus
00:04:29.440
on on delivering results as quickly as
00:04:32.280
possible but if there are more strengths
00:04:34.479
there are other strengths of your
00:04:35.560
application and speed is not something
00:04:38.160
that you want to promote to your users
00:04:40.400
then then maybe you should focus on
00:04:42.280
bunch of other things now let's assume
00:04:45.039
that you really have a problem with the
00:04:47.160
speed and that your users complain your
00:04:50.000
boss hates you nobody's using your
00:04:52.320
product because it's so slow so then if
00:04:54.759
you have a web application there's many
00:04:57.160
many topics that you uh that you should
00:05:00.120
think about there's many layers of
00:05:02.520
optimizing web application very often
00:05:05.280
these are totally independent layers and
00:05:07.440
this is such a broad topic that today
00:05:09.639
instead of talking about everything I
00:05:11.560
will just focus about optimizing API so
00:05:14.720
we'll not be talking about JavaScript
00:05:16.400
static content Etc just the stuff that
00:05:19.240
relates to your AP that is related to
00:05:21.960
rendering Json or or XML by your by your
00:05:25.759
web
00:05:28.199
server whenever user uses the device to
00:05:32.160
make a request to your application this
00:05:35.319
request goes a long long way okay maybe
00:05:38.639
not always if you reach a certain
00:05:40.840
website that is hosted here in Singapore
00:05:42.639
this way will be just a few kilometers
00:05:44.440
right but if you for example pin GitHub
00:05:47.560
that has a server in United States then
00:05:49.639
it's a couple of thousand kilometers
00:05:51.560
that the requests must go there and back
00:05:54.800
and if we were able to achieve the full
00:05:58.199
speed of light we with our requests and
00:06:01.039
and packages then this request within
00:06:04.880
one second would be able to go around
00:06:07.039
the a like seven or eight times but of
00:06:10.240
course we are not able to do that first
00:06:12.880
because we do not live in a vacuum so
00:06:15.080
the speed of light the speed of internet
00:06:16.960
is way slower and the second thing is
00:06:19.880
that we can't directly hit the server
00:06:22.800
somewhere in the other part of the world
00:06:24.680
we have to go through many many devices
00:06:27.039
that slow down this request until we
00:06:29.759
reach the server so whenever you think
00:06:34.639
about speeding up your application
00:06:37.120
speeding up your web API you need to
00:06:39.520
think where are my users because if your
00:06:43.000
server if your database is in Singapore
00:06:45.199
and your users are right close from here
00:06:48.000
in Jakarta then the latency will be
00:06:50.599
around 10 to 20 milliseconds but if you
00:06:53.919
go further to Vietnam this will go up to
00:06:56.639
100 New York 260 milliseconds just for a
00:07:01.440
pink just for a small tiny package to
00:07:04.599
hit the server in New York and go back
00:07:06.919
is 200 milliseconds so even if your API
00:07:10.000
if your application will render results
00:07:12.560
within 10 milliseconds user will have to
00:07:14.800
wait way way more uh until until we'll
00:07:18.759
see the
00:07:19.879
result then if you have for example uh
00:07:23.840
customers in Shanghai in China this gets
00:07:26.080
even worse because of their internet
00:07:28.400
infrastructure and the great firewall
00:07:30.160
that slows down all the traffic uh going
00:07:33.599
out of the country and coming uh coming
00:07:36.440
from another countries so the first
00:07:39.720
thing that you should do if you have
00:07:42.160
users out of your country if you have
00:07:44.520
users far away is to put your
00:07:46.680
application behind the CDN
00:07:48.680
infrastructure initially the CDN were
00:07:52.199
designed and are still considered a
00:07:55.520
solution to serve static content but
00:07:57.960
this is not the only case where the
00:07:59.599
useful so CDN is not only the server
00:08:02.720
that is closer to your user that will
00:08:04.440
store your Javascript file and render it
00:08:06.560
faster cdns actually have a powerful big
00:08:10.159
infrastructure that will allow you to
00:08:13.199
that will help you to serve even Dynamic
00:08:15.520
content faster for example when user
00:08:19.440
makes a request and this request instead
00:08:21.840
of trying to reach your server goes
00:08:24.560
first to the C the closest CDN endpoint
00:08:28.360
then the traffic between one endpoint of
00:08:30.560
that CDN and another endpoint that is
00:08:32.880
closest to your server will be way
00:08:34.919
faster than if it go through normal
00:08:37.360
route that's because the routes between
00:08:39.959
the end points of that of that
00:08:42.240
infrastructure are are improved are
00:08:45.120
optimized what's more certain CDM
00:08:48.080
providers uh work on special protocols
00:08:51.880
to move the data between their endpoints
00:08:54.399
so sometimes they make just a plain HTTP
00:08:57.440
request between one endpoint and another
00:08:59.480
but certain companies uh work on binary
00:09:02.120
protocols that that allow to this
00:09:04.920
requests to go way way
00:09:06.920
faster another thing that will make it
00:09:10.760
uh that allows to take advantage the CDN
00:09:13.880
is http2 so this is a new protocol uh
00:09:17.560
like new version of the protocol that we
00:09:19.160
already know and while we can't fully
00:09:22.360
take advantage of what http2 offers us
00:09:25.800
because of the limitations of the
00:09:27.760
software that we use uh the the user the
00:09:31.000
user's browser probably uh allows the
00:09:33.839
usage of http2 and the CDN
00:09:36.560
infrastructure also allows it so the
00:09:39.000
traffic between the user's device and
00:09:41.480
the last end point of CDN the one last
00:09:44.480
step between your server will be will be
00:09:46.880
going through hp2 so it will allow uh it
00:09:50.519
will allow uh users to to get that
00:09:53.760
faster now the next thing after putting
00:09:57.519
your application behind CDN
00:10:00.320
is thinking about where your servers are
00:10:04.040
because even if you have CDN but your
00:10:06.600
server is in Singapore and your users
00:10:08.560
are let's say in Saudi Arabia this is
00:10:10.760
quite a distance to go through so you
00:10:13.760
might consider instead of having one
00:10:15.800
server and one database using multiple
00:10:19.040
copies all over the world this is quite
00:10:21.519
a trick tricky topic because you need to
00:10:24.440
decide if your application is read heavy
00:10:26.720
or is it right heavy if your application
00:10:29.760
uh if you mostly are reading from
00:10:31.360
database then it's quite easy because
00:10:33.320
you have you can have multiple read only
00:10:35.760
replicas of your database spread all all
00:10:38.480
around the world however if your
00:10:40.920
application is Right heavy then you need
00:10:42.839
to somehow synchronize these databases
00:10:44.959
and then you're going to quite a rocky
00:10:47.440
area where you may have issues with
00:10:49.880
synchronization of data anyway if your
00:10:53.040
application is read heavy then you
00:10:55.399
should certainly consider putting your
00:10:58.279
application servers and a copy of
00:11:00.160
databases in various endpoints that will
00:11:02.480
be closer to
00:11:05.240
user the second
00:11:07.320
step after reaching your server is
00:11:10.279
obviously waiting for the result it
00:11:13.440
boils down to speeding up your Ruby
00:11:16.480
application and there's many
00:11:18.480
presentations there's many books about
00:11:21.880
how to speed up your Ruby application
00:11:24.320
how to speed up your Ruby code and the
00:11:27.560
very very first rule that I have here is
00:11:30.720
not to be a
00:11:31.920
smartass I used to be a smartass and it
00:11:36.079
costed me a lot of time because whenever
00:11:38.760
my application was slow I was like oh
00:11:40.920
yes sure we sure we should cash it and
00:11:43.800
of course sometimes it helped maybe in
00:11:46.000
50% of examples but in the other half I
00:11:50.320
cached the the content and I deployed it
00:11:53.120
to production and I saw maybe 3% of
00:11:55.880
improvement and obviously my boss wasn't
00:11:58.760
happy when after a couple of days of
00:12:00.360
work he so 3% of improvement that's not
00:12:02.360
what you expect so the first thing to do
00:12:06.760
whenever you want to speed up something
00:12:08.680
is to determine what is slow you
00:12:11.040
shouldn't focus on the part that the
00:12:13.120
parts that are already fast because well
00:12:15.800
they're already fast just focus on the
00:12:17.800
slowest part of your
00:12:19.399
application so to measure the
00:12:21.720
performance of your application you can
00:12:23.760
use uh many tools the gems that I'm
00:12:27.040
wrote here are Ruby Prof and Rak Mini
00:12:29.199
profiler both of them will allow you to
00:12:31.920
see which exact line which exact method
00:12:35.440
takes more time than others or which
00:12:37.959
method is called many many times so that
00:12:40.760
you can you can notice that it takes too
00:12:43.560
much time it's called too many times it
00:12:45.480
becomes a problem so the problem might
00:12:48.079
be database and in some cases will be
00:12:51.000
but it's not always uh it's not always
00:12:54.160
true whenever you measure your
00:12:56.680
application you should do it in
00:12:58.480
production mode
00:12:59.800
this is obvious but sometimes I see
00:13:02.079
people forgetting about it and they see
00:13:04.279
that oh my application spends like 90%
00:13:06.959
of time on reloading classes or
00:13:09.040
compiling assets how does it happen well
00:13:11.560
of course in production mode it will not
00:13:13.279
happen it will happen only when you
00:13:15.279
start your application so you should
00:13:17.440
always test it in production mode and
00:13:19.800
for that I suggest something called
00:13:21.320
pre-production or beta stage this is
00:13:23.800
basically copy of your production
00:13:26.120
environment uh that is not available to
00:13:28.920
you users that uses these gems and
00:13:32.440
preferably if it's possible it should
00:13:34.639
use read only replica of your of your
00:13:36.680
production database because well the
00:13:39.079
time that your application spends on
00:13:40.880
loading 10 users that you have in your
00:13:42.600
local database and a couple of thousands
00:13:45.720
users that you have in production
00:13:47.000
database will be definitely very
00:13:48.839
different one of these two gems a rack
00:13:51.399
mini profiler is actually meant also to
00:13:53.639
be used in in the real production
00:13:56.160
environment but nevertheless I recommend
00:13:58.480
you to use this pre-production stage
00:14:01.360
except for these two gems you've got a
00:14:03.279
bunch of external tools uh both New
00:14:05.680
Relic and Skylight are commercial
00:14:08.519
products that have some free plans so
00:14:11.120
you can use them and what they do is
00:14:13.600
that you install a gem that will that
00:14:16.720
will analyze your running application
00:14:18.880
will send this information to their
00:14:20.199
servers and then you've got nice web
00:14:21.839
applications to that will allow you to
00:14:24.560
learn something about your application
00:14:27.639
and then it does not work uh only on a
00:14:30.839
single request but obviously uh all over
00:14:33.800
the time that your application is
00:14:35.079
running so thanks to that you can see
00:14:38.160
not only how much time your application
00:14:40.560
spends on certain p uh on certain part
00:14:43.240
of code in a single request but for all
00:14:45.920
the
00:14:46.560
users and the nice thing about the about
00:14:49.320
these applications is that they allow
00:14:51.639
you to see not only the average time but
00:14:54.639
also the 75th or 95th percentiles
00:14:58.480
average is a terrible measure that
00:15:01.120
people
00:15:02.440
overuse if my brother is a millionaire
00:15:05.360
and I am broke on average we're both
00:15:07.600
very rich but well I do not really
00:15:11.199
experience the same as my brother so if
00:15:13.440
one of your users see the result in 10
00:15:15.519
milliseconds and the other in 500 well
00:15:18.519
the average is 250 milliseconds that's
00:15:20.639
nothing right but one of your users is
00:15:22.639
very happy and the other is frustrated
00:15:25.279
therefore you should use these
00:15:26.480
applications and you should focus on the
00:15:28.240
75th or 95th
00:15:31.279
percentiles now when you measure
00:15:33.720
something first you need to profile
00:15:37.199
which means that you need to determine
00:15:39.639
what is the slowest part of your
00:15:41.000
application and focus on it and then you
00:15:44.000
Benchmark which means that you compare
00:15:46.000
alternative
00:15:47.560
Solutions first profile then Benchmark
00:15:50.959
do not do not Benchmark things that
00:15:53.040
don't matter and uh these two things are
00:15:57.000
not exclusive they are just one after
00:15:59.079
another and that's that's how you should
00:16:01.399
do
00:16:03.360
that now when you measure and when you
00:16:06.040
determine what is the slowest part of
00:16:07.720
your application you should start
00:16:09.759
improving and the first thing that I
00:16:13.360
always do and that I think that people
00:16:17.120
say quite the opposite is to rely on
00:16:19.600
your
00:16:21.160
database whenever someone says that we
00:16:24.160
need to speed up our application we
00:16:26.279
start by thinking about caching because
00:16:28.959
because in many cases the time spent in
00:16:31.720
database is very significant but I
00:16:34.959
believe that we learned to treat
00:16:38.079
database as a big black box that we just
00:16:40.560
throw stuff in and take it out while
00:16:42.759
databases are really powerful systems
00:16:45.720
they have many functions that can
00:16:48.199
aggregate the data they can analyze
00:16:50.279
process the data and instead of just
00:16:52.360
fetching everything we have in database
00:16:54.480
and processing it in our Ruby
00:16:55.839
application we can just use databases
00:17:00.079
I think that the problem is that we are
00:17:02.440
so used to using ORS like SQL or active
00:17:05.160
record these tools teach us to write
00:17:09.240
Ruby syntax and to fetch just simply
00:17:12.360
fetch the data instead of writing cql
00:17:15.720
that allows us to to fully use all the
00:17:19.280
database features so ORS do not offer
00:17:21.959
you everything that the database offers
00:17:23.799
you just because ORS usually try to
00:17:26.480
cover uh a try to support as many
00:17:30.080
databases as possible so very often they
00:17:32.600
only support these functions that are
00:17:34.559
common for multiple
00:17:36.080
databases a couple of weeks ago here in
00:17:38.679
Singapore on the Ruby Meetup we had a
00:17:41.080
developer talking about the cubes
00:17:42.679
functionality in postgress database this
00:17:45.120
is not supported by anym but this is
00:17:47.520
functionality that allows you to
00:17:48.880
aggregate your data in database over
00:17:50.760
multiple Dimensions at the same time and
00:17:53.880
this is something new this is something
00:17:55.440
that probably we will not see supported
00:17:57.520
in any orms but if you learn you if you
00:18:00.559
learn some SQL then you can take
00:18:02.720
advantage of it already right
00:18:04.960
now when I was at University I had like
00:18:08.080
two semesters of the Oracle database
00:18:11.159
course and after that after these two
00:18:13.600
semesters my professor told me that hey
00:18:15.840
so now you know the basics so now you
00:18:17.840
can go and learn yourself something more
00:18:20.559
of course I never learned more of Oracle
00:18:22.720
databases database later but I learned
00:18:25.799
during this time that I can write the
00:18:28.000
whole application
00:18:29.520
using just Oracle so it's not only a
00:18:32.400
tool to store data but databases are
00:18:35.640
really powerful applications it's really
00:18:37.600
powerful software and you should not be
00:18:40.760
afraid of that you should just learn
00:18:42.360
some SQL and you should trust and rely
00:18:44.840
on your
00:18:47.039
database of course at some point you
00:18:49.159
will be forced or you will want to use
00:18:50.960
the cache and then you need to consider
00:18:54.919
where to put that cache it might be a
00:18:57.240
weird question but
00:18:59.600
you might keep it on a separate machine
00:19:01.679
so you might store some information in
00:19:03.480
red on a separate server in the same
00:19:05.919
network which will be fast then you
00:19:08.520
might have red on the same machine and
00:19:10.919
obviously it will be faster because
00:19:12.400
we're removing this period of time that
00:19:14.960
is needed for transferring data from one
00:19:17.400
machine to the other and the third
00:19:19.960
option is to store uh information in
00:19:23.080
your application memory of course if I
00:19:25.840
say that the application memory is the
00:19:27.480
fastest why not or everything there
00:19:29.679
right well each piece of memory that you
00:19:33.640
use for the cache is the memory that you
00:19:36.240
cannot use for your server to be running
00:19:38.919
and we all know that Ruby applications
00:19:41.039
are pretty hungry when it comes to the
00:19:42.799
memory right the simple race application
00:19:45.559
run on unicorn can consume around 4 to
00:19:49.960
500 megabytes so you need to consider
00:19:54.360
you need to consider this tradeoff like
00:19:56.559
do I want to spend my memory
00:19:59.159
on another service or another server
00:20:01.600
worker or on a cache what I usually do
00:20:05.280
is combine the third and first approach
00:20:08.280
so whatever data is accessed almost
00:20:12.400
every single request and doesn't change
00:20:14.320
often I try to keep in application
00:20:16.200
memory but whatever doesn't fall in that
00:20:19.080
category I move to separate machine on
00:20:21.400
red CU you need to remember that even
00:20:25.000
though everyone uh keeps repeating that
00:20:27.760
memory is cheap
00:20:29.200
cheap doesn't mean that it's
00:20:31.760
free the next thing about cash is using
00:20:34.520
multi-layered cach so whenever user
00:20:37.720
reaches your server you try to increase
00:20:40.000
your cash hit ratio so you want your
00:20:42.280
user to take advantage of this cach and
00:20:46.039
sometimes different pieces of
00:20:48.000
information are a bit different for each
00:20:50.159
user for example at caligo we store a
00:20:53.640
static information about hotels so some
00:20:56.600
of this information is the same for each
00:20:58.280
user like the hotel rating or how good
00:21:01.000
is the Wi-Fi or how tasty was the
00:21:03.320
breakfast in terms of in terms of some
00:21:05.320
scale from 1 to 5 this is the same for
00:21:07.720
each user but then we've got description
00:21:09.799
of the hotel which is in text and will
00:21:12.200
be different for user in Russia and user
00:21:14.559
in Singapore just because it will be
00:21:16.039
written in different language for that
00:21:18.200
case we use this Russ doll or
00:21:20.240
multi-layered Cache where all the users
00:21:23.279
will take advantage of this common cache
00:21:26.039
the information that is common for all
00:21:27.559
of them and they will not take advantage
00:21:30.960
of the other part because it will be in
00:21:33.360
the different
00:21:36.880
languages the next part is what I really
00:21:39.720
hate to say because I'm a huge fan of
00:21:43.039
functional programming I use erlang and
00:21:45.480
elixir on daily basis I really enjoyed
00:21:48.080
writing husk and prolog at
00:21:50.000
University and all these languages are
00:21:52.240
functional and do not allow you to
00:21:55.480
mutate data and Ruby allows you to do
00:21:58.240
that
00:22:00.080
and you should do it pretty often that's
00:22:02.960
because Ruby even though Ruby allows you
00:22:05.279
to write functional code it's not really
00:22:08.320
optimized for that so imagine that you
00:22:10.360
have a hash with thousand elements and
00:22:12.600
now you want to add one element to that
00:22:14.559
hash if you do uh hash do merge and then
00:22:18.440
put that one other element what will
00:22:20.520
happen is that Ruby will copy the whole
00:22:23.520
element the whole thousands keys to
00:22:26.720
another structure to another part uh
00:22:28.640
address in the memory and then add this
00:22:30.679
one piece there which means that it is
00:22:33.360
very expensive operation if you work on
00:22:35.360
big data structures purely functional
00:22:37.919
languages languages that do not allow
00:22:39.679
you to uh to mutate your data they will
00:22:42.720
just create a new piece uh with one
00:22:45.480
element and a reference to that old
00:22:47.919
address in memory that's because that
00:22:49.919
address that data is immutable so it
00:22:52.240
will never
00:22:53.400
change and using merge with exclamation
00:22:56.400
mark instead of merge can be T fast T
00:23:00.520
time faster or if if your data is really
00:23:03.039
huge then can be even hundreds times
00:23:04.760
faster so I really hate to say that but
00:23:07.559
when you need you should mutate your
00:23:10.240
data it is risky and you should be
00:23:12.120
careful about it but in in many cases it
00:23:15.880
will help you to save off a lot of
00:23:18.559
time now this is pretty cheap technique
00:23:21.320
but people often forget about it
00:23:23.679
upgrading your libraries even between
00:23:26.640
some minor or tiny releases can have a
00:23:29.400
big impact of your performance that's
00:23:32.240
because when developers release a new
00:23:33.840
version of Library they increase their
00:23:36.200
minor or major version Whenever there is
00:23:38.320
some new big feature or something that
00:23:40.120
breaks the compatibility but between the
00:23:42.440
big features there is a lot of work
00:23:44.720
happening in open source just on this
00:23:47.039
level of the micro optimizations and a
00:23:49.159
bunch of them can sum up to pretty big
00:23:51.480
difference for example we sometimes
00:23:53.840
sometime ago we used a ro Library which
00:23:57.320
is a representative Library and moving
00:23:59.440
from
00:24:00.279
one minor version to
00:24:02.840
another reduced our response time by
00:24:05.600
about 10 to 20% just because we upgraded
00:24:09.360
this gem we didn't have to do anything
00:24:13.600
else sometimes it will happen that you
00:24:16.080
cannot uh use some Library anymore and
00:24:19.679
then you should obviously consider
00:24:21.600
replacing it in some cases it is
00:24:24.200
extremely cheap for example if you have
00:24:26.840
problem with Json parsing you can
00:24:28.840
replace the Json gem with these two gems
00:24:31.559
here OJ stands for optimize Json and
00:24:34.159
it's a uh Json parcel written in C and
00:24:38.200
the OJ mimic Json Jam will basically
00:24:41.159
allow you to use the same current syntax
00:24:43.399
that use for Json right now with the uh
00:24:46.960
with the new library and it if if you're
00:24:49.720
often passing passing big Json it will
00:24:52.360
make a big big
00:24:55.000
difference now it's get pretty difficult
00:24:58.559
native
00:24:59.559
extensions I wrote maybe one native
00:25:02.039
extension in my life it wasn't
00:25:05.039
easy but you can check some existing
00:25:08.559
native extensions that are written for
00:25:10.200
Ruby some of them are written for C if
00:25:12.159
they are for MRI some are written in
00:25:13.760
Java if the a 4J Ruby it's not that bad
00:25:16.840
it may happen that there is a certain
00:25:18.600
function certain method in your
00:25:20.480
application that is called many many
00:25:22.559
many times and maybe just by moving this
00:25:25.520
one method this one function to a faster
00:25:27.880
language
00:25:28.919
uh you can save a lot of time and maybe
00:25:30.760
it will not be that difficult and if you
00:25:33.159
do not want to use C you can use rust
00:25:35.960
thanks to two uh libraries that that
00:25:39.200
already exist and allow you to write
00:25:40.919
some extensions in
00:25:43.320
Rust the next thing this is quite
00:25:45.600
obvious but often people forget about it
00:25:48.880
is move processing to the background the
00:25:51.600
most obvious example here is sending
00:25:53.320
emails usually you can send email after
00:25:55.640
user gets a response no you do not need
00:25:59.039
to make user waiting until that email is
00:26:01.399
sent especially that if you're using
00:26:03.279
SMTP protocol this will be quite slow
00:26:05.840
but there's many other cases where you
00:26:08.159
can give user a response and you can
00:26:10.840
send a status of a transaction for
00:26:12.760
example when you're processing payment
00:26:14.440
it may take up to a minute so instead of
00:26:16.720
making user wait a minute you just send
00:26:18.679
ID of the transaction and status in
00:26:20.559
progress and then user can hit your uh
00:26:23.440
hit your server again every couple of
00:26:25.320
seconds to check if the transaction was
00:26:27.679
was finished or
00:26:29.200
not when you're really really
00:26:31.960
desperate you might want to extract part
00:26:34.320
of your
00:26:35.360
application and I really mean when
00:26:37.080
you're desperate and I really mean part
00:26:40.039
not ever write rewrite everything in go
00:26:43.440
I often read articles like oh we rewrote
00:26:46.320
our Ruby application in go now we use 10
00:26:48.559
servers instead of 100 and we spent a
00:26:51.919
couple of thousand man hours just for
00:26:54.200
that even though we could afford that
00:26:56.880
servers so you should be really really
00:26:59.559
careful with that one and I think that
00:27:01.799
this is overused and overhyped rewriting
00:27:04.960
application is not a good stuff to do
00:27:07.880
because you're basically spending a lot
00:27:09.360
of time on building the same thing that
00:27:11.159
you've already
00:27:12.600
built there's way more things to talk
00:27:15.080
about that I do not really have time to
00:27:17.679
cover so I will just skip to the third
00:27:20.919
part of the request which is the
00:27:23.600
download of course we do not have many
00:27:26.360
more things left to do
00:27:28.840
the most obvious is to use gzip and to
00:27:31.640
compress your response if you already
00:27:34.159
have your application behind CDN this
00:27:36.640
will also make an impact here and the
00:27:39.520
third thing to consider is that maybe
00:27:41.600
you don't need need you don't need to
00:27:43.760
send all the data that you want to the
00:27:45.640
user maybe big part of this response
00:27:48.039
will be used only in certain cases in 10
00:27:50.399
15% of cases and you should you should
00:27:53.200
move it to another end
00:27:55.159
point so our request come through the
00:27:58.640
user device through the whole world to
00:28:00.559
the server and back to the user device
00:28:03.240
and I would like to write wrap up my
00:28:05.320
presentation just by telling you that
00:28:07.360
you should use CDN infrastructure you
00:28:09.440
should profile and then Benchmark always
00:28:12.200
in this case always focus on the slowest
00:28:14.360
part and rewriting is the last thing to
00:28:17.519
consider Ruby is really fast enough for
00:28:20.000
you catron R and all the other
00:28:22.159
Frameworks are faster in my previous
00:28:24.519
company we scaled the application Ruby
00:28:27.039
application to handle half a million
00:28:28.679
requests per minute before that
00:28:31.000
application will start being extracted
00:28:33.320
to other languages so unless you hit
00:28:35.679
such a big limit then you do you
00:28:38.159
shouldn't really consider rewriting your
00:28:39.880
application you should just focus on the
00:28:42.000
slowest part and gradually improve the
00:28:44.399
speed my name is Gregor vitek this was a
00:28:46.880
presentation about your API which is
00:28:49.519
most probably fast enough thank you very
00:28:51.840
much