Matt-Hornsby

Matt-Hornsby

Hi all - cross posting this from the elixir-talk mailing list. I could use some help. I am currently evaluating Elixir and Phoenix for a performance-critical application for a Fortune 500 company. This could be another great case study for Elixir and Phoenix if I can show that it can meet our needs. Initial performance testing looked phenomenal, but I am running into some performance concerns that will force me to abandon this tech stack entirely if I cannot make the case.

The setup: an out-of-the box phoenix app using mix phoenix.new. No ecto. Returning a static json response. Basically a hello-world app.

The hardware:

  • Macbook Pro, 16gb, 8 core, 2.5ghz, running elixir/phoenix natively, and also using docker container
  • Amazon EC2 T2.Medium running Elixir Docker image

The tests: used ab, wrk, siege, artillery, curl with a variety of configurations. Up to 100 concurrent connections. Not super scientific, i know… but

No matter what I try, Phoenix logs out impressive numbers to stdout - generally on the order of 150-300 microseconds. However, none of the load testing tooling agrees. No matter the hardware or load test configuration, I see around 20-40 ms response times. The goal for the services that I am designing is 20ms and several thousand requests per second. The load tests that @chrismccord and others have published suggest that I should be able to expect 3ms or less when running localhost, but i’m not seeing anything close to that.

Would anyone be willing to work with me to look at some options here? I’d be incredibly grateful. Don’t make me go back to Java, please :slight_smile: Is this even possible what I am asking?

Showing Posts 1 to 10

terakilobyte

terakilobyte

I’ve read several times that for performance testing you should run the app in production mode.

MIX_ENV=prod mix compile.protocols
MIX_ENV=prod PORT=4001 elixir -pa _build/prod/consolidated -S mix phoenix.server

This is from the 0.7.2 docs so I’m not sure it’s all still needed, but might be worth a try.

Matt-Hornsby

Matt-Hornsby OP

Thanks for the great suggestion @terakilobyte - I just tried running it in PROD mode:

MIX_ENV=prod mix compile
MIX_ENV=prod mix phoenix.digest
MIX_ENV=prod PORT=4001 mix phoenix.server

./wrk -t8 -c100 -d30S --timeout 2000 http://localhost:4001/api/products

Running 30s test @ http://localhost:4001/api/products
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 29.16ms 32.83ms 365.59ms 94.76%
Req/Sec 494.23 139.45 770.00 76.14%
116284 requests in 30.06s, 71.44MB read
Requests/sec: 3868.18
Transfer/sec: 2.38MB

Still not very good unfortunately :frowning:

Matt-Hornsby

Matt-Hornsby OP

Interestingly, with only 10 concurrent connections:

Running 10s test @ http://localhost:4001/api/products
8 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.18ms 3.91ms 40.59ms 88.15%
Req/Sec 1.12k 249.24 1.78k 68.38%
89005 requests in 10.01s, 54.68MB read
Requests/sec: 8890.15
Transfer/sec: 5.46M

sasajuric

sasajuric

Author of Elixir In Action

There was a similar thread recently. You may find some tips there.

Some low-hanging fruit to improve perf would be:

  1. Raise log level in prod to :warn to suppress logging each request.
  2. If you’re testing a REST endpoint, make sure it goes through the :api pipeline, and not the :browser one.
  3. Build an OTP release and bench against that

Also, check your cpu usage while testing. If all your CPUs are not constantly near 100% then you may have some bottleneck.

thinkpadder1

thinkpadder1

Check this micro benchmark tool released by a member of the community: Benche and BencheeCSV 0.1.0 release - easy and extensible (micro) benchmarking

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

To expand on Sasa’s point, the :browser endpoint by default generates CSRF tokens to be used in forms as a security measure. These can be fairly expensive to generate at least compared to a hello_world JSON endpoint. Definitely make sure you aren’t doing that.

Matt-Hornsby

Matt-Hornsby OP

Thank you for your quick response on this @sasajuric. I looked around in the forums first but didn’t see the other thread. Lots of great information over there to try. Pretty sure I’m piping through :api - here’s my router:

defmodule MarketApi.Router do
  use MarketApi.Web, :router

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/api", MarketApi do
    pipe_through :api
    resources "/products", ProductController, except: [:new, :edit]
  end
end

CPU is pretty well maxed out across all cores when I run the tests.

Thanks @benwilson512 - I’m super green to Phoenix, so I appreciate the tip. I think I am using :api. Is there anything I need to do besides pipe_through :api ?[quote=“thinkpadder1, post:6, topic:832, full:true”]
Check this micro benchmark tool released by a member of the community: Benche and BencheeCSV 0.1.0 release - easy and extensible (micro) benchmarking
[/quote]

I hadn’t seen this before - I’ll give it a whirl. Is it possible with the tool to have it benchmark where Phoenix is spending all its time?

defoemark

defoemark

Try to make a release with exrm, and then start as a service:
rel/your_app/bin/your_app start.

thinkpadder1

thinkpadder1

Also, check out Elixir’s very own Observer tool.

romul

romul

Could you put your test app to Github or smth else? It would help to found a reason.

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 92995 915
New
caslu
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
GES233
I’m posting this in response to Jose’s recent tweet (Cr. link) : People are sleeping on Elixir for a coding harness: Hot-code swappi...
New
marciol
It would be helpful to have a list of companies worldwide that hire engineers without prior experience in Elixir. Often, it can be quite ...
New
durvia
Anyone running long-lived stateful processes on BEAM? We’re building an AI agent runtime and would love to compare notes. We’re a small ...
New
nseaSeb
I’ve just put together a small POC exploring PDF inspection from Elixir/Phoenix: The idea is pretty simple: drag & drop a PDF in a...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews