bMalum (@bmalum) profile picture

AWS Senior Solutions Architect - coding Elixir

Germany
Joined November 2010
Photo by bMalum (@bmalum)Photo by bMalum (@bmalum)Photo by bMalum (@bmalum)
Weekend Project: Booted Elixir as PID 1 on Asterinas - 15 MB image - no distro, no shell, no init system - kernel entry to /init in 0.5 s - app serving TCP/TLS at ~4s - runs in 144 MB RAM bmalum.github.io/elixir_unik…
3
419
In programming, "speed" is not so simple to measure. There are a few measures you look at: Concurrency: The number of things your system can handle at once. Throughput: The actual number of requests served per second in real world conditions. Latency: How long it takes for any one request under real world conditions to complete. This includes queueing delay. Queueing Delay: How long a request has to wait at the front door before your system even starts processing it. You typically are playing a balancing act between maximizing throughput and minimizing latency on any single server, while increasing number of servers (capacity) to account for actual load. A system under load does not behave the same as a system with spare capacity. Raw speed doesn't save you under contention, because "just do the thing as fast as it can possibly be done" is just insufficient. Instead, you have to write your code in such a way that any one given thing can "yield" to other things. If you don't, the requests you're working on finish quickly, but once all of your threads/processes are fully utilized, you have no way to handle more load without introducing queueing (which eventually becomes failures/timeouts) on callers. This brings us to queueing delay. When the system is processing all of the data that it can, the callers have to all just sit there and either wait, retry or fail. If your system were able to accept more concurrent work, you can lower this queuing delay under heavy load. If you can't do that, you end up trading away too much of your goodput (requests that actually succeed within their deadline) in exchange for consistently low latency for the operations that you do handle. When building systems at scale, the general guiding light is keeping the queue delay low, and keeping goodput as high as possible. To do this, you accept as much work as the internal system can track (increasing memory usage typically), allowing latency to go up, in order to accept more concurrent traffic internally. You still need backpressure and load shedding, since no scheduler saves you from arrival rates that permanently exceed what you can serve, but within those bounds you keep goodput maximized. For this to actually work, your internal schedulers need to be able to do something called "preemption". This is where any given operation cannot take an entire CPU core for longer than some given period of time, or for some amount of operations. A "preemptive scheduler" balances work fairly across all of the operations that are asking for CPU cycles. (Work stealing, where idle cores pull queued work from busy ones, helps too, but plenty of cooperative runtimes have that. Preemption is the key part.) The BEAM is a powerhouse for this. It preempts processes by counting "reductions," so no process can hog a scheduler. Immutability and share-nothing processes make that preemption cheap and harmless: a process is never paused while holding a lock someone else needs, and every process has its own heap and garbage collector, so there are no global stop-the-world pauses. This allows BEAM applications to achieve maximal goodput, with very low failures due to queue delay, while spreading latency across all work fairly. Without that preemption, you would see a huge spread among the latency of your system. i.e some requests happening practically immediately, while other requests take pathologically large amounts of time to complete. I get that people want programming language not to matter these days, but at a very minimum you cannot escape the limitations of your runtime. The BEAM's runtime is built for operating at scale, and will always be smoked on benchmarks for tight loop operations where there is no resource contention. #ElixirLang
BEAM is not faster than Rust so something is wrong with the Rust code
7
45
5
274
8,292
bMalum retweeted
"In an overload situation, the rust implementation delivers a whopping 1% of messages to all connected clients, and the Elixir implementation delivers 100% of messages to all clients, applying natural backpressure to writes."
I have a branch with various performance improvements to the Elixir version, focused on specifically the websocket side of things. I didn't spend much time on the rest. The load generation code was flawed in overload scenarios because any socket that had an issue just stayed disconnected forever, so I assume no benchmarks were run in this fashion prior. Now those reconnect on disconnect and continue sending traffic (a more realistic scenario). Most relevant finding: In an overload situation, the rust implementation delivers a whopping 1% of messages to all connected clients, and the Elixir implementation delivers 100% of messages to all clients, applying natural backpressure to writes. Speed is cool. Rust is fast. Speed is not even close to the most important thing when building real applications.
1
3
86
6,152
bMalum retweeted
I took a stab at improving the performance of Elixir. I used the PR for Elixir that @ZachSDaniel1 posted and worked some more on it. In the benchmark Elixir is now faster than Rust (ccece30 newest commit) for the Sidebar and Search benchmark.
Last conversion of the Campfire from my token stash goes to JavaScript/Express. As with the others, I'm sure you can find more to optimize. But this gives you a sense of what order of magnitude these options exist within with agent-led development. github.com/basecamp/once-cam…
47
46
17
581
106,815
Every backend I touched needed PDFs. Every time it was a headless browser (page breaks by luck) or LaTeX in a container (slow, errors nobody reads). @typstapp compiles in milliseconds and tells you the line. So I hosted it once and you get 300 pages for free! foliant.dev
40
The Kiro merch shop is now open shop.kiro.dev/ I think my favorite is these ghosty keycaps
5
4
32
3,283
Elixir v1.20 released! Now officially a gradually typed language: Elixir type checks every single line of code, finding bugs and dead code, without developer overhead (no typing signatures) and extremely low false positives rate. Plus a faster compiler! Links and reports below.
55
307
47
1,487
129,626
> The rule is already in AGENTS.md. The problem is I keep forgetting to run it. well thanks AGENTS.md
28
Houston, we have a problem. Actually, make that two problems. I see two Microsoft Outlooks on this thing… and neither one is working. #ArtemisII #MicrosoftOutlook #SpaceProblems
71
The Erlang VM has all these incredible things. Did you know you can boot a `:peer` node as a VM within the VM, fully meshed? Enter `FlyDeploy.BlueGreen` - "hot bluegreen" deploys where we spin up the new incoming VM, then cutover seamlessly: before/after code changes:
14
41
2
348
22,731
What do you use as agent for tidewave.ai? Want to try Tidewave for personal projects #phoenix #elixir
3
8
1,878
We're almost ready for the beta launch! 🎉 #MyElixirStatus #ElixirLang
1
2
1
37
1,968
I’m not sure if taking #spacex public is a good idea … tell me the pros
3
62
bMalum retweeted
ngl, these memory prices are VERY REASONABLE
48
65
27
4,376
637,115
bMalum retweeted
Kiro autonomous agent is in preview today, giving developers and teams a new way to keep work moving without breaking focus. It carries long-running work autonomously, keeps context across sessions and repos, and learns from your code reviews to improve with every task. Learn more here 👉 spr.ly/601370xrz #Agent #DevTools #AICoding #FrontierAgent #AWSreInvent
12
32
7
180
14,939
Anthropic just bought the JavaScript runtime Bun?! What…
Anthropic is acquiring @bunjavascript to further accelerate Claude Code’s growth. We're delighted that Bun—which has dramatically improved the JavaScript and TypeScript developer experience—is joining us to make Claude Code even better. Read more: anthropic.com/news/anthropic…
3
80
I totally missed the ECS Express Service launch—will it replace App Runner? I love the idea: just provide a container image and two roles, and you're good to go with sane defaults. docs.aws.amazon.com/AmazonEC…
2
595