Heroku dyno issue, perhaps a configuration issue on my part

Hi,

I asked Heroku support this question:

When I use Performance-M dynos, my app's memory usage never exceeds 1GB, it never even gets close to using 1BG.
When I switch to Standard 2x dyno, my app will exceed 1BG, often. Same code.
Can you explain this to me? It doesn't make sense.

Here is the answer I received:

Hmm, this is kind of hard to say. Your app is a "Swift" app which isn't an officially supported language/buildpack. The buildpack used to build your application isn't maintained by us so we don't have a lot of knowledge about how it works. I'm also unsure how Swift sets memory limits or even if this is possible in Swift. One thing here is that performance-m dynos and standard dynos run on different AWS instance types. As standard dynos are multi-tenant the underlying AWS host is actually much more powerful and has larger memory pools overall than an AWS host for a performance-m dyno (the difference is standard dyno have to share the host with many other dynos, while performance dynos get the host all to themselves). I'm wondering if your app is picking up on this fact and setting defaults based on the host rather than the limits of your dyno.

While I haven't really seen this before with memory limits I do see it fairly often with apps that create threads based on CPU cores. Customers will often ask why on a standard dyno they get 8 threads/workers for their apps but only 2 on performance-m dynos. This is because the AWS hosts for standard dynos have 8 CPU cores while performance-m dynos only have 2.

What happens when you use a performance-l dyno? Do you use much more memory than a performance-m? The host of performance-l dynos is much closer to standard dynos.

I think this is the key point from Heroku

I'm wondering if your app is picking up on this fact and setting defaults based on the host rather than the limits of your dyno.

Is this the case? What can I do about this issue?

I don't think anything in Vapor or the standard Swift server components sets any memory limits of any kind. However, it's highly likely that you create threads in proportion to the number of CPU cores available, as that's the standard Vapor behaviour. You can override that setting by passing an explicit EventLoopGroup yourself to your Application.

Cory is correct, Vapor api are based off the number of CPU cores as an event loop maps to a CPU core (in a simplistic view) and each event loop has it's own buffer, storage, services etc etc