<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Zane's Zines]]></title><description><![CDATA[Zane's Zines]]></description><link>https://zane.sterlings.family</link><image><url>https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png</url><title>Zane&apos;s Zines</title><link>https://zane.sterlings.family</link></image><generator>Substack</generator><lastBuildDate>Wed, 13 May 2026 09:51:19 GMT</lastBuildDate><atom:link href="https://zane.sterlings.family/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Zane Sterling]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[zanesterling@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[zanesterling@substack.com]]></itunes:email><itunes:name><![CDATA[Zane Sterling]]></itunes:name></itunes:owner><itunes:author><![CDATA[Zane Sterling]]></itunes:author><googleplay:owner><![CDATA[zanesterling@substack.com]]></googleplay:owner><googleplay:email><![CDATA[zanesterling@substack.com]]></googleplay:email><googleplay:author><![CDATA[Zane Sterling]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Nouvelle Vague]]></title><description><![CDATA[Today I went to see Nouvelle Vague (2025). It depicts the filming of Breathless (orig: &#192; bout de souffle), an important example of French New Wave cinema, and does so in the style of the time.]]></description><link>https://zane.sterlings.family/p/nouvelle-vague</link><guid isPermaLink="false">https://zane.sterlings.family/p/nouvelle-vague</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Wed, 01 Apr 2026 23:17:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ViU5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ViU5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ViU5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 424w, https://substackcdn.com/image/fetch/$s_!ViU5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 848w, https://substackcdn.com/image/fetch/$s_!ViU5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 1272w, https://substackcdn.com/image/fetch/$s_!ViU5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ViU5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp" width="400" height="533.3333333333334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:400,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ViU5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 424w, https://substackcdn.com/image/fetch/$s_!ViU5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 848w, https://substackcdn.com/image/fetch/$s_!ViU5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 1272w, https://substackcdn.com/image/fetch/$s_!ViU5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F728613da-dbb5-4b4a-a450-1d021f20fd08_1200x1600.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Today I went to see <em><a href="https://en.wikipedia.org/wiki/Nouvelle_Vague_(disambiguation)">Nouvelle Vague</a></em><a href="https://en.wikipedia.org/wiki/Nouvelle_Vague_(disambiguation)"> (2025)</a><em>.</em> It depicts the filming of <em><a href="https://en.wikipedia.org/wiki/Breathless_(1960_film)">Breathless</a></em><a href="https://en.wikipedia.org/wiki/Breathless_(1960_film)"> (orig: </a><em><a href="https://en.wikipedia.org/wiki/Breathless_(1960_film)">&#192; bout de souffle</a></em><a href="https://en.wikipedia.org/wiki/Breathless_(1960_film)">)</a>, an important example of French New Wave cinema, and does so in the style of the time. Director Richard Linklater has said that he intended the film to seem as if it could have plausibly been shot by another director in the movement working at the same time.</p><p>I&#8217;ll here continue the ongoing tradition of breaking my own rule of not reviewing the movies I watch by saying it was good! I liked it!</p><p>In the movie, long-time film critic Jean-Luc Godard takes on the task of directing his first movie, which is to serve as &#8220;the greatest criticism&#8221; by depicting the way he believes a movie should be. His distinct approach to filmmaking is jarring to the industry veterans that he works with, putting him at loggerheads with both the producer and star. In the end he succeeds at working the way he wants to and releases the movie to acclaim.</p><p>That&#8217;s a very familiar shape of story. I&#8217;ve seen a whole passel of movies and books starring the brilliant underdog who knows just how to do the thing right, if they can just overcome the stick-in-the-mud academy/teacher/boss who stands in their way. For some examples, see <a href="https://en.wikipedia.org/wiki/Skyward_(novel)">Skyward</a>, <a href="https://en.wikipedia.org/wiki/Amadeus_(film)">Amadeus</a>, <a href="https://en.wikipedia.org/wiki/Harry_Potter_and_the_Methods_of_Rationality">Harry Potter and the Methods of Rationality</a>, and 17-year-old Zane in his fantasies. And yet despite fitting that shape narratively, <em>Nouvelle Vague</em> carries none of the righteousness that I would have thought was necessary to the trope. It does not feel like Godard is a genius and the producer a bozo, and there is no lasting enmity or redemptive moment of &#8220;you were right Mr Godard, we see the light now&#8221;. What&#8217;s left is a very healthy depiction of normal people having differences, getting frustrated, and showing up to work anyhow.</p><p>Godard has a strong vision for what he will film and how his crew will make it happen, and he is rarely willing to compromise with his coworkers. At the same time, he does not need to be the smartest person in the room, or be seen as having all the answers. If he has no ideas to film on the day, he cancels or cuts short production. If his tooth hurts and he can&#8217;t think of anything to put to film, he sends everyone home. He&#8217;s perfectly content to sit in the caf&#233; with his notebook and papers trying to come up with what comes next, while the cast and crew sit around drinking, chatting, and dancing. That would embarrass me to tears! I flush just thinking about it. I&#8217;ve cut Dungeons and Dragons sessions short for the same reason, and it always feels like failure. Something to learn from Godard, then.</p><p>A model behavior too, is the way that the members of the movement discuss each other&#8217;s films. In the opening scene Godard and friends watch the new movie from Georges de Beauregard. At the party afterward, Beauregard asks Godard what he thinks, and Godard tells him the film is terrible. Beauregard replies cheerily that Godard is his favorite film critic, and the two have a drink. This resilience in the face of criticism is the domain of a man comfortable in his own worth. Quiet confidence: not the fragile arrogance that everything you make is golden, but the acceptance that you are not your work, and a failed act does not a failed man make.</p><p>That same confidence, focused in attention but detached from shame, is I think what gives this Godard his power to accept his flubs and sail through chaos to the finish line. I&#8217;m not sure how one disentangles those shame-fibers that have grown through their mind-cloth. An ongoing project, in my case.</p><div><hr></div><p>Today&#8217;s graveyard section is short, just <em><a href="https://en.wikipedia.org/wiki/Good_Luck,_Have_Fun,_Don%27t_Die">Good Luck, Have Fun, Don&#8217;t Die</a></em>. Eh? Meh? Not a lot interesting to say about it. Someone said once that a movie should pass the &#8220;refrigerator test&#8221;: that is, if you&#8217;re enthralled by the magic moving picture at the theater, and don&#8217;t think of a plothole or objection to the movie until you&#8217;re at home staring into your fridge&#8217;s cavernous receptacle of sandwich meats, then the movie has succeeded. Fridge thoughts don&#8217;t count. GLHFDD did not pass the fridge test. Both predictable and incoherent. Still, a fun modern B-movie if you just want some spectacle that touches on contemporary themes.</p><p>That&#8217;s all for today! May you find the self-assuredness of the New Wave in your own world.</p><p>Zane</p>]]></content:encoded></item><item><title><![CDATA[Project Hail Mary, and not talking much at dinner after the movie]]></title><description><![CDATA[In this edition also: a graveyard of the unmentioned; and Kurosawa's autobiography]]></description><link>https://zane.sterlings.family/p/project-hail-mary-and-not-talking</link><guid isPermaLink="false">https://zane.sterlings.family/p/project-hail-mary-and-not-talking</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Mon, 23 Mar 2026 13:07:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GjqA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GjqA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GjqA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GjqA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GjqA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GjqA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GjqA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg" width="1000" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GjqA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GjqA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GjqA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GjqA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e0805b-b30b-419e-9a67-210870098065_1000x562.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Yesterday I went to see the new Project Hail Mary adaptation. It was good! And I don&#8217;t have much more to say about it.  It was an effective adaptation of the book, and a fun and visually striking movie in its own right. Ryan Gosling brings a lot of charisma and humanity to his role as Dr. Grace, the grade-school science teacher trapped in space. Apart from one scene in the middle climax where the drama wasn&#8217;t justified (why could they remote-trigger the ball drop, but not the winch rewind?) all the pieces fit together cleanly and tell a tight story. Like my friend <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Solariego&quot;,&quot;id&quot;:208278277,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa5e485f-c2b0-43e4-bb7a-f5759b7db88d_2424x2424.jpeg&quot;,&quot;uuid&quot;:&quot;1f6e7241-607e-4d22-bfd1-7199f1a44646&quot;}" data-component-name="MentionToDOM"></span> said afterward, it&#8217;s two and a half hours, but it really doesn&#8217;t feel like it.</p><p>As much as I enjoyed it though, I was left afterward with very little to ponder or talk about. Why is that? I don&#8217;t think that it&#8217;s that the movie is bad, or unenjoyable: when we went to see The Bride, which I think doesn&#8217;t quite hold together as a movie despite doing a bunch of things well, we were left for days afterwards picking over its bones and thinking about what it did right and wrong. Nor do I think it&#8217;s that Hail Mary is too good: Marty Supreme, The Testament of Ann Lee, and Silent Friend are all great movies from this year that left me with connections aplenty to think about and talk about.</p><p>I&#8217;m a bit stumped here. I find myself tempted to say things like &#8220;well, maybe it&#8217;s because it didn&#8217;t have a Big Concept&#8221;, but I think this is just me hiding my incomprehension in words that I can&#8217;t define, or picking another synonym for the thing that I&#8217;m failing to explain.</p><p>And perhaps I should caveat that this could just be a me thing. Ars Technica put out <a href="https://arstechnica.com/culture/2026/03/project-hail-mary-is-in-theaters-but-do-the-linguistics-work/">a pretty extensive article</a> discussing the linguistic issues of first contact and how they&#8217;re portrayed or ignored in the movie. So clearly someone else found some meat to chew on! Maybe I didn&#8217;t have the right receptors or thought-connections for this movie to light my sparklers.</p><p>Still I think that some movies are just talking about more than other movies, or talking in a way that is itself novel. That novelty, or at least novelty-for-me, is a big part of what I&#8217;m looking for in all media. A fun game is good, but a game that is fun in a way that I haven&#8217;t seen before is way better.</p><p>What do you think? What kinds of movies get you talking?</p><div><hr></div><p>Here below the fold I lay out a graveyard of movies that I watched, and might have had something to say about, but did not get around to blogging about. Please take my silence on these movies as my own failure to sit down and write, and not a criticism on the movies. Most were great!</p><ul><li><p>Winter in Sokcho: A girl in Sokcho, Korea has never known her French father, who left before she was born. A French painter moves in to the guesthouse she works at, and becomes the canvas for her feelings.</p></li><li><p>Un Poeta: A poet, alcoholic, and former professor struggles to put his life back together and bring a budding young talent to light.</p></li><li><p>Hoppers: Avatar, but for beavers.</p></li><li><p>The Bride: Frankenstein&#8217;s monster brings a woman to life to be his Bride. Little does he know she&#8217;s also haunted by the ghost of Mary Shelley.</p></li><li><p>Silent Friend: Do plants speak? Could we possibly understand each other?</p></li><li><p>Dust Bunny: Mads Mikkelsen, high-end hitman, refuses to take on the monster under your bed.</p></li><li><p>Rental Family: Brendan Fraser will pretend to be whoever you need him to be. Can false pretenses create real connection?</p></li></ul><p>Oh, in other news I read Akira Kurosawa&#8217;s <a href="https://en.wikipedia.org/wiki/Something_Like_an_Autobiography">Something Like an Autobiography</a>. It was good! Thanks to Carl for the recommendation &#8212; if you&#8217;re looking for skilled designers to help you with your design issues, give <a href="https://frog.house/">Frog House</a> a ring. Kurosawa recounts scenes from his life from earliest memories in the 1910s through to his directing Rashomon in 1950. And what a life! Walking hours in the morning to take kendo lessons from master swordsmen, witnessing the horror of the <a href="https://en.wikipedia.org/wiki/Great_Kant%C5%8D_Earthquake">Great Kanto Earthquake</a>, working as a painter in the silent film era. He saw and felt a lot, and lays it out for the reader with the sensitivity and awe for natural phenomena that would become characteristic of his directorial style.</p><p>That&#8217;s all I have for today. Until next time!</p>]]></content:encoded></item><item><title><![CDATA[Absurdism, surrealism, and maximalism]]></title><description><![CDATA[The contemporary aesthetics of Wuthering Heights and No Other Choice]]></description><link>https://zane.sterlings.family/p/absurdism-surrealism-and-maximalism</link><guid isPermaLink="false">https://zane.sterlings.family/p/absurdism-surrealism-and-maximalism</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Thu, 12 Feb 2026 23:53:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FhNx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FhNx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FhNx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 424w, https://substackcdn.com/image/fetch/$s_!FhNx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 848w, https://substackcdn.com/image/fetch/$s_!FhNx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 1272w, https://substackcdn.com/image/fetch/$s_!FhNx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FhNx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:22369024,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/tiff&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://zane.sterlings.family/i/187803801?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FhNx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 424w, https://substackcdn.com/image/fetch/$s_!FhNx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 848w, https://substackcdn.com/image/fetch/$s_!FhNx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 1272w, https://substackcdn.com/image/fetch/$s_!FhNx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fe8e71d-1a4a-43a3-bb95-50b32fed1452.tif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Just watched<a href="https://en.wikipedia.org/wiki/Wuthering_Heights_(2026_film)"> Wuthering Heights (2026).</a> Holy cow is that movie horny. In retrospect, that should have been no surprise from the director of Saltburn! Emerald Fennel, chill out, man.</p><p>In the movie, Catherine lives with her father, who is both a gambler and a drunk, in their house on the moors. One day he adopts a poor boy of her age, who she names Heathcliff. The two grow up together and fall in love, but just as they think to do something about it she marries the new neighbor, the wealthy Mr Linton. Heathcliff runs away, returns five years later rich, and the two have an affair that brings the movie to its climax. A bit like Great Gatsby, but a century earlier.</p><p>I was struck by the visual contrast between scenes filmed out on the wild moors, in fog and rain and some tepid sun, and those shot in the controlled lighting of a soundstage. The mansions of Catherine&#8217;s father and Mr Linton show off a fairytale absurdity: strawberries the size of your head; wallpaper painted to look like skin; a fireplace lintel made of stucco hands; a pile of liquor bottles ten feet high. Sometimes they play this for a laugh, but mostly it shows the grotesquery, idiocy, and wretched taste of the hyper-rich. The stark wild beauty of the moors stands in contrast as the site of Catherine and Heathcliff&#8217;s many trysts: the truth of one&#8217;s desire is plain, and harsh, and unforgiving.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xGIg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xGIg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xGIg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xGIg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xGIg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xGIg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg" width="1000" height="535" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:535,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:53888,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://zane.sterlings.family/i/187803801?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xGIg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xGIg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xGIg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xGIg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d7decc3-a826-4e8a-b53b-9775da279347_1000x535.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>There&#8217;s something going on with the maximalist aesthetic these last few years. <a href="https://en.wikipedia.org/wiki/Poor_Things_(film)">Poor Things (2023)</a> features similiarly over-the-top decor, and especially the design of the mad scientist.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eAJ8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eAJ8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 424w, https://substackcdn.com/image/fetch/$s_!eAJ8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 848w, https://substackcdn.com/image/fetch/$s_!eAJ8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 1272w, https://substackcdn.com/image/fetch/$s_!eAJ8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eAJ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:107414,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/avif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://zane.sterlings.family/i/187803801?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eAJ8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 424w, https://substackcdn.com/image/fetch/$s_!eAJ8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 848w, https://substackcdn.com/image/fetch/$s_!eAJ8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 1272w, https://substackcdn.com/image/fetch/$s_!eAJ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0489dbc-2019-4e05-a41e-d6b955b9bc57_2000x1000.avif 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><a href="https://en.wikipedia.org/wiki/Bugonia_(film)">Bugonia (2025)</a>, another Lanthamos joint, also shows bulbous flesh/cloth sets in the last chunk of the movie. I&#8217;ll say no more about that one. The earliest I can remember seeing this style was in the hotdog-fingered wackiness of <a href="https://en.wikipedia.org/wiki/Everything_Everywhere_All_at_Once">Everything Everywhere All at Once (2022)</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e5lv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e5lv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!e5lv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!e5lv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!e5lv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e5lv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg" width="636" height="360" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:360,&quot;width&quot;:636,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:33320,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://zane.sterlings.family/i/187803801?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!e5lv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!e5lv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!e5lv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!e5lv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F208e83fd-6b89-46b4-a29d-f42d5036520b_636x360.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>It&#8217;s hard to put my finger on what this aesthetic is. Visually I think it tends to be round, fleshy, and saturated. It&#8217;s deployed to different effect in different movies, but it always seems to convey a sense of overstuffed absurdity -- a feeling which I also got from the opening scene of <a href="https://en.wikipedia.org/wiki/No_Other_Choice">No Other Choice (2025)</a>. This scene introduces our main character as the family man, husband and father to two, having a typical Sunday barbeque. Their dogs, a pair of golden retrievers, patiently wait for scraps. His wife opens her birthday gift: a pair of golden dance shoes. The family comes together for a group hug, awash in the literal golden light of this picture-perfect moment. Though aesthetically it couldn&#8217;t be more different from the fleshy world of the other movies described, something rhymes in the way it layers elements of its ideal one over another until the whole thing feels like it must crash down like a jenga tower made of jello.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KWWp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KWWp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KWWp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KWWp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KWWp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KWWp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg" width="1408" height="792" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:1408,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:127362,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://zane.sterlings.family/i/187803801?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KWWp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KWWp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KWWp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KWWp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F139621f5-e6f4-4e89-a8af-8ccf6084103d_1408x792.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Is there a term for this style? I wonder if they have named themselves. Until they do, I dub them henceforth: fleshglorp. Long live the fleshglorp.</p>]]></content:encoded></item><item><title><![CDATA[The Testament of Ann Lee, Obex, and The Last Viking]]></title><description><![CDATA[in which our narrator admits that he might be in over his head]]></description><link>https://zane.sterlings.family/p/the-testament-of-ann-lee-obex-and</link><guid isPermaLink="false">https://zane.sterlings.family/p/the-testament-of-ann-lee-obex-and</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Fri, 30 Jan 2026 23:52:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-2R5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;m back in Germany after a long holiday season in the states, and I have three movies stacked up to say something about. Unfortunately I don&#8217;t have much to say! In the spirit of getting caught up, we&#8217;ll shake up the format this time and just get something written.</p><h2><a href="https://en.wikipedia.org/wiki/The_Testament_of_Ann_Lee">The Testament of Ann Lee (2025)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-2R5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-2R5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-2R5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-2R5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-2R5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-2R5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg" width="266" height="398.734" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1499,&quot;width&quot;:1000,&quot;resizeWidth&quot;:266,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-2R5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-2R5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-2R5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-2R5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99b51b5-c42b-451b-8280-c1a25eecc678_1000x1499.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Gorgeous! Compelling! Human!</p><p>The story is a little thread of americana woven tightly into the dense tapestry of northeastern American history. These &#8212; the Shakers &#8212; were always a small group: nine made the crossing to New York, at peak they numbered two to four thousand, and today they are just three. And yet they live on in the many clever and beautiful things they made.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wTnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wTnL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wTnL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wTnL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wTnL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wTnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg" width="486" height="328.45054945054943" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:984,&quot;width&quot;:1456,&quot;resizeWidth&quot;:486,&quot;bytes&quot;:688685,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://zane.sterlings.family/i/186358431?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wTnL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wTnL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wTnL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wTnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b349db5-2530-40f8-b906-9bc6765ad771_2536x1714.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Detail from <em>Shop Drawings of Shaker Iron and Tinware</em> by Ejner Handberg.</figcaption></figure></div><p>In high school we sang <a href="https://www.youtube.com/watch?v=OXDW-J3U2g4">Simple Gifts</a>, one of thousands of Shaker hymns. My parents have what I now believe to be a set of Shaker chairs, or at least chairs made in the Shaker style. They&#8217;re light, comfortable, sturdy, and seem to be endlessly repairable.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3KSI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3KSI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3KSI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3KSI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3KSI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3KSI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg" width="552" height="406.9921875" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:755,&quot;width&quot;:1024,&quot;resizeWidth&quot;:552,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3KSI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3KSI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3KSI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3KSI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F291fe326-b3a6-413b-84cc-0f3ff6cd109a_1024x755.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Some shorter Shaker chairs, shown hanging from the wall as they would be kept when not in use.</figcaption></figure></div><p>The cultural legacy of this small, hardworking group is remarkable. I&#8217;m thankful to Mona Fastvold and her cast and crew for giving me a peg on which to hang these details of my life.</p><h2><a href="https://en.wikipedia.org/wiki/OBEX">Obex (2026)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nzzZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nzzZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 424w, https://substackcdn.com/image/fetch/$s_!nzzZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 848w, https://substackcdn.com/image/fetch/$s_!nzzZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!nzzZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nzzZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg" width="304" height="450.224" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1481,&quot;width&quot;:1000,&quot;resizeWidth&quot;:304,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nzzZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 424w, https://substackcdn.com/image/fetch/$s_!nzzZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 848w, https://substackcdn.com/image/fetch/$s_!nzzZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!nzzZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb147d4c6-c55b-4723-9bb8-704bead00d1f_1000x1481.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is an odd one. It felt very much to me like two different movies. The first half is an instrospection into a life of isolation that felt unsettlingly familiar to me. There are real emotions here, and it gives you the time to feel your way through them, while also building up to the midpoint switch.</p><p>The second half is a simple adventure movie. Everything and everyone exists to support the plot. Emotions are simple and stated aloud. All threads resolve by the end. The writing here had only as much depth as the ancient Mac games it was emulating.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g04u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g04u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 424w, https://substackcdn.com/image/fetch/$s_!g04u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 848w, https://substackcdn.com/image/fetch/$s_!g04u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!g04u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g04u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg" width="602" height="338.625" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:602,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!g04u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 424w, https://substackcdn.com/image/fetch/$s_!g04u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 848w, https://substackcdn.com/image/fetch/$s_!g04u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!g04u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763080ff-8663-42fa-aa21-b93d50c2969e_2560x1440.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Maybe there&#8217;s something in that contrast? Our main character is a shut-in who won&#8217;t even open the door to talk to the woman who goes grocery shopping for him. His dreams are nightmarish reverberations of some childhood trauma. His only means of dealing with the challenging emotions of everyday life is to drown them out in media overload. The two-part structure could be an intentional reflection of this life: the overwhelming trials of the everyday set against the straightforward formula of the media that we use to escape it.</p><p>I dunno, man. I&#8217;d rather sit with the complex emotions for the whole 90 minutes. For a movie that does that, check out <a href="https://en.wikipedia.org/wiki/Still_Walking">Still Walking (2008)</a>. A man, his wife, and their son visit his parents to commemorate the anniversary of his brother&#8217;s death.</p><p>Alternatively if you just want to see some wacky shit happen in black and white, try <a href="https://en.wikipedia.org/wiki/Hundreds_of_Beavers">Hundreds of Beavers (2022)</a>.</p><h2><a href="https://en.wikipedia.org/wiki/The_Last_Viking_(2025_film)">The Last Viking (2025)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LTJS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LTJS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LTJS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LTJS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LTJS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LTJS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg" width="326" height="465.9381868131868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2081,&quot;width&quot;:1456,&quot;resizeWidth&quot;:326,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LTJS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LTJS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LTJS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LTJS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8c0688-3c37-4a2c-8480-031822350e2f_1984x2835.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Mads Mikkelsen in a heartfelt role = instant recommendation every time. The man is in a lot of Hollywood shovelware &#8212; like seriously, did anyone expect a hit from <a href="https://en.wikipedia.org/wiki/Indiana_Jones_and_the_Dial_of_Destiny">Indiana Jones and the Dial of Destiny</a>? &#8212; but when given a role with depth he fills it admirably.</p><p>Not really sure what to say that would add to this movie, so I think I&#8217;ll leave you today with two other Mads Mikkelsen movies that really show what he can do.</p><p>In <a href="https://en.wikipedia.org/wiki/Another_Round">Another Round (2020)</a>, he plays a high school teacher who agrees with a few of his colleagues to chase the Ballmer peak: maintain a blood alcohol level of 0.5% during work hours, under they hypothesis that it will improve their lives.</p><p>In <a href="https://en.wikipedia.org/wiki/The_Hunt_(2012_film)">The Hunt (2012)</a>, he plays a divorced kindergarten teacher who is falsely accused of sexually abusing a child, with disastrous consequences.</p><div><hr></div><p>That&#8217;s all we&#8217;ve got today! I will try to go see some more movies this weekend to catch up with what&#8217;s coming out here, and workshop some more how to fit a trip to the theater into my work week.</p><p>To all you popsicle-fingered folks in the US, I hope you are staying warm and melty indoors.</p><p>See you soon!</p>]]></content:encoded></item><item><title><![CDATA[Primate; urgh]]></title><description><![CDATA[Today I walked over to the AMC to watch Primate. Pretty forgettable movie in a pretty soulless theater in a pretty gross corporate hellscape of a neighborhood. Would not recommend any of the above. If you&#8217;re in the greater Boston area, I&#8217;d recommend checking out what&#8217;s showing at the]]></description><link>https://zane.sterlings.family/p/primate-urgh</link><guid isPermaLink="false">https://zane.sterlings.family/p/primate-urgh</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Tue, 13 Jan 2026 02:35:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today I walked over to the AMC to watch <a href="https://en.wikipedia.org/wiki/Primate_(film)">Primate</a>. Pretty forgettable movie in a pretty soulless theater in a pretty gross corporate hellscape of a neighborhood. Would not recommend any of the above. If you&#8217;re in the greater Boston area, I&#8217;d recommend checking out what&#8217;s showing at the <a href="https://www.somervilletheatre.com/">Somerville Theatre</a> or <a href="https://brattlefilm.org/">The Brattle</a> before trying the AMC at Assembly.</p><p>Short one today. Did you know rabies takes one to three months from infection to first symptoms? The virus spends that time hiking up your nerves from the site of infection to the brain.</p><p>In countries where rabies is common in dogs, the vast majority of cases in humans come from dog bites. Thankfully in Europe and the United States there is no longer a stable circulating population of rabies in dogs. Score one for vaccination!</p><p>One last odd rabies story before I go.</p><blockquote><p>In 1978, a hiker walking through the Rhone River valley in the Swiss Alps might have been surprised to stumble over a chicken head. Chicken heads, laced with live rabies vaccine, had been spread across the valley in an attempt to halt an oncoming tide of rabies. Scientists hoped that foxes would eat the bait, thus immunizing themselves and forming a living barrier against the disease. The plan worked, and hope for a new solution to the rabies problem grew.</p><p>Chicken heads are messy and hard to get in massive numbers, so scientists developed a sort of fox dessert wafer made of fishmeal, bonemeal and fat, with an imbedded plastic packet of rabies vaccine. The wafer was a hit with foxes, and since 1983 over 5.2 million baits have been distributed. Over 70 per cent of foxes in the target areas take the bait and become immunized. This means that there are no longer enough susceptible animals in these areas to continue the chain of transmission.</p><p>Today Switzerland is virtually rabies-free.</p><p><em>Taken from <a href="https://archive.org/details/worldoffox00gram/page/94/mode/2up">The World of the Fox</a> by Rebecca L. Grambo.</em></p></blockquote><div><hr></div><p>Hey, what the hell, are those vampire teeth?!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UOK0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UOK0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UOK0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UOK0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UOK0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UOK0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg" width="616" height="345.6877637130802" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:266,&quot;width&quot;:474,&quot;resizeWidth&quot;:616,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UOK0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UOK0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UOK0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UOK0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc2c2406-fa3c-4002-b537-dc7f502ed432_474x266.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div>]]></content:encoded></item><item><title><![CDATA[Resurrection and sitting with the mystery]]></title><description><![CDATA[The other day I watched Resurrection, a new movie directed by B&#236; G&#224;n (&#27605;&#36195;).]]></description><link>https://zane.sterlings.family/p/resurrection-and-sitting-with-the</link><guid isPermaLink="false">https://zane.sterlings.family/p/resurrection-and-sitting-with-the</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Sun, 11 Jan 2026 20:14:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The other day I watched <a href="https://en.wikipedia.org/wiki/Resurrection_(2025_film)">Resurrection</a>, a new movie directed by B&#236; G&#224;n (&#27605;&#36195;). It&#8217;s a series of four dreams and a framing narrative, all about death, rebirth, and the end or new beginning of cinema.</p><p>Maybe? I&#8217;m still figuring it out.</p><p>It&#8217;s clear from the outset that the movie is About Something, but the continually unrolling mystery resists total analysis. You can catch fragments of symbolism and themes that fit together like a collage of mirrors, for me never quite resolving into a unified image.</p><p>This movie-going experience can be uncomfortable. It&#8217;s relaxing to see a movie that speaks in clear metaphors, like <a href="https://en.wikipedia.org/wiki/Nausica%C3%A4_of_the_Valley_of_the_Wind_(film)">Nausica&#228;</a>, say. And it can be satisfying to watch one that initially appears blurry before snapping into focus in the final moments, giving a feeling akin to the final scenes of a puzzle-box mystery like <a href="https://en.wikipedia.org/wiki/Last_Night_in_Soho">Last Night in Soho</a>. If you&#8217;re expecting an experience like either of those, the ambiguity that a movie like Resurrection immerses you in can make you feel stupid, like you&#8217;re just not getting the point. It&#8217;s a little like buying a jigsaw puzzle, but getting a box of watercolors. Like what is this bullshit! What&#8217;s the intended way to put these together?</p><p>But if you release the movie from the obligation of communicating a single clear point, these movies can provide some of the richest experiences out there, extending off the screen into conversations afterward as you try to piece together not what the movie meant, but what it meant to you.</p><p>For that reason, I loved watching <a href="https://en.wikipedia.org/wiki/The_Boy_and_the_Heron">The Boy and the Heron</a> when it came out two years ago. It&#8217;s a movie overflowing with themes and things that could symbolize emotions or events in the real world, but each angle of analysis I threw at it could only account for some different fraction of the events of the movie. Nothing I could think of would unify the many bits of strange synthetic folklore that Miyazaki balled up into the movie. In the end, my tin-foil hat theory is that the movie&#8217;s resistance to analysis reflects the unexplainability of the horror that is war.</p><p>I&#8217;ve never seen anyone else talk about this theory, and I doubt that it was Miyazaki&#8217;s true motivation in making the work what it is. But I had great fun grappling with what I saw and heard and felt and trying to anneal it into a crystal of thought.</p><p>---</p><p>Best wishes to you in this second week of the second quarter of our century. May you find your peace with, what the heck, another immortal vampire born in 1601, where in the world are these things coming from, Artemis did you leave the back door open ---</p>]]></content:encoded></item><item><title><![CDATA[Movies you can spoil, and movies you can't]]></title><description><![CDATA[Yesterday I watched Hamnet, a movie about Shakespeare and his wife, the death of their son, and how that (fictionally) inspired him to write Hamlet.]]></description><link>https://zane.sterlings.family/p/movies-you-can-spoil-and-movies-you</link><guid isPermaLink="false">https://zane.sterlings.family/p/movies-you-can-spoil-and-movies-you</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Wed, 07 Jan 2026 04:17:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday I watched <a href="https://en.wikipedia.org/wiki/Hamnet_(film)">Hamnet</a>, a movie about Shakespeare and his wife, the death of their son, and how that (fictionally) inspired him to write Hamlet.</p><p>Today I watched <a href="https://en.wikipedia.org/wiki/It_Was_Just_an_Accident">It Was Just an Accident</a>, in which a guy thinks he&#8217;s found the intelligence agent who tortured him in jail, now years after his release.</p><p>I&#8217;ve now told you the whole plot of the first movie, but if you&#8217;re gonna like it I don&#8217;t think that matters. And yet I don&#8217;t dare tell you anything more about what happens in the second for fear of ruining it for you. What the heck? How can two excellent movies be so different in this way? What&#8217;s the difference between movies you can spoil and movies you can&#8217;t?</p><p></p><p>I think that it has something to do with what&#8217;s interesting about the movie. A fractional list of ways a movie can be interesting: It can have shots that convey some symbolic meaning, like the crime boss in <a href="https://en.wikipedia.org/wiki/Tazza:_The_High_Rollers">Tazza</a> standing at Jesus&#8217; place in The Last Supper and looking over at Judas. It can have shots that are simply wordlessly moving, like gosh, any shot of the sea in <a href="https://en.wikipedia.org/wiki/The_Outrun_(film)">The Outrun</a>. It can make you itch to know something, like a good whodunit. It can make you curious to learn more about a mysterious world. It can make you laugh. It can take you to a place that you don&#8217;t want to leave, or let you spend time with characters you think are clever, or cool, or hot.</p><p>Some of these kinds of fun are wholly reliant on surprise, like the whodunit itch, and some are totally separate, like the moving landscape shots. Others land somewhere in the middle. A joke is less funny the second time -- with some rare exceptions -- but I think you&#8217;d be hard pressed to tell me any of the jokes in the Naked Gun in such a way as to spoil them. You could describe them, yeah, but they&#8217;re still going to be funny when I see them in the movie.</p><p>I would divide them into two categories: experiential and analytical. Here by experiential, I mean things like feeling an emotion, looking at a richly textured image, or watching an expression play out on an actor&#8217;s face. These are complex experiences with a ton of detail that&#8217;s hard to put into words. They stand in contrast to the analytical: the events in a story, the meaning of symbols, or a fact about the world. These may be complicated, but if we sat down and talked through them we could get all the information across. For whatever reason, experiential fun is harder to talk about, unless both people have a shared experience that they can point to. If you&#8217;re both lying there looking at the clouds, you can just say &#8220;that one looks like a nose&#8221; and the other person will get to have the same perception as you; but go home to tell your partner about the cloud that looked like a nose and, try as you might, they won&#8217;t really get it.</p><p>Because experiential fun is so hard to convey in words, a movie that relies mostly on it is unspoilable. The point of watching Hamnet is how the pictures, gestures, and expressions build up an arc of feeling in you bit by bit over the course of the movie. Know what you may about the plot, these elements will still have their impact. Analytical fun, though, is all about words! Symbols, meaning, and plot are all tied up in and made out of language, and so by using language we can defang their fun. In It Was Just an Accident the crux of the fun of the movie is the tension of what will come next. Did our main character get the right guy? Will he run from him? Capture him? Kill him? The open question of the plot creates tension that would fall apart if I told you what comes next.</p><p>Most movies incorporate fun from both sides of the spectrum. Even the examples I&#8217;ve chosen do this: Hamnet&#8217;s second half is probably more impactful if you don&#8217;t know quite how it plays out, and It Was Just an Accident has plenty of beautiful shots that can delight even if you know where the story is going.</p><p>So take some comfort the next time you see a trailer that shows too much. The story might be spent for you, but the telling is still to come.</p>]]></content:encoded></item><item><title><![CDATA[Marty Supreme]]></title><description><![CDATA[Yesterday I went to see Marty Supreme, the new movie with Timoth&#233;e Chalamet.]]></description><link>https://zane.sterlings.family/p/marty-supreme</link><guid isPermaLink="false">https://zane.sterlings.family/p/marty-supreme</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Fri, 02 Jan 2026 01:35:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday I went to see Marty Supreme, the new movie with Timoth&#233;e Chalamet. While it&#8217;s not a 2026 movie, I&#8217;m eager to kick off the year of movies with a Something on this, the first day of the year.</p><p>The film follows Marty Mauser, a world-class ping pong player desperate to be the greatest. The story centers on his conflict with Endo Koto, the player for Japan, and Marty&#8217;s struggles to be able to attend the 1952 British Open, and later the World Championships. In character, Mauser&#8217;s narcissism and monomaniacal obsession with his sport recall Chalamet&#8217;s 2024 depiction of a young Bob Dylan in A Complete Unknown. In structure and emotional tone, the movie reminded me a lot 2019&#8217;s Uncut Gems, the panic attack of a movie starring Adam Sandler as a gambling-obsessed gem dealer trying to recover a lost jewel. Now that I look at the credits, that makes a ton of sense: Uncut gems was directed by the Safdie brothers Josh and Benny, and cowritten by them and Ronald Bronstein; Marty Supreme has the same credentials, minus the involvement of Benny Safdie.</p><p>I was really struck by how historically charged the atmosphere of the movie was. 1952 was just seven years after the end of World War II, and many of the characters wear scars of the time: tattoos from Auschwitz, hearing loss from the <a href="https://en.wikipedia.org/wiki/Bombing_of_Tokyo">Tokyo air raids</a>, the painful memory of a lost son. My picture of the &#8220;postwar period&#8221; is dominated by the Korean war -- the product of a childhood spent rewatching <a href="https://en.wikipedia.org/wiki/M*A*S*H_(TV_series)">M*A*S*H</a> -- so I found novel this picture of a world of damaged people heaving a collective sigh and going back to work.</p><p>The dramatic final match takes place in Japan in 1952. I didn&#8217;t know much about this period of Japanese history, so I did some reading up. After Japan&#8217;s surrender on September 2nd 1945, the nation entered a seven-year period of American occupation. During this time the civil government still operated separately from the occupying army, but underwent dramatic changes at their demand including the institution of a new American-written constitution. Among other changes, Article 9 of this constitution banned the country from maintaining an army of its own. In the first years of occupation a primary goal was to demilitarize the country by removing 200,000 wartime officials from government posts and restructuring finance and industry to make it less able to support a military. Rising Cold War tensions and American concerns over the spread of communism in the far east led to the reversal of much of that work.</p><p>In 1952 the <a href="https://en.wikipedia.org/wiki/Security_Treaty_between_the_United_States_and_Japan">US-Japan Security Treaty</a> went into effect, which along with the <a href="https://en.wikipedia.org/wiki/Treaty_of_San_Francisco">Treaty of San Francisco</a> ended the occupation, reestablished Japan as a sovereign nation, and created the military alliance between the US and Japan that lasts to this day. These were hotly disputed among the members of government and the people of Japan, who variously believed that Japan: should not continue to be occupied by 260,000 US troops; should not risk being drawn into US-Soviet conflicts; and should not create a standing army. Widespread protests occurred throughout the country, including the <a href="https://en.wikipedia.org/wiki/Bloody_May_Day_(1952)">Bloody May Day Incident</a>. In 1950 criticism from Joseph Stalin had caused the Japanese Communist Party to reverse their policy of peaceful protest and attempt to foment revolution. Members and supporters of the party infiltrated the peaceful union May Day protest and incited a violent confrontation between protestors and police. In the ensuing chaos 2300 people were injured, and 2 were killed.</p><p>It is into this uncertain world that Marty inserts himself in the movie&#8217;s third act. While the plot doesn&#8217;t delve into the local politics, the tension between the people of Japan and the American GIs is on full display. If you&#8217;re interested in seeing a contemporary Japanese perspective on this period, the 1960 film <a href="https://www.imdb.com/title/tt0053989/">Dry Lake (aka Youth in Fury)</a> follows a university student entangled in the mass protests against the revised security treaty. The director, Masahiro Shinoda, is one of the greats of Japanese New Wave cinema. My two favorites of his are <a href="https://en.wikipedia.org/wiki/Demon_Pond_(1979_film)">Demon Pond</a>, an adaptation of a kabuki play by the same name, and <a href="https://en.wikipedia.org/wiki/Silence_(1971_film)">Silence</a>, a movie following two Jesuit priests who illegally enter 16th century Japan to spread the word of Christianity.</p><p>If you like the ping pong angle but want something a bit more heartfelt and less cynical, I highly recommend the incredible <a href="https://www.imdb.com/title/tt3592032/">Ping Pong the Animation</a>.</p><p></p><p>That&#8217;s all for this first Something. I wish you all a happy new year, and may you see many movies that make you say &#8220;I&#8217;m an immortal vampire born in 1601.&#8221;</p>]]></content:encoded></item><item><title><![CDATA[The Year of Movies]]></title><description><![CDATA[In 2026 I&#8217;ll be starting a new challenge: I&#8217;m going to try to watch every new movie that comes out in a Munich theater.]]></description><link>https://zane.sterlings.family/p/the-year-of-movies</link><guid isPermaLink="false">https://zane.sterlings.family/p/the-year-of-movies</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Mon, 29 Dec 2025 23:22:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In 2026 I&#8217;ll be starting a new challenge: I&#8217;m going to try to watch every new movie that comes out in a Munich theater.</p><p>The idea came to me earlier this year when I was trying to work out how big the Korean movie industry is. This is a surprisingly hard thing to do! There are some articles on the internet with fuzzy estimates that disagree with each other, in the neighborhood of 100-500 movies.</p><p>Part of the problem is getting the data: to my knowledge there&#8217;s no single publicly available database which lists all movies that have released in a theater. IMDB presumably has much of that information, but surfaces it in ways that (1) obscure the answer and (2) make me nervous that they might be missing a large chunk of releases.</p><p>Another part of the problem is definitions. What&#8217;s a movie? Do documentaries count? What about recordings of live performances? Does it have to be 90 minutes? Does a 20-minute short by Wes Anderson count? What about Leo Dicaprio&#8217;s 4-hour epic of the year? What does it mean to come out in a theater? Does showing just once in a private screening count? If not, then how many times does it need to show? In how many theaters? For that matter, what constitutes a real theater? Home theaters obviously don&#8217;t count; what about museums? What about private clubs? The questions go on and on, with every one dialing the movie count up or down. Trying to answer all of these seriously seems like great bait for pedants, but I&#8217;m not much interested in really getting an answer. Instead, the question has become a jumping-off point for my project of 2026.</p><p>Let&#8217;s set some ground rules. For me to count it in the challenge, a movie has to be a new release showing in one of the 14 Munich movie theaters<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>. I won&#8217;t be including documentaries. Nothing against a good documentary, but I&#8217;m most interested in exploring fiction movies this year. Biopics and historical dramas are fine, though. The new releases rule is partly to avoid blowing up the movie count, and partly so that what I watch can be an even covering sample of what&#8217;s released with minimal editorial influence from any source of recommendations. I expect that there will be some edge cases around foreign (ie. non-German) movies that first released abroad in a recent year, and are now being released in Germany for the first time in 2026. I&#8217;ll deal with these individually as they come up. The spirit of the law here is to see them if they&#8217;re new, and I don&#8217;t want to get bogged down in planning for every eventuality.</p><p>For each movie that I go see I&#8217;ll write <em>something</em> here on this blog. I&#8217;d like each one to include something interesting I learned from the movie, whether that be about the form of movies, the subject matter, or whatever else the experience makes me think of. I will definitely include my subjective experience, but these are not meant to be reviews in any traditional sense. And lastly, I&#8217;ll do my best to avoid spoilers and flag them when they come up.</p><p>Some questions I&#8217;ve gotten when pitching this to friends:</p><blockquote><p>Oh god, why?</p></blockquote><p>I love a crazy project. When I graduated from college I cycled the length of the US Pacific coast, from the Mexican border in San Diego all the way to Vancouver, Canada. 2000 miles, and 6 weeks on the road. Now, this is arguably not crazy: lots of people do it every year, and the route is popular enough to be covered by multiple guidebooks, including the excellent <a href="https://en.wikipedia.org/wiki/Bicycling_the_Pacific_Coast">Bicycling the Pacific Coast</a>. While I was on the road I met up with a friend of my dad&#8217;s who had just completed an even longer cycling trip from New York City to Oregon, some 3000-odd miles, and was killing time by riding down the coast to San Francisco. But still, the thing has a romance to it and, as I found out when I told people what I was planning, a real shock value!</p><p>The crazy project serves as a nice reminder of what&#8217;s possible when you put your mind to it. Completed, it gives you a good reason to believe that you can do the next crazy thing. Uncompleted, it stands as a half-finished story or a fond memory. Either way, I find I learn something about myself.</p><p>And I definitely have something of a defiant streak. The more people tell me something&#8217;s impossible, the more I want to try it :-)</p><blockquote><p>Okay, but why <em>this</em> project?</p></blockquote><p>How do you choose what to watch?</p><p>For me, movies on my watchlist come from some mix of personal recommendations from friends, suggestions and mentions from internet people I follow, posters I see around the city, and sometimes whatever&#8217;s at the top of Critierion Channel. This works well to help me find movies I like: <a href="https://trakt.tv">Trakt</a> tells me I watched 54 movies in 2025, and looking back through the list there&#8217;s only one or two that I didn&#8217;t like.</p><p>At the same time, I do worry about the influence of advertising. In the most utopian view, advertising is a way to pair good products with people who would like them. In the more dystopian view, it&#8217;s an attempt by corporations to persuade consumers to buy something they don&#8217;t need or want. In the extreme, an algorithmic feed has 100% control over what you watch within the feed. If TikTok doesn&#8217;t want to show you some content, you will never see it unless linked to it from outside. Surrendering control over your attention like this is fun, but concerning: a meaningful chunk of who we are comes from what we watch, read, and think about. Giving up your attention to the algorithm means giving up part of your ability to decide who you are. On the internet you can regain control by subscribing to RSS feeds and newsletters from individual people and brands. What then can we do about movies?</p><p>Now, obviously the situation at the theater is not at so dire as with infinite feeds. We don&#8217;t sit down in the movie theater with a blank ticket and watch whatever they think we&#8217;d like (mostly -- some theaters have tickets like this for advance screenings) (also hmm isn&#8217;t this how a lot of people watch Netflix?), we think about it, talk with our friends, and then consciously decide to go to a specific movie. That choice is influenced by advertising, yes, but also by recommendations from real human beings.</p><p>Still, I wonder: what&#8217;s out there that I&#8217;ve never heard about?</p><p>By watching every movie that comes out I can step through the mystifying veil and get a real, total understanding of what&#8217;s being made, and hopefully find a lot of interesting stuff that no one I know is talking about.</p><blockquote><p>What about direct-to-streaming movies?</p></blockquote><p>1. Too expensive to get subscriptions for all the platforms.</p><p>2. Too hard to understand what&#8217;s being released.</p><p>3. Good grief, isn&#8217;t 100-500 movies enough?</p><blockquote><p>Man, you&#8217;re gonna watch a lot of baaad movies.</p></blockquote><p>Ain&#8217;t that the truth.</p><p>My hope is that even a bad movie can inspire an interesting thought. A movie with flat characters can still have an interesting premise, or teach me something about story structure, or have a neat shot or series of cuts.</p><p>As well, what I think is bad may be someone else&#8217;s favorite movie. Sometimes that&#8217;s because of irreconcilable personality differences, but sometimes it&#8217;s just because I haven&#8217;t figured out <em>how</em> to enjoy the thing. For a long time I found roguelike games boring. I would play them for hours until I got frustrated enough to quit, and never pick them up again. When Hades came out in 2020, I tried a different approach: each morning I played two runs, maybe an hour of game time, and then I put the game down and went about my day. Short sessions helped me avoid burning out on the game, and daily play helped me build up skill. Over the course of the next couple months I put in &gt;40 hours, and completed the story. Having fun is a wide skill. You might be good at it in some situations, and bad at it in others. I intend to try to have fun, even with movies that I initially don&#8217;t like.</p><p>I do reserve the right to skip kids&#8217; movies if I get tired of them though.</p><blockquote><p>But what about the cost?</p></blockquote><p>A few theaters in Munich offer monthly or yearly subscriptions. <a href="https://www.city-kinos.de/en/shop#!/Digitaler-Yorck-Unlimited-Gutschein/p/514822543">The Yorck theaters</a> offer a year of unlimited movies for ~240EUR. That pays off if you watch two movies a month. <a href="https://neokinos.de/abo">Neo Kinos</a> has a deal with the same price, but for 8 viewings a month. I&#8217;ll probably use one or the other, and pay for an individual ticket if there&#8217;s a movie that I can only see at a different theater.</p><blockquote><p>Isn&#8217;t it just too many movies?</p></blockquote><p>Well, it is a <em>lot</em> of movies. At the upper end of 500 movies a year, that&#8217;s more than one every day and about 10 times as many as I saw the previous year. At an average 2hrs per movie that comes out to 1000 hours over the course of the year, or about half of a full-time job. It will take up a big chunk of my free time, and is guaranteed to restructure my social life (such as it is).</p><p>Too many? I guess we&#8217;ll have to wait and see.</p><div><hr></div><p>Follow along here on the blog. First <em>something</em> will be coming new years&#8217; day.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><ol><li><p>Arena Filmtheater</p></li><li><p>Cadillac &amp; Veranda Cinema</p></li><li><p>CinemaxX Munich</p></li><li><p>City-Atelier Kinos</p></li><li><p>Gloria Palast</p></li><li><p>Kino Solln</p></li><li><p>Leopold Kino</p></li><li><p>Mathaeser Filmpalast</p></li><li><p>Monopol Kino</p></li><li><p>Neues Rex Kino</p></li><li><p>New Maxim Cinema</p></li><li><p>Rio Filmcafe</p></li><li><p>Royal Filmpalast</p></li><li><p>Theatiner Filmtheater</p></li></ol></div></div>]]></content:encoded></item><item><title><![CDATA[15x faster than Eigen]]></title><description><![CDATA[Accelerating CPU-side matrix multiplication with AMX and Neon]]></description><link>https://zane.sterlings.family/p/15x-faster-than-eigen</link><guid isPermaLink="false">https://zane.sterlings.family/p/15x-faster-than-eigen</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Mon, 18 Aug 2025 13:59:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zYsg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb502b8-88ba-4805-9056-d656b849d3f5_933x933.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello! This month I&#8217;ve been digging into dense matrices: how to write blazing fast CPU-side matrix multiplications, and how to adjust the storage pattern to minimize the time spent waiting on cache misses.</p><p>I&#8217;ll soon be starting a new job at <a href="https://bedrockenergy.com/">Bedrock Energy</a>, where I&#8217;ll be working on accelerating some physical simulations that we use to design an optimal field of boreholes for <a href="https://en.wikipedia.org/wiki/Ground_source_heat_pump">geothermal heat pumps</a>. These sorts of simulations, using the <a href="https://en.wikipedia.org/wiki/Finite_element_method">Finite Element Method (FEM)</a>, essentially come down to solving the equation Au=b, where A is a known matrix, b is a known vector, and u is the vector you&#8217;re trying to solve for. You could solve this by finding the inverse of A (assuming it&#8217;s invertible) and computing u=A^(-1)*b, but for an n x n matrix inversion is an O(n^3) operation, and the matrices we deal with are quite large. So practical techniques involve an optimization process: start with a guess for u, compute Au and compare to the known target b, and adjust your guess to produce a better guess. That process involves a lot of repeated matmuls, so it&#8217;s important to be able to do them fast.</p><p>An aside: in practice the matrix A is usually very sparse, with most entries being 0. For that scenario the optimal storage and matmul algorithms end up being quite different than the general case. In this blog post we&#8217;ll ignore that, and just look at dense matrices. I may look at sparse matrices in a future post.</p><p>And one last thing before we get into the meat of the optimization. When I heard &#8220;matrix multiplication&#8221;, my first instinct was &#8220;can we do this on a GPU?&#8221; GPUs are linear-algebra crunching machines, thanks to ~35 years of optimization for games and ML workloads. The issue in our case, though, is the high cost of data transfer from RAM to GPU memory. In the optimization cycle described above, each time we try a guess for u we need to send that vector over to the GPU. It&#8217;s my impression, although I haven&#8217;t yet done a careful evaluation, that the time taken by data transfer would eat up the gain from faster matrix multiplications.</p><p>So I&#8217;m left wondering: how fast can we get matrix multiplications on modern CPUs? Let&#8217;s find out. To give a goalpost to aim for, we&#8217;ll benchmark against <a href="http://eigen.tuxfamily.org">Eigen</a>, which is in my experience the linear algebra library that everyone uses.</p><h2>1. A naive implementation</h2><p>We&#8217;ll start with the simplest implementation we can think of. We&#8217;ll store matrices at rest in <strong>row-major order</strong>. This means that the values are in one big NxM array, walking through the matrix from left to right and top to bottom, in the same order that your eyes are reading through this text.</p><pre><code>struct RowMatrix {
  size_t rows, height;
  f32 *values;

  RowMatrix(size_t width, size_t height)
    : width(width), height(height)
  {
    values = (f32*)aligned_alloc(128, sizeof(f32) * width * height);
  }
  ~RowMatrix() {
    free(values);
  }

  inline void set(size_t row, size_t col, f32 value) {
    values[row * width + col] = value;
  }
  inline f32 get(size_t row, size_t col) {
    return values[row * width + col];
  }
};</code></pre><p>The matrix multiplication will also be as simple as possible. Matrix multiplication is defined such that if C = A*B, then C_ij = sum_k(A_ik * B_kj). We&#8217;ll implement that directly with a triply nested for-loop.</p><pre><code>void naive_matmul(RowMatrix &amp;C, RowMatrix &amp;A, RowMatrix &amp;B) {
  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      f32 acc = 0.0f;
      for (size_t k = 0; k &lt; A.cols; k++) {
        acc += A.get(i, k) * B.get(k, j);
      }
      C.set(i, j, acc);
    }
  }
}</code></pre><p>Done! How&#8217;d we do? On a 512 x 512 matrix of f32s, our naive implementation was 0.03x as fast as Eigen. Oof!. I&#8217;ll notate this as a speed of <strong>0.03E</strong>, where 1E is the speed of Eigen, and 2E is twice as fast.</p><h2>2. Transpose first</h2><p>So how can we improve on that? Let&#8217;s think about memory first. When you issue a load instruction, the CPU will first check the L1 cache for the data before repeating with the L2, then L3, and finally issuing a fetch from RAM. The caches are split into <em>cache lines</em>, which are usually 64 bytes these days. When the fetch misses the cache and falls through to RAM, it will pull up a whole cache line&#8217;s worth of consecutive memory at a time, replacing some line which was already in the cache. This helps to keep the number of lines for the CPU to check small, and also helps make the ~400-cycle long fetch worth it.</p><p>This is relevant to the inner loop of our naive implementation. In that k-loop we&#8217;re iterating over a row of A and a column of B. Since our matrices are in row-major format, the elements of that row of A are consecutive in memory. When we load the first 4-byte element, we actually pull 64B/4B=<strong>8 elements</strong> at once into the cache, making the next iterations of the loop quicker to run. The elements of the column of B, however, are spaced out in memory, so each fetch from RAM can only pull one into cache at a time.</p><p>Under the hypothesis that the extra fetches are affecting our runtime, we can try first transposing B so that when we&#8217;re in our hot loop those fetches can run smoothly.</p><pre><code>void naive_matmul_transp(RowMatrix &amp;C, RowMatrix &amp;A, RowMatrix &amp;B) {
  RowMatrix BB(B.cols, B.rows);
  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      BB.set(j, i, B.get(i, j));
    }
  }

  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      f32 acc = 0.0f;
      for (size_t k = 0; k &lt; A.cols; k++) {
        acc += A.get(i, k) * BB.get(j, k);
      }
      C.set(i, j, acc);
    }
  }
}</code></pre><p>This speeds up our matmul by <strong>1.5x</strong>, bringing it to <strong>0.04E</strong>. Instrumentation shows that the transpose is just 1% of the runtime, and the multiply 99%.</p><h2>3. SIMD!</h2><p>Next let&#8217;s try some SIMD. I&#8217;m on an Apple M1 chip, which is ARM, so we&#8217;re looking at the <a href="https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(NEON)">Neon</a> instruction set. Neon allows us to do loads, adds, and multiplies of four f32s with one instruction, as well as a bunch of other stuff that we won&#8217;t get into here<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>. As long as the chip has enough floating point hardware, this should allow us to speed up our matmuls by a factor of 4.</p><p>To understand the code sample, let&#8217;s go through some Neon basics. A float32x4_t is Neon&#8217;s C type for a 128-bit vector of four f32s. We can put them in variables as normal, and the compiler will make sure to use the vector registers instead of the normal ones. vmulq_f32 and vaddq_f32 each take two float32x4_ts and produce the elementwise product and sum of the two vectors, respectively. So vmulq_f32({1,2,3,4}, {5,6,7,8}) &#8594; {5,12,21,32}, and vaddq_f32({1,2,3,4}, {5,6,7,8}) &#8594; {6,8,10,12}. vaddvq_f32 takes a float32x4_t and adds the component f32s together, producing a single f32 sum.</p><pre><code>#include &lt;arm_neon.h&gt;

void matmul_1(RowMatrix &amp;C, RowMatrix &amp;A, RowMatrix &amp;B) {
  RowMatrix BB(B.cols, B.rows);
  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      BB.set(j, i, B.get(i, j));
    }
  }

  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      float32x4_t acc = {};
      for (size_t k = 0; k &lt; A.cols; k += 4) {
        float32x4_t *ap = (float32x4_t *)(A.values  + A.cols  * i + k);
        float32x4_t *bp = (float32x4_t *)(BB.values + BB.cols * j + k);
        float32x4_t product = vmulq_f32(*ap, *bp);
        acc = vaddq_f32(acc, product);
      }
      C.set(i, j, vaddvq_f32(acc));
    }
  }
}</code></pre><p>I&#8217;ll note here that this implementation assumes the dimensions of your matrices are divisible by 4. It&#8217;s not hard to extend the matrix implementation to make sure that this is always true internally by padding the edges of the matrix with zeros. For brevity, I won&#8217;t bother to do that in this post.</p><p>Using Neon gives us a <strong>4.5x</strong> speedup, bringing us to <strong>0.18E</strong>. I&#8217;m not sure how we do better than 4x there. If you have an idea, I&#8217;d be eager to hear about it in the comments.</p><h2>4. Loop unrolling</h2><p>I tried a few things next, none of which improved the performance: moving the pointer computation outside the k-loop; incrementing the pointer instead of issuing a p[k]; using fused multiply-add in the form of vfmaq_f32. The next improvement came from a little loop unrolling:</p><pre><code>void matmul_6(RowMatrix &amp;C, RowMatrix &amp;A, RowMatrix &amp;B) {
  RowMatrix BB(B.cols, B.rows);
  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      BB.set(j, i, B.get(i, j));
    }
  }

  for (size_t i = 0; i &lt; C.rows; i++) {
    for (size_t j = 0; j &lt; C.cols; j++) {
      float32x4_t acc_1 = {};
      float32x4_t acc_2 = {};
      float32x4_t acc_3 = {};
      float32x4_t acc_4 = {};
      float32x4_t *ap = (float32x4_t *)(A.values + A.cols * i);
      float32x4_t *bp = (float32x4_t *)(BB.values + BB.cols * j);
      for (size_t k = 0; k &lt; A.cols; k += 16) {
        acc_1 = vaddq_f32(acc_1, vmulq_f32(*(ap++), *(bp++)));
        acc_2 = vaddq_f32(acc_2, vmulq_f32(*(ap++), *(bp++)));
        acc_3 = vaddq_f32(acc_3, vmulq_f32(*(ap++), *(bp++)));
        acc_4 = vaddq_f32(acc_4, vmulq_f32(*(ap++), *(bp++)));
      }
      C.set(
        i, j,
        vaddvq_f32(acc_1) + vaddvq_f32(acc_2) +
        vaddvq_f32(acc_3) + vaddvq_f32(acc_4)
      );
    }
  }
}</code></pre><p>This bumped us up by <strong>1.8x</strong>, landing us at <strong>0.32E</strong>.</p><p>Loop unrolling like this generally helps improve performance by reducing the number of loop instructions to be executed and allowing more loop iterations to run in parallel. Exactly how many times to unroll is a priori a mystery; profile on your target platform to find the right number. For my machine, 4 hit the sweet spot; 2 or 8 were both slower.</p><p>Also slower was using f32 accumulators instead of the float32x4 accumulators. I guess the vector reduce vaddvq_f32 is slower than the vector add vaddq_f32.</p><h2>5. Apple Silicon AMX</h2><p>The next big idea is to use a newer, bigger form of SIMD. Apple Silicon has an undocumented instruction set known as AMX, and <a href="https://github.com/corsix/amx">brilliantly reverse-engineered by Peter Cawley (corsix@)</a>. I&#8217;ll be using <a href="https://github.com/corsix/amx/blob/main/aarch64.h">his header file</a> to get access to AMX intrinsics throughout this post. AMX gives you enormous 512-bit vector registers for operands and lets you drive a huge amount of floating point hardware to do a 16x16 vector outer product with a single instruction. Bram Wasti has some great visuals to illustrate how bonkers huge these registers are compared to Neon in <a href="https://jott.live/markdown/1.5tflop_m1">his post on jott.live</a>.</p><p>The idea then is to rearrange our matrix multiplication to be a bunch of outer products. This takes a couple of insights. The first one is that a sub-block C(a:b, c:d) = (AB)(a:b, c:d) = A(a:b, :) * B(:, c:d). The second is that any matrix multiplication AB can be factored as the sum of the outer products of matching rows of A and columns of B. Combining these two insights, we can compute a 16x16 block of our result matrix C by finding the right 16 columns of A and rows of B, and then iterating along the k-axis computing outer products of pairs of 16-float vectors.</p><pre><code>#include "amx/aarch64.h";

inline void transpose(RowMatrix &amp;dst, RowMatrix &amp;src) {
  for (size_t row = 0; row &lt; src.rows; row++) {
    for (size_t col = 0; col &lt; src.cols; col++) {
      dst.set(col, row, src.get(row, col));
    }
  }
}

void matmul_amx_1(RowMatrix &amp;C, RowMatrix &amp;A, RowMatrix &amp;B) {
  RowMatrix AA(A.cols, A.rows);
  transpose(AA, A);
  RowMatrix CC(C.cols, C.rows);

  // Enable AMX instructions.
  // Have to do this or the program will crash.
  AMX_SET();
  // Loop over each 16x16 block in C to compute it.
  for (size_t block_row = 0; block_row &lt; C.rows; block_row += 16) {
    for (size_t block_col = 0; block_col &lt; C.cols; block_col += 16) {
      // Only set for k == 0
      // to reset the matrix-accumulator Z.
      u64 reset_z = 1ull &lt;&lt; 27;

      for (size_t k = 0; k &lt; A.cols; k++) {
        // Load 16 floats from AA into X register 0.
        AMX_LDX((u64)(AA.values + (k+q)*AA.cols + block_row));
        // Load 16 floats from B  into Y register 0.
        AMX_LDY((u64)(B.values  + (k+q)*B.cols  + block_col));

        // if (reset_z) Z = 0;
        // Z += outer_product(X, Y);
        AMX_FMA32(reset_z);

        reset_z = 0;
      }

      // Read the 16x16 floats from the various Z registers
      // into the correct block of CC.
      for (u64 i = 0; i &lt; 16; i++) {
        u64 z_reg = (i * 4ull) &lt;&lt; 56;
        AMX_STZ(z_reg | (u64)(CC.values + (block_col + i)*CC.cols + block_row));
      }
    }
  }
  // Disable AMX instructions.
  // Have to do this because AMX_SET() is not reentrant.
  AMX_CLR();

  transpose(C, CC);
}</code></pre><p>This gives us a huge 10x improvement, bringing us to <strong>3.27E</strong>.</p><h2>6. Bigger blocks, fewer loads</h2><p>We can further improve our utilization of the hardware by doing a 32x32 block of C at once. The advantage here comes from improving the ratio of loads to outer products: previously we did 2 loads to compute 1 outer product, whereas now we do 4 loads to compute 4 outer products. This cuts our program&#8217;s total loads in half, saving memory bandwidth and cutting the runtime.</p><pre><code>void matmul_amx_2(RowMatrix &amp;C, RowMatrix &amp;A, RowMatrix &amp;B) {
  RowMatrix AA(A.cols, A.rows);
  transpose(AA, A);
  RowMatrix CC(C.cols, C.rows);

  AMX_SET();
  size_t BLOCK_SIZE = 32;
  for (size_t block_row = 0; block_row &lt; C.rows; block_row += BLOCK_SIZE) {
    for (size_t block_col = 0; block_col &lt; C.cols; block_col += BLOCK_SIZE) {
      u64 reset_z = 1ull &lt;&lt; 27; // only set for k == 0

      for (size_t k = 0; k &lt; A.cols; k++) {
        // Load 32 floats into X and Y registers 0 and 1.
        f32 *aa_addr = AA.values + k*AA.cols + block_row;
        AMX_LDX((0ull &lt;&lt; 56) | (u64)aa_addr);
        AMX_LDX((1ull &lt;&lt; 56) | (u64)aa_addr + 16);
        f32 *b_addr  = B.values  + k*B.cols  + block_col;
        AMX_LDY((0ull &lt;&lt; 56) | (u64)b_addr);
        AMX_LDY((1ull &lt;&lt; 56) | (u64)b_addr + 16);

        // Do a 32x32 outer product as 4 16x16 outer products:
        // [ X0@Y0  X1@Y0 ]
        // [ X0@Y1  X1@Y1 ]
        AMX_FMA32(reset_z | (0ull &lt;&lt; 20) | (0ull  &lt;&lt; 10) | 0ull);
        AMX_FMA32(reset_z | (1ull &lt;&lt; 20) | (64ull &lt;&lt; 10) | 0ull);
        AMX_FMA32(reset_z | (2ull &lt;&lt; 20) | (0ull  &lt;&lt; 10) | 64ull);
        AMX_FMA32(reset_z | (3ull &lt;&lt; 20) | (64ull &lt;&lt; 10) | 64ull);
        reset_z = 0;
      }

      // Read the 32x32 outer product out of the Z registers.
      for (u64 i = 0; i &lt; 16; i++) {
        u64 reg = i*4ull;
        AMX_STZ(
          load_store_2
          | (reg + 0) &lt;&lt; 56
          | (u64)(CC.values + (block_col + i +  0)*CC.cols + block_row)
        );
        AMX_STZ(
          load_store_2
          | (reg + 0) &lt;&lt; 56
          | (u64)(CC.values + (block_col + i + 16)*CC.cols + block_row)
        );
      }
    }
  }
  AMX_CLR();

  transpose(C, CC);
}</code></pre><p>This gives another <strong>~2x</strong> improvement, for a total of <strong>6.19E</strong>.</p><h2>7. Faster transposes with SIMD</h2><p>When we started we justified ignoring the matrix transpose because it took just 1% of the runtime, whereas the naive multiply took 99%. Over the course of this post we&#8217;ve cut down that multiply by a factor of <strong>&gt;200x</strong>, so it&#8217;s probably time to look at the transpose. Profiling now confirms: our two transposes together are 66% of the runtime.</p><p>We can do a 4x4 transpose with some creative use of Neon byte-juggling instructions.</p><pre><code>inline void transpose_4x4_block(f32 *dst, f32 *src, size_t rows, size_t cols) {
  float32x4_t row0 = vld1q_f32(src + 0*cols); // 0 1 2 3
  float32x4_t row1 = vld1q_f32(src + 1*cols); // 4 5 6 7
  float32x4_t row2 = vld1q_f32(src + 2*cols); // 8 9 a b
  float32x4_t row3 = vld1q_f32(src + 3*cols); // c d e f

  float32x4x2_t mix01 = vtrnq_f32(row0, row1);
  // 0 4 2 6
  // 1 5 3 7
  float32x4x2_t mix23 = vtrnq_f32(row2, row3);
  // 8 c a e
  // 9 d b f

  float32x4_t out0 = vcombine_f32(vget_low_f32(mix01.val[0]), vget_low_f32(mix23.val[0]));
  vst1q_f32(dst + 0*rows, out0); // 0 4 8 c
  float32x4_t out1 = vcombine_f32(vget_low_f32(mix01.val[1]), vget_low_f32(mix23.val[1]));
  vst1q_f32(dst + 1*rows, out1); // 1 5 9 d
  float32x4_t out2 = vcombine_f32(vget_high_f32(mix01.val[0]), vget_high_f32(mix23.val[0]));
  vst1q_f32(dst + 2*rows, out2); // 2 6 a e
  float32x4_t out3 = vcombine_f32(vget_high_f32(mix01.val[1]), vget_high_f32(mix23.val[1]));
  vst1q_f32(dst + 3*rows, out3); // 3 7 b f
}</code></pre><p>Using this as a primitive, we can build up a bigger transpose by walking over the matrix and doing 4x4 block transposes.</p><pre><code>// B = A.transpose()
inline void transpose_4x4(RowMatrix &amp;B, RowMatrix &amp;A) {
  f32 *dst = B.values;
  f32 *src = A.values;
  size_t rows = A.rows;
  size_t cols = A.cols;
  for (size_t j = 0; j &lt; cols; j += 4) {
    for (size_t i = 0; i &lt; rows; i += 4) {
      transpose_4x4_block(dst + j*rows + i, src + i*cols + j, rows, cols);
    }
  }
}</code></pre><p>This speeds up the transposes by a factor of 3x, so that they&#8217;re now just 35% of the runtime of the matmul, giving us a <strong>1.8x</strong> overall speedup and putting us at <strong>11.06E</strong>.</p><h2>8. Transposes with AMX</h2><p>And, one more idea: let&#8217;s do bigger transposes at once by using AMX. The <a href="https://github.com/corsix/amx/blob/main/extr_v.md">AMX_EXTRV</a> instruction treats the Z registers collectively as a square matrix of cells, each holding a few values, and moves a column from Z into a single Y register. By loading rows into Z, moving columns into Y, and then reading those columns out to memory as rows, we can transpose a 16x16 block of f32s with 48 instructions: 16 loads, 16 moves, and 16 stores.</p><pre><code>inline void transpose_16x16_block(f32 *dst, f32 *src, size_t rows, size_t cols) {
  AMX_SET(); {
    for (u64 row = 0; row &lt; 16; row++) {
      u64 z_reg = row*4;
      AMX_LDZ((z_reg &lt;&lt; 56) | (u64)(src + row*cols));
    }

    for (size_t row = 0; row &lt; 16; row++) {
      size_t z_column = row * 4;
      AMX_EXTRY(
        AMX_EXTRV_PLAIN_ZTOY
        | AMX_EXTRV_LANEWIDTH_32BIT
        | (z_column &lt;&lt; 20)
      );
      AMX_STY((u64)(dst + row*cols));
    }
  } AMX_CLR();
}

// transpose_16x16() is then very similar to transpose_4x4(),
// just moving over 16x16 blocks and calling our new kernel.</code></pre><p>This chops our transpose time down by a factor of 4.2x, so that it&#8217;s now just 12% of our total matmul time, improving our total time by <strong>1.36x</strong>, and leaving us at a final <strong>15.03E</strong>.</p><p></p><p>Over the course of this article we took an initial naive implementation of matrix multiplication and incrementally improved its runtime by 500x by improving cache coherency and making use of all the intrinsics available. Our final implementation was 15x faster than Eigen. That was a nice surprise! Eigen makes use of SIMD, but evidently it does not try to use Apple Silicon&#8217;s AMX extensions. It would be interesting to see what it would take to patch Eigen to make use of these extensions when they&#8217;re available.</p><p>I set out on this exploration to learn how fast matmuls work and to try using SIMD intrinsics. I&#8217;m happy to report that I learned a great deal. One more piece of evidence in favor of <a href="https://endler.dev/2025/reinvent-the-wheel/">Matthias Endler&#8217;s recommendation to reinvent the wheel</a>.</p><p>A great thing about this project has been how at every point there are several more threads to pull on to learn more. Some that I&#8217;m left with here at the end:</p><ul><li><p>patch Eigen with to use Apple Silicon AMX</p></li><li><p>repeat the optimization process for sparse matrices</p></li><li><p>translate to x86 SIMD, and explore <a href="https://en.wikipedia.org/wiki/Advanced_Matrix_Extensions">Intel&#8217;s AMX</a></p></li><li><p>adjust the naive code to convince the compiler to auto-vectorize it</p></li><li><p>figure out why that SIMD change gave a 4.5x speedup instead of just 4x</p></li><li><p>do more careful profiling with hardware performance counters to verify or disprove our guesses about why each step helped</p></li><li><p>get hard numbers for the cost + benefit of doing the matmuls on the GPU.</p><ul><li><p>when does it start making sense? when the matrices are large? when you&#8217;ll reuse them some number of times?</p></li></ul></li><li><p>explore some of the further optimizations listed in the <a href="https://en.algorithmica.org/hpc/algorithms/matmul/">Algorithmica HPC post on matmuls</a></p></li></ul><p>Not sure which of these I&#8217;ll try. Until next time!</p><p></p><p>Resources</p><ul><li><p><a href="https://simd.info">simd.info</a></p></li><li><p><a href="https://jott.live/markdown/1.5tflop_m1">How to Get 1.5 TFlops of FP32 Performance on a Single M1 CPU Core</a></p></li><li><p><a href="https://github.com/corsix/amx">@corsix/amx</a></p></li><li><p><a href="https://en.algorithmica.org/hpc/algorithms/matmul/">Algorithmica HPC - Matrix Multiplication</a></p></li><li><p><a href="https://libeigen.gitlab.io/eigen/docs-nightly/TopicInsideEigenExample.html">What happens inside Eigen, on a simple example</a></p></li></ul><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>If you want to find out more about what instructions exist, you can check out either the <a href="https://developer.arm.com/documentation/den0018/a/NEON-and-VFP-Instruction-Summary/List-of-all-NEON-and-VFP-instructions">ARM docs</a> or the <a href="https://simd.info/tag-tree">instrinsics tree at simd.info</a>.</p><p></p></div></div>]]></content:encoded></item><item><title><![CDATA[50x faster parsing of timeseries]]></title><description><![CDATA[or: just what you need, and nothing else]]></description><link>https://zane.sterlings.family/p/just-what-you-need-and-nothing-else</link><guid isPermaLink="false">https://zane.sterlings.family/p/just-what-you-need-and-nothing-else</guid><dc:creator><![CDATA[Zane Sterling]]></dc:creator><pubDate>Tue, 01 Jul 2025 08:14:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HyiI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For the last year and a half at work I&#8217;ve been working on performance optimization of our in-house dashboarding system for timeseries data &#8212; an equivalent of Grafana, if you&#8217;re familiar. Today I&#8217;d like to tell the story of one optimization I made, and how it has changed the way that I think about writing software.</p><p>But first! Since we&#8217;re talking about performance optimization I feel obligated to get up on my soapbox and say: Don&#8217;t try to optimize your code until you&#8217;ve looked at a profiler! Performance optimization is a sharp tool. Don&#8217;t play with it when the lights are out. Okay, down off my soapbox now; let me show you some cool stuff.</p><div><hr></div><p>My goal with this work was to improve the load time of our dashboards. That&#8217;s the time between when you hit enter in browser&#8217;s URL bar, all the way until all the graphs on the page had all the data drawn to the screen.</p><p>After doing some profiling, I&#8217;d discovered that parsing the timeseries data we were getting from the backends took 40% of the total page load time. In one case that parsing was taking 20ms per chart, or ~1000ms for the whole page. The total amount of time would vary depending on the size of the dashboard and amount of data being loaded, but we&#8217;ll use those numbers as a reference for later improvements.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HyiI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HyiI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 424w, https://substackcdn.com/image/fetch/$s_!HyiI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 848w, https://substackcdn.com/image/fetch/$s_!HyiI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!HyiI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HyiI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg" width="710" height="352" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:352,&quot;width&quot;:710,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HyiI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 424w, https://substackcdn.com/image/fetch/$s_!HyiI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 848w, https://substackcdn.com/image/fetch/$s_!HyiI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!HyiI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03ff0a12-aab2-4739-a423-f155ce51247e_710x352.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Depending on your background and your standards for your tools that might sound like a lot of time, or nothing at all. How should we feel about 20ms? To quote Dick Sites:</p><blockquote><p>Someone walks into my office and says &#8220;My program is too slow.&#8221; After a pause, I ask &#8220;How slow should it be?&#8221;</p></blockquote><p>Let&#8217;s do the math. One of our charts is showing 50 timeseries, each of which has 60 points. Each point consists of an 8-byte floating point value and an 8-byte timestamp. In total, then, a chart&#8217;s data must be at least <code>50*60*16B ~= 47KiB</code>. If our wire format were perfectly arranged such that we could just move the data from the response into an array, we would expect to be limited by memory bandwidth. The famous <a href="https://gist.github.com/jboner/2841832">Latency Numbers Every Engineer Should Know</a> by Jeff Dean and Peter Norvig quote 1MB of sequential memory reads as 250&#181;s, so we&#8217;re looking at a best case of <code>250&#181;s / 1MB * 47KiB ~= 10&#181;s</code>. Our real parsing takes 20,000&#181;s instead! That gives us 2000x room for improvement.</p><p>So what the heck are we trying to parse, then? A look at the network tab shows that a single point is encoded as this lovely JSON blob:</p><pre><code>[{
  "3": 3.141592653589793116,
  "1": [{
    "1": "1745311200"
  }]
}]</code></pre><p>Some digging around in the codebase turns up this <a href="https://protobuf.dev">protobuf</a> message definition:</p><pre><code>message Point {
  Timestamp timestamp = 1;
  string string_value = 2;
  float64 float_value = 3;
}

message Timestamp {
  int64 seconds = 1;
  int32 nanos = 2;
}</code></pre><p>Another (internal) tool called JSPB is then producing JSON serializers from these messages. Parsing is handled by a <code>JSON.parse()</code>, followed by the JSPB-generated parser walking the JSON tree to produce an object tree that looks more like the proto messages, followed by our code doing <em>another</em> copy of the data into a third format. There&#8217;s a lot to dislike here!</p><ul><li><p>The point is 53B (minimized), instead of the optimal 16B.</p></li><li><p>Each message is encoded as an array with an object inside of it.</p></li><li><p>There are two nested messages, instead of just one flat one.</p></li><li><p>The <code>int64 seconds</code> field is encoded as a string. This is unfortunately necessary if you&#8217;re putting it in JSON, because the JS number type is a 64-bit float, which can only represent up to 53-bit integers accurately. JSON doesn&#8217;t support bigints.</p></li><li><p>The floating point value is encoded in 20 bytes of ASCII decimal, because JSON, instead of 8 bytes of binary.</p></li></ul><p>We could keep ragging on it, but at this point it&#8217;s clear: <strong>we can do better!</strong></p><p>Let&#8217;s try the simplest possible encoding. As described above each point is an 8B timestamp and an 8B floating point value. We&#8217;ll encode these directly on the wire back-to-back in little endian, so that our &#8220;parser&#8221; can just read them directly. In the header we&#8217;ll put a 2B version number for the format so that we can upgrade it later, a 2B point type to choose between double- or string-valued points, and a 4B count of the number of points in the message. Together that looks like this:</p><pre><code>+------------+------------+-------------------------+
| 2B version | 2B type    | 4B num points           |
+------------+------------+-------------------------+
| 8B timestamp                                      |
| 8B float value                                    |
| ... N times                                       |
+---------------------------------------------------+</code></pre><p>We&#8217;ll also support a version with string-valued points, where the 8B float value is replaced with a 4B string length and 4B string offset into a data block that lives at the end of the message. Including error checking and comments, a JS parser that handles both versions is about 60 lines of code.</p><p>So how did we do? A run in prod shows this is 10x faster when both are compiled and minified, and 30x faster when running in a debug build. Great!</p><p>&#8230;but we can do better.</p><p>We&#8217;re encoding an 8B timestamp for every point. Our timeseries backend guarantees that the data it produces is evenly spaced in time, as long as there are no gaps. We can take advantage of this by encoding only the timestamp of the first point, and the time between consecutive points. We can indicate a gap by inserting points with a value of <code>NaN</code>. Our new format looks like this:</p><pre><code>+------------+------------+-------------------------+
| 2B version | 2B type    | 4B num points           |
+------------+------------+-------------------------+
| 8B start timestamp                                |
| 8B time between points                            |
+---------------------------------------------------+
| 8B float value                                    |
| ... N times                                       |
+---------------------------------------------------+</code></pre><p>This packed format is more efficient for data without gaps. The sparse format is better for data with a lot of gaps. We can get the best of both worlds by having the serializer check on the fly which version would be faster to decode, and encoding to the faster-to-parse format.</p><p>Measuring again, this is now 16x faster than the original when both are compiled and minified, and 50x faster in debug builds.</p><p>There&#8217;s certainly more we could do to improve parsing: NaN-boxing a number of gap points; <a href="https://en.wikipedia.org/wiki/Run-length_encoding">run-length-encoding</a> for timeseries with constant values; adjusting the rest of our frontend code so that we can reduce the number of allocations for our list of points; etc. But we should stop here.</p><p>Our original goal was not to optimize parsing, but to optimize the page load. Now that we&#8217;ve improved parsing by 16x in prod, it&#8217;s no longer a big fraction of the total page load time. We&#8217;re at the point of diminishing returns, and our optimization effort is better spent elsewhere in the system.</p><p>So let&#8217;s celebrate!</p><ul><li><p>Our original page that took 1000ms to parse now takes just 62ms.</p></li><li><p>Parsing the points now takes less time than parsing the rest of the metadata about the timeseries.</p></li><li><p>Where parsing took 40% of the page load before, it now takes just 4%.</p></li></ul><p></p><p>Why is the new format faster? Are there insights that we could apply more generally?</p><p>I have some hypotheses as to why. Each of these is a true statement about the code that would affect the performance, but I&#8217;m not sure what the effect size is in each case.</p><ul><li><p>The new code copies the data just once, instead of three times.</p></li><li><p>The new code does just one allocation per point instead of 7+.</p><ul><li><p>again, would be great to also dodge this allocation</p></li></ul></li><li><p>The new code is MUCH easier to branch predict.</p><ul><li><p>The old code has to do JSON parsing plus a tree walk. The JSON parser has at its core <a href="https://github.com/v8/v8/blob/main/src/json/json-parser.cc#L1901">a switch statement</a> that checks what the next token is. That&#8217;s inherently unpredictable for the CPU!</p></li><li><p>The new code in contrast should give &lt;= 3 branch prediction failures for the whole timeseries, outside of allocations. Those would be when checking whether to parse string values or float values, and at the start and end of the per-point for loop.</p></li></ul></li><li><p>The new wire format is smaller, and so may have better cache locality.</p></li></ul><p>Those are good technical reasons. But I think there&#8217;s a more general reason why the new code performs better: <strong>It does exactly what we need, and nothing more.</strong></p><p>Protobuf and JSPB are great tools. They solve a general, hard problem well:</p><ul><li><p>they auto-generate serializing and parsing code</p></li><li><p>for complex, deeply nested messages</p></li><li><p>where the schema changes often</p></li><li><p>and the serializer and parser might be using different schema versions.</p></li></ul><p>But each of these features has a cost, and in this case we just don&#8217;t need them.</p><ul><li><p>Writing serializing and parsing code once didn&#8217;t cost that much: just ~80loc;</p></li><li><p>points are simple, and don&#8217;t nest;</p></li><li><p>the schema hasn&#8217;t changed in 4-5 years;</p></li><li><p>and given that cadence, we can manage release of new versions manually.</p></li></ul><p></p><p>More broadly, it&#8217;s important to recognize that convergence, ie. applying a common tool to your problem, is a double-edged sword. It has some great, and well-written-about benefits:</p><ul><li><p>many tools will support the common thing</p></li><li><p>there&#8217;s a team working just on that thing</p></li><li><p>etc.</p></li></ul><p>But it has series downsides that are underappreciated in my corner of the tech world:</p><ul><li><p>it rarely does exactly what you need, and adapting it has a cost</p></li><li><p>it often does something else too that you still have to pay for</p></li><li><p>you have to learn how to use it</p></li><li><p>changing its behavior is hard, because you can&#8217;t afford to break other users</p></li><li><p>and your mileage may vary, but often the team working on the tool won&#8217;t fix your bugs and may not accept your patches because you&#8217;re just one user, likely using it in a strange way they didn&#8217;t predict.</p></li></ul><p>Neither approach is a perfect fit for every situation. Like most things in software buy versus build is a choice with tradeoffs that you need to critically evaluate yourself. But please don&#8217;t assume that because someone else wrote it, it&#8217;s the best fit for your problem. Don&#8217;t be afraid to make something new.</p>]]></content:encoded></item></channel></rss>