Skip to content

Weird behavior under "high traffic/concurrency" #134

@did

Description

@did

Hi all 👋,

A bit of context first, I'm a Ruby dev (so Crystal noob here) and I decided to use Kemal to implement our ping service (used by our mobile app to display a maintenance view). It's called by the mobile apps every 30s.
Our first version was not using Redis at all and our Kemal server was serving up to 1000req/s flawlessly.

Lately, we decided to use Redis to control our Ping service. Our endpoint is super simple:

redis = Redis::PooledClient.new(url: ENV.fetch("REDIS_URL") { nil })

get "/ping" do |env|
  env.response.content_type = "application/json"
  redis.get("maintenance_started_at") ? hibernating_state : state
end

Kemal.run

And things started to get super weird randomly. We noticed that the Kemal server was not responding at all and we got errors such as accept: Too many open files (Socket::Error) and No free connection....

It took me a while to reproduce the issue locally.
If the number of concurrent of requests is not too high (but higher than the pool size), the Redis pooler displays the No free connection error (but not always) and at some point, the Kemal server freezes.
When the number of concurrent requests is way too high, the Kemal app quickly freezes completely, only displaying the logs of the first 6 requests (related to the pool size).
My guess (not confirmed yet) is that the Kemal app keeps (silently) accepting the requests and at some point, the unix system raises the Too many open files exception.

Just to make things clear here, if I disable the call to Redis, I don't have any trouble running my benchmark.

So for now, we found the right spot regarding the pool size and the traffic. Obviously, when we'll receive an unexpected peak of traffic, our ping service will crash for sure...
And this will be a shame to re-implement it in pure Ruby (Sinatra) since under normal circonstances, Kemal + Redis is super fast (average: 150µs of my laptop).

Thanks for your help and your awesome work !!!!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions