Live data from Hacker News

How much memory do you need in 2024 to run 1M concurrent tasks?

hez2010.github.io

131–140 of 205 posts

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#131
post #90

Earlier quoted context omitted.

But you wouldn't call a million tasks with `Promise.all` in Node, right? That's just not a thing that one does. Instead, there's usually going to be some queue outside the VM that will leave you with _some_ sort of chunking and otherwise working in smaller, more manageable bits (that might, incidentally, be shaped in ways that the VM can handle in interesting ways). It's definitely true to say that the "idioamatic" w…

> But you wouldn't call a million tasks with `Promise.all` in Node, right? That's just not a thing that one does. But neither would you wait on a waitgroup of size 1 million in Go... right?

You could, and the tasks would run concurrently. Node is single threaded so unless you used one of the I/O calls backed by a thread pool, they would all execute sequentially .

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#133
There's a difference between "running a task that waits for 10 seconds" and "scheduling a wakeup in 10 seconds".

The code for several of the languages that are low-memory usage that do the second while the high memory usage results do the first. For example, on my machine the article's go code uses 2.5GB of memory but the following code uses only 124MB. That difference is in-line with the rust results.

  package main
  
  import (
    "os"
    "strconv"
    "sync"
    "time"
  )
  
  func main() {
    numRoutines, _ := strconv.Atoi(os.Args[1])
    var wg sync.WaitGroup
    for i := 0; i 

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#134
post #78

I write (async) Rust regularly, and I don't understand how the version in the appendix doesn't take 10x1,000,000 seconds to complete. In other words, I'd have expected no concurrency to take place. Am I wrong? UPDATE: From the replies below, it looks like I was right about "no concurrency takes place", but I was wrong about how long it takes, because `tokio::time::sleep()` keeps track of when the future was created,…

> because `tokio::time::sleep()` keeps track of when the future was created, (ie when `sleep()` was called) instead of when the future is first `.await`ed I’m not a Rust programmer but I strongly suspect this updated explanation is erroneous. It’s probably more like this: start time is recorded when the task execution is started. However, the task immediately yields control back to the async loop. Then the async loop…

Someone linked the code in another comment, and the start time is most definitely recorded when the future is created: https://docs.rs/tokio/1.41.1/src/tokio/time/sleep.rs.html#12...

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#135

There's a difference between "running a task that waits for 10 seconds" and "scheduling a wakeup in 10 seconds". The code for several of the languages that are low-memory usage that do the second while the high memory usage results do the first. For example, on my machine the article's go code uses 2.5GB of memory but the following code uses only 124MB. That difference is in-line with the rust results. package main i…

Spawning a periodically waking up Task in .NET (say every 250ms) that performs work like sending out a network request would retain comparable memory usage (in terms of async overhead itself).

Even at 100k tasks the bottleneck is going to be the network stack (sending outgoing 400k RPS takes a lot of CPU and syscall overhead, even with SocketAsyncEngine!).

Doing so in Go would require either spawning Goroutines, or performing scheduling by hand or through some form of aggregation over channel readers. Something that Tasks make immediately available.

The concurrency primitive overhead becomes more important if you want to quickly interleave multiple operations at once. In .NET you simply do not await them at callsite until you need their result later - this post showcases how low the overhead of doing so is.

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#138

Earlier quoted context omitted.

Fair or not, it’s a strange way to count - Go isn’t using that RAM. It’s preallocating it because any real world program will.

Go is absolutely using that ram, it’s not available to other services on the system.

The argument then, is what if we DO load 2K worth [0] of randomized data into each of those 1m goroutines (and equivalents in the other languages), and do some actual processing. Would we still see the equivalent 10x (whatever math works it out to be) memory "bloat"? And what about performance?

We, as devs, have "4" such resources available to us, memory, network, I/O and compute. And it behooves us to not prematurely optimize on just one.

[0] I can see more arguments/discussions now, "2K is too low, it should be 2MB" etc...!

Post reply on HN