Gunnar Morling

morling.dev · Personal blog · on HN since 2020

Gunnar Morling, a Java and data engineer, writes about performance, code review, distributed systems patterns, and the One Billion Row Challenge.

What HN saysHN links it for the code review pyramid, performance optimization work, and his serverless Lucene search on Lambda with GraalVM, which commenters engage with.
56HN people shared it
13linked it in comments
77stories submitted
2.4Kstory points
3 months agolast shared
2020people per year2026

Most-shared posts

  1. 1
    The Code Review Pyramid
    7 people · 233 points · first shared 2022 · 110 comments on HN
  2. 2
    The One Billion Row Challenge
    6 people · 496 points · first shared 2024 · 350 comments on HN
  3. 3
    Towards Continuous Performance Regression Testing
    6 people · 9 points · first shared 2020 · 1 comments on HN
  4. 4
    Idempotency keys for exactly-once processing
    4 people · 192 points · first shared 2025 · 79 comments on HN
  5. 5
  6. 6
    Building a Durable Execution Engine with SQLite
    3 people · 180 points · first shared 2025 · 54 comments on HN
  7. 7
    What's in a good error message?
    3 people · 118 points · first shared 2022 · 78 comments on HN
  8. 8
    FizzBuzz – SIMD Style
    3 people · 68 points · first shared 2021 · 23 comments on HN
  9. 9
  10. 10
    Tracking Java Native Memory with JDK Flight Recorder
    3 people · 7 points · first shared 2023 · 2 comments on HN
  11. 11
    The Insatiable Postgres Replication Slot
    3 people · 5 points · first shared 2022 · 1 comments on HN
  12. 12
    Lower Java Tail Latencies with ZGC
    3 people · 3 points · first shared 2025 · discussion on HN
  13. 13
    1BRC–The Results Are In
    3 people · 3 points · first shared 2024 · discussion on HN
  14. 14
    Building Class Data Sharing Archives with Apache Maven
    3 people · 1 points · first shared 2020 · discussion on HN
  15. 15
    What If We Could Rebuild Kafka from Scratch?
    2 people · 259 points · first shared 2025 · 220 comments on HN

What HN people wrote when they linked it

gunnarmorling · 2025-11-24
Great to see more love for using Lucene on Lambda via GraalVM native binaries! Explored that same idea few years back for my personal blog [1]. It worked pretty well, but I moved eventually away from Lambda as I wanted to close down my personal AWS account. One thing I always meant to explore was embedding the (in my case small) Lucene index directly into the binary image using Lucene's RAMDirectory via Quarkus' bytecode recording machinery, but I never got to it. [1] https://www.morling.dev/blog/how-i-built-a-serverless-search-for-my-bl…
pron · 2024-09-06
> -XX:+TraceClassLoading -XX:+TraceClassUnloading The best insight into the operation of the JVM is now obtained via a single mechanism, JFR (https://dev.java/learn/jvm/jfr/), the JDK's observability and monitoring engine. It records a whole lot of event types: https://sap.github.io/SapMachine/jfrevents/ See here for examples related to tracking memory: https://www.morling.dev/blog/tracking-java-native-memory-with-jdk-flig…
bil7 · 2022-07-12
haha, I've definitely seen some of those. Comment standards are worth obeying, personally I like the code review pyramid https://www.morling.dev/blog/the-code-review-pyramid/
m-i-l · 2021-09-27
Great writeup. Writing your own search index and crawler from scratch is a big undertaking, but sounds like the sort of thing you might have to do due to the constraints of Lambda. For the search index, the blog you link to (https://www.morling.dev/blog/how-i-built-a-serverless-search-for-my-bl… does use Apache Lucene within Lambda (compiled into a native binary via Quarkus and GraalVM to make startup time viable, although not a distributed index and doesn't need to be because of its relatively small size), and for the crawler, it sounds like you were nearly there with Colly (except for memory issues). On the non-tech side: >"In February 2021 the Australian Greens Party called for a publicly owned search engine to be created and be independent and accountable like the ABC." Which is an interesting idea, given search has become something of a utility.
koliber · 2024-06-04
Implement some none-trivial algorithm and then try to optimize the heck out of it. Focus on the concrete CPU, architecture, cache, and memory in the hardware you have in front of you. Forget portability for a moment. This comes to mind: https://www.morling.dev/blog/one-billion-row-challenge/ Read how others have done it. Here's an example in Java that goes relatively low-level to squeeze out performance: https://questdb.io/blog/billion-row-challenge-step-by-step/
matthews2 · 2024-03-01
I haven't had chance to use it properly yet, but I think JfrUnit[0][1] is a good option here to test non-functional behaviour like memory usage and garbage collection. [0]: https://github.com/moditect/jfrunit [1]: https://www.morling.dev/blog/towards-continuous-performance-regression…
sampo · 2024-02-26
I found an online version https://icu4c-demos.unicode.org/icu-bin/collation.html but there you first have to select the language from the drop-down menu. So in general, you would first need to know the country where your weather station was located, before you can correctly collate its name. I don't believe the fastest entries are doing all this(?) Edit: In the examples [1], the guy writes a Polish city using its English name "Cracow". So you can't choose the alphabetical ordering based on the geographical location of the weather station, but you need to somehow detect in which language its name is written in, in the data. [1] https://www.morling.dev/blog/one-billion-row-challenge/ Edit2: I guess you could declare that either the "Default Unicode Collation Element Table (DUCET)", or perhaps the American English "en-US-u-va-posix" locale is the correct way to alphabetize.
marginalia_nu · 2023-12-27
Yes[1], but you need a relatively new version of JFR and you also need to enable a few flags to get much value out of it. [1] https://www.morling.dev/blog/tracking-java-native-memory-with-jdk-flig…
hedora · 2026-08-14
Does it provide hard latency bounds like Azul does (did?), and are they lower than disk/network latencies on modern hardware? I moved to c++/rust years ago because those languages do, and tens of milliseconds matter for network services. At the time Java could pause for 10’s of seconds, which was 1000x worse than waiting for a spinning disk to seek. These days, disks are 100s micros to single digit millis, so I guess if Java GC is finally working 30 years after they “fixed” its performance problems, then I’d want to be able to tune ZGC to not pause the app for more than ~ 500us, max. This article is from last year, but suggests they’re still off by an order of magnitude: https://www.morling.dev/blog/lower-java-tail-latencies-with-zgc/ Also, that’s measuring a 30 second window. If you hammer a 100GB-1TB heap in steady state with small allocations for, say, a month at 100% CPU, does it eventually do the typical Java thing, where a major compaction takes the process down for seconds or even minutes, or does it just slow down application requests so it can keep up with load?
tang8330 · 2023-07-24
Thanks for the comment! Your comment regarding DDL is interesting. Today, this is what happens: 1/ Column doesn't exist in the destination, we'll create it based on our typing inference from the data type (important: not the data value). 2/ Certain tools will handle automatic column data type conversion if a change like this was detected at the source. We do not do this. We will simply hard fail and cause head-of-line blocking reasons being: this is anti-pattern and should be rare, in which case - it's okay to cause an err and require manual intervention for this breaking change. 3/ If the column has been dropped from the source, you as the end user can decide whether this column should be also dropped in the destination, or not. The default is not to drop it. ^ We hear more customers explicitly don't want columns to be dropped because it could cause downstream errors, such as other views / tables not compiling due to referencing a non-existent column. We haven't heard much from folks that don't even want columns to be added. If there is a need, we can definitely add that as a config option to provide maximum configurability. > Finally, the biggest issue with CDC always ends up being the seed loads, recoveries and the incremental snapshot strategies. Yep totally. On the recovery bit, this is exactly why we are leveraging Kafka. If there are any particular issues, we simply don't commit the offset and cause head-of-line blocking. On the incremental snapshot and…
mschuster91 · 2021-12-16
If you're doing user-supplied CSVs, definitely... but if you are ingesting CSVs from a known source with known format (<insert audible sigh here>) it can definitely make sense to use a high-speed optimized ingester. One might wonder if it might be worth the time to look into optimising the runtimes of various languages. I took a look, all operate on naive byte-by-byte scanning, and all sans PHP are written in the respective language which means any form of SIMD optimization is right off the table (okay, maybe something could be done in Java, but it seems incredibly complex, see https://www.morling.dev/blog/fizzbuzz-simd-style/): - PHP isn't optimized anywhere, but at least it's C: https://github.com/php/php-src/blob/1c0e613cf1a24cdc159861e4406abfcee7… - Python's C implementation is the same: https://github.com/python/cpython/blob/main/Modules/_csv.c - Java doesn't have a "standard" way at all (https://www.baeldung.com/java-csv-file-array), and OpenCSV seems the usual object-oriented hell (https://sourceforge.net/p/opencsv/source/ci/master/tree/src/main/java/… - Ruby's CSV is native Ruby: https://github.com/ruby/ruby/blob/bd65757f394255ceeb2c958e87f862139dd3…
pjmlp · 2021-10-09
Much better, because you still do have the JIT data, it is similar to having done a couple of GraalVM runs gathering profile data. Here is an overview of using it with Maven https://www.morling.dev/blog/building-class-data-sharing-archives-with… And here is the documentation for the JIT/AOT and JIT server preview for J9, https://www.eclipse.org/openj9/docs. By the way, this is also the way that ART evolved after the short lived AOT attempt. Nowadays a modern version of ART will have a tiered execution of fast startup interpreter (when no native code is available), a JIT with PGO data gathering, AOT compilation from only the parts that matter when the device is idle, upload of PGO profiles into the store so that every device of similar class doesn't start from zero when an APK gets installed. If the PGO dataset changes, then it backs into JIT again, and recompiles the native code again on idle.
ignoramous · 2021-09-27
Neat! > Incidentally searching around for prior art I found this blog post https://www.morling.dev/blog/how-i-built-a-serverless-search-for-my-bl… about building something similar using lucene, but without storing the content and only on a single lambda. See also: Sqlite FTS (no server): https://news.ycombinator.com/item?id=27016630 EdgeSearch (Workers): https://github.com/wilsonzlin/edgesearch EdgeSql (Workers): https://github.com/lspgn/edge-sql InfiniCache (Lambda): https://news.ycombinator.com/item?id=25788893 quickwit (Lambda): https://news.ycombinator.com/item?id=27074481 > I had been working on a bloom filter based index based on the ideas of bitfunnel which was developed by Bob Goodwin, Michael Hopcroft, Dan Luu, Alex Clemmer, Mihaela Curmei, Sameh Elnikety and Yuxiong He and used in Microsoft Bing https://danluu.com/bitfunnel-sigir.pdf. Reminds me of wavelet trees: https://alexbowe.com/succinct-debruijn-graphs/ https://alexbowe.com/wavelet-trees/

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close