Search code examples
node.jsamazon-web-servicesamazon-ecsaws-fargate

Would a higher vCPU benefit a single threaded app for a Fargate task?


If the code running in my ECS Task is strictly single-threaded and doesn't make use of parallelization or multi-threading, is it safe to assume that assigning more than a single 1 vCPU for the task would have no impact on its performance and would be a waste?

Where memory values are the same, running the same single-threaded container with 1024 (1 vCPU) compared to 2048 (2 vCPUs) wouldn't make use of the extra vCPU, right?

How would this work in the context of a Node.js application that doesn't use clustering?


Solution

  • TLDR: 1 vCPU is the suitable configuration for a single-threaded application.


    If the code running in my ECS Task is strictly single-threaded and doesn't make use of parallelization or multi-threading, is it safe to assume that assigning more than a single 1 vCPU for the task would have no impact on its performance and would be a waste?

    Correct.

    In my other answer here, I detail my definition of a vCPU as a virtualized abstraction of a physical CPU core or thread, depending on the instance type and CPU type.

    Regardless of if 1 vCPU is mapped to a core or a thread, a single-threaded application can only ever use one thread at a time & will only benefit from 1 vCPU.

    Provisioning more than 1 vCPU will not provide any performance benefit.


    Where memory values are the same, running the same single-threaded container with 1024 (1 vCPU) compared to 2048 (2 vCPUs) wouldn't make use of the extra vCPU, right?

    'make use' meaning benefit from, or result in performance gain? No.

    'make use' meaning actually used & not idle? Most likely, yes.

    A single-threaded application is guaranteed to run on only one thread at a time, but it is not guaranteed to always run on the same thread. At the discretion of the operating system, it can run on any core that is available but it is impossible for it to run on multiple cores at the same time.


    How would this work in the context of a Node.js application that doesn't use clustering?

    The answer remain the same - with a small caveat.

    Four items makes a Node.js application code run on more than a single CPU thread:

    1. worker threads (node:worker_threads)
    2. clustering (node:cluster)
    3. child processes (node:child_process)
    4. C++ addons

    Without any of the above, your Javascript code - that runs in the event loop - only runs on a single CPU thread and only benefits from 1 vCPU.

    The caveat is that in addition to the event loop, Node.js also has the worker pool i.e. thread pool that does benefit from more threads.

    The threadpool is internally used (1, 2) for these module APIs:

    1. I/O-intensive

      1. DNS: dns.lookup(), dns.lookupService().

      2. File System: All file system APIs except fs.FSWatcher() and those that are explicitly synchronous use libuv's threadpool.

    2. CPU-intensive

      1. Crypto: crypto.pbkdf2(), crypto.scrypt(), crypto.randomBytes(), crypto.randomFill(), crypto.generateKeyPair().

      2. Zlib: All zlib APIs except those that are explicitly synchronous use libuv's threadpool.

    These would benefit from a multi-core system. Nonetheless, the benefits will most likely be minimal, depending on how heavily they are used.

    If there is heavy use of them, it's best to individually benchmark the application with 1 vCPU & then 4 vCPUs (in line with the default threadpool size of 4).