Hacker Newsnew | past | comments | ask | show | jobs | submit | more devjam's commentslogin

I’m bemused by these sorts of disparaging comments that come from people who seem to have no real world experience running Go applications at scale.

It’s entirely possible to run a server that will handle tens of thousands of req/sec on hardware with comparatively small amounts (by todays standards) of RAM e.g. 512MB


I have written a bunch of tiny Go apps, and agree with you. In general, 64MB is where I set the limit on these things and there are no problems. I have some big applications that literally allocate 1GB at once and they still run OK within 2GB memory limits. (Obviously, you can't do two of these operations at once, though.)


I don't see how you think my comments are "disparaging," this is just code doing what it is programmed to do.

> It’s entirely possible to run a server that will handle tens of thousands of req/sec

Indeed, you can do this. I'm talking about what happens once the Go starts getting memory pressure and the GC starts dominating the CPU. This is what it is designed to do. If your code can prevent that from happening, you are correct then, as it won't be an issue.


I’ve done well over 100k req/s and I’d have to ask former coworkers but I’m pretty sure we were using under 2Gb of ram.


> Go starts getting memory pressure and the GC starts dominating the CPU

That does not happen. You must be thinking of Java 15 years ago.


Prior to GOMEMLIMIT being a thing, people would get themselves into this situation occasionally. Their steady state working set size is something like 2.1GB, but they want to fit into a 4GB container limit, so GOGC=100 led to OOMs occasionally. They would bring GOGC down to 10 or something (why not 90!?), and then they are running GC every time they allocated 10% or 200MB, and then their CPU profiles would show they were burning a lot on GC, because it's pretty easy for an RPC server to generate 200MB of garbage.

GOMEMLIMIT definitely improves things, taking the very blunt instrument GOGC out of people's hands, and does what they actually want instead, which is to prioritize GC only when you're about to run out of memory.

People dislike tunables like this, and rightfully so, but a similar problem exists somewhat insidiously in non-garbage collected languages. Calling malloc() and free() is not a zero-cost operation, and you can certainly waste CPU by calling free() when nothing actually needs the memory you are freeing. GC lets cases like "this is a CLI app, the system has 128GB of RAM, the working set size is 2GB, and it's over in 1 second" basically never do any memory freeing. You allocate as much as you need, GC never runs, and the app exits. That kind of optimization is actually pretty neat. But, for steady state servers that run for an unbounded period of time, it is inevitable that you are going to spend time trying to reuse memory that you no longer need, because the system only has a finite amount of memory. Then the compromises start to balance throughput with efficiency. gc + GOMEMLIMIT is a very nice compromise that is excellent for many applications, but no heuristic is perfect for every possible computer program.


Even Java 17 years ago is ironic, considering the hardware requirements of J2ME, Java Embedded, Blue Ray players, Ricoh and Xerox copiers, Cisco phones, and so forth.


Is it likely that you would run servers "at scale" on a RPi?


A newer rpi is in fact more than enough scale for most websites in existence.


A RPi is more powerfull than most PCs I owned between 1990 until 2002.


Come to think of it, in terms of computing power, the ESP32 is probably more powerful than what you used before 2000.


I always compare it to a Amstrad PC1512, given its memory.

Still even with limitations, there was a ton of stuff we could do in MS-DOS, let alone a more powerful system with dual core and built-in networking.


A huge time-saver for me when adding table-driven test boilerplate in Go has been using gotests[0] to generate the template.

If you use VSCode with the Go extension it's already available there as a command "Go: Generate Unit Tests for Function/Package".

[0] https://github.com/cweill/gotests


I just ask ChatGPT to do it. Actually just today I asked it to format an existing set of tests into table-driven format. Worked great.


Chips. Although very occasionally you will hear crisps.

Often "hot chips" (french fries), as distinct from a "packet of chips" (crisps), but it's contextual: e.g. a Schnitzel with salad and chips, would always be with hot chips.


> Published 16 January 2023 3:59pm


I always put the publication date as 6 months prior on my blogs - Consider it a form of time travel.


It's obvious, you need to run:

    $ man find
before you can do that.


I'm using uBlacklist [1].

[1] https://iorate.github.io/ublacklist/docs


> It didn't become dominant by being a bad browser...

IE6: hold my beer


IE6 was by far the best browser at the time it became dominant

It just stagnated and became the worst browser over time


I had the same thought; this is in my shell RC:

    alias weather='f() { curl wttr.in/${1:-sydney} };f'


Interesting -- why do you define an alias that defines and then immediately calls a function instead of just defining `weather` as the function itself?


         echo yourcity | nc graph.no 79
or

         finger yourcity@graph.no


Or the slightly less antagonistic version ;)

    10 PRINT "MARK IS COOL"
    20 GOTO 10


Unless it's time-sensitive/critical, from the point of view of an OSS maintainer why should it matter whether a patch took 3 days to develop, or 3 minutes? As long as the quality and correctness is consistent across those patches, as a maintainer I'd encourage a wider base of developers who are fluent in my codebase, even if their initial PRs took slightly longer.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: