




    <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
			<channel>
					<title>Tim Wehrle</title>
					<link>https://www.timwehrle.de/blog/?ref=rss</link>
					<description>Posts by Tim Wehrle</description>
					<language>en-US</language>

					
							<copyright>Tim Wehrle</copyright>
					

					

					<pubDate>Tue, 21 Jul 2026 19:05:03 +0000</pubDate>
					<lastBuildDate>Tue, 21 Jul 2026 19:05:03 +0000</lastBuildDate>

					

					<generator>Tim Wehrle</generator>

					
							
									<item>
											<guid isPermaLink="false">news-34</guid>

											<pubDate>
													Mon, 20 Jul 2026 19:30:41 +0000
											</pubDate>

											<title>Which Streaming Service Was That On Again?</title>

											<link>https://www.timwehrle.de/blog/which-streaming-service-was-that-on-again/</link>

											<description></description>

											<content:encoded><![CDATA[<p>I'm a huge movie fan. I'd even call myself a <a href="https://en.wikipedia.org/wiki/Cinephilia" target="_blank" rel="noreferrer">cinephile</a>. The films I enjoy most are the ones that leave me thinking afterwards. What <i>I don't</i> want to think about beforehand is where I can actually watch them. These days, movies are spread across what feels like a hundred different streaming services. I still don't understand how there isn't a better solution for this. Or maybe I just don't want to accept that this is the solution. Either way, I wanted to figure out how we ended up here, so I did some research.</p>
<p>The original promise of streaming was simple. Everything would be available whenever you wanted it. You could sit down in the evening and binge an entire season without waiting a week for the next episode. Well... weekly releases seem to be making a comeback. I've forgotten more than one show simply because I had to wait a week for the next episode. I still remember recording TV shows because otherwise you'd miss them, or waiting until 8:15 p.m. because that's when the big movie of the week started. Today you just lie down in bed, open an app, and watch whatever you're in the mood for. Broadcast schedules don't matter anymore. One of the most annoying things about television was the ad breaks every fifteen minutes. Early streaming didn't have that. You paid for a Netflix subscription and that was it. It was usually cheaper than cable or pay TV too. Whether that's still true today is debatable (I don't know the current prices of cable or pay TV). Back then, one streaming service was enough to watch most of the movies people cared about.</p>
<p>Then everything started to fragment. Over time, it felt like every major studio launched its own service. Then Netflix proved just how profitable streaming subscriptions could be. Instead of licensing their movies to Netflix, studios realized they could keep the content, launch their own platform, and collect the subscription fees themselves. From a business perspective, it made perfect sense. From a viewer's perspective, it was the beginning of the mess. Disney made Disney+, Warner launched (HBO) Max, Paramount created Paramount+, and so on. I remember reading about the Transformers films moving to Paramount+. I ended up binge-watching all of them before they disappeared. Each company wants to keep its own movies and shows exclusive to its own platform. It's what convinces people to subscribe. The downside is that movies disappear from other services once the licensing rights move back to their original owners. And it's not just movies and TV. Sports have become just as fragmented. The Champions League is on one platform, Formula 1 on another, the NBA somewhere else. And even if you're lucky enough to subscribe to the right service, the movie you want might be on Hulu in the US, Disney+ in Germany or simply unavailable where you live.</p>
<p>As a student I (sadly) don't have unlimited money. Three streaming subscriptions at around €8 or €10 each already add up. If you want 4k or need more than one device, that's another extra charge. Then came the ad-supported plans. Subscription growth eventually slowed down, so streaming companies started looking for new ways to increase revenue. The cheaper plans include ads, while the ad-free versions keep getting more expensive. The goal is simple: make the more expensive plan look like the better deal. And sports subscriptions are even worse. If you want to follow everything related to your favorite sport, spending €50 a month isn't unusual. Add regular price increases on top of that, and suddenly streaming isn't the affordable alternative it used to be.</p>
<p>Let's say you've accepted that this is just how streaming works now. Now you have to figure out where your movie actually is. Every app has its own interface, its own search function, and its own way of organizing content. Personally, I've never liked how clunky TV apps often feel. I'm looking at you, Prime. Eventually you find your movie. After it's over, another interesting recommendation pops up, so you save it to your watchlist. Except every platform has its own watchlist. Sure, every company wants you to stay in its own ecosystem. Before you know it, you've got movies saved across six different apps. Video quality isn't consistent either. One service includes 4K, while another only offers HDR or Full HD unless you pay more. And sometimes it's almost ridiculous: you watch the first movie on Disney+, then have to switch to another service just to watch the sequel.</p>
<p>There are more movies available than ever before, yet it's somehow harder to find one to watch. At least for me, it's not unusual to spend twenty minutes scrolling through different apps just to watch a ninety-minute movie. Sometimes, after all that searching, I don't even feel like watching anything anymore. And the recommendation algorithms. I mean, they've suggested some genuinely great movies to me so I don't want to pretend that they're completely useless. But a lot of the time they keep pushing the same popular titles. Smaller films and independent productions rarely get the same visibility.</p>
<p>Ironically, streaming is starting to look a lot like TV again. Ads are back unless you pay for the expensive tier. <a href="https://en.wikipedia.org/wiki/Free_ad-supported_streaming_television" target="_blank" rel="noreferrer">FAST channels</a> with fixed schedules are becoming more common, because they're cheap to operate and generate advertising revenue 24/7. Bundles like Disney+, Hulu and ESPN+ feel a lot like cable TV all over again. Exclusive licensing means certain shows only exist on one platform. And live events, like boxing on Netflix or exclusive sports broadcasts elsewhere, are bringing appointment viewing back.</p>
<p>But it has consequences. Some people end up turning back to piracy. It's not just because they don't want to pay. A lot of them are already paying for several streaming services. The bigger issue is the convenience. Spotify showed that if legal streaming is more convenient than piracy, most people are happy to pay. Illegal platforms usually put everything into one interface. There's no jumping between apps, no wondering who owns the rights this month and regional restrictions often disappear. Of course there's a reason it's called piracy. These sites can disappear overnight and you might get fined, but yeah, you get me.</p>
<p>There are probably a few ways to improve things. Cross-platform search should be standard by now. A shared watchlist across services would help. You can track movies with Letterboxd or one of the other apps, but then you're relying on yet another app to organize your entertainment. Bundled subscriptions where you choose three services for a discounted price could also make things simpler. Those are just a few ideas, but they're probably easier said than done.</p>
<p>Streaming is still great, don't get me wrong. The flexibility is unmatched, and the picture quality has never been better. The problem isn't with streaming itself. It's just that the ecosystem became too fragmented. Streaming solved TV's biggest problems. But over time, it slowly recreated most of them. And that's why I'll probably keep asking myself the same question for a while longer: Wait… which streaming service was that on again?</p>]]></content:encoded>

											
									</item>
							
									<item>
											<guid isPermaLink="false">news-33</guid>

											<pubDate>
													Sun, 12 Jul 2026 14:00:48 +0000
											</pubDate>

											<title>Why I Replay One Song Over and Over</title>

											<link>https://www.timwehrle.de/blog/why-i-replay-one-song-over-and-over/</link>

											<description></description>

											<content:encoded><![CDATA[<p>Lately, since I've started listening to more music again, I've noticed that I almost always end up replaying the same song over and over. I'll find a song I love, listen to it until I can't stand it anymore, and then move on to the next one. That's the cycle. I know I'm not the only person who does this, so I decided to spend some time figuring out why it happens… while listening to the same song for the sixteenth time.</p>
<p>When you hear a new song, your brain immediately starts trying to predict what comes next. Since it doesn't know the structure yet, almost every part of the song is a small surprise. Those surprises activate your brain's reward system, which leads to the release of dopamine. The result is that feeling of excitement that makes you want to hit replay the moment the song ends.</p>
<p>Another reason is something called the <a href="https://en.wikipedia.org/wiki/Mere-exposure_effect" target="_blank" rel="noreferrer">mere-exposure effect</a>. People tend to like things more simply because they become familiar with them. The first listen might even feel confusing. By the fifth listen, though, your brain has started recognizing the patterns, making the song much easier to follow. Of course this differs from song to song, but it's also why (at least for me) my favorite songs are almost never my favorites after the very first listen.</p>
<p>With every replay, your brain notices new details. At first you might only focus on the lead vocal. Then you suddenly hear the bass line. Then the background vocals. Then some tiny production detail you've somehow missed ten times already. Every listen adds another layer to your mental model of the song. You're not just hearing the same song over and over again. You're hearing more and more of it.</p>
<p>Another point on my list is the situation you're in when you hear a song. For me, it could be a song I heard at a festival while my friends and I were having the time of our lives. For someone else, it could be a song they listened to during a breakup or while studying for exams. The song becomes linked to those emotions. Later, hearing it again can bring back parts of that emotional state almost instantly.</p>
<p>But if that's true, why can't I listen to the same song every day forever?</p>
<p>One of the brain's most basic learning processes is habituation. Repeated exposure to the same stimulus reduces the brain's response over time. Your brain simply gets used to the song. It already knows what's coming. As a result the emotional reaction gradually becomes weaker.</p>
<p>There are also other factors. Dopamine isn't released simply because something is enjoyable. It's closely tied to anticipation, learning, prediction errors, and uncertainty. Once you know every note, every lyric, and every transition by heart, there aren't many surprises left. The brain has very little left to learn, so the reward signal becomes smaller.</p>
<p>The same thing happens with positive experiences in general. Think about buying a new phone or going on vacation. Eventually those things stop feeling extraordinary because we adapt to them. Our baseline shifts. What once felt exciting eventually feels normal. This phenomenon is called <a href="https://en.wikipedia.org/wiki/Hedonic_treadmill" target="_blank" rel="noreferrer">hedonic adaptation</a>.</p>
<p>So if you want your brain to experience that reward again, the best thing you can do is take a break. Try not to listen to the song for a while, maybe a few weeks or even months. During that time, you'll forget some of the small details as well, your predictions won't be on the spot, and those emotional connections might feel new and fresh again. The song feels a little uncertain again. It probably won't sound like the very first listen but it'll sound better than it did after the twentieth replay in a row, trust me. At least for me, when I go back and listen to my most listened to songs from past years, I always find one that I forgot and start loving again.</p>
<p>But why do some songs lose their "magic" after twenty listens while others stay exciting after a hundred?</p>
<p>As I mentioned earlier, not every song works the same way. Research suggests that the more musical layers, harmonic complexity, emotional depth, evolving dynamics, and subtle details a song contains, the longer it tends to stay rewarding. Simpler songs can deliver a huge initial dopamine hit, but they often run out of surprises much faster. So keep this in mind before clicking the "Skip back" key.</p>]]></content:encoded>

											
									</item>
							
									<item>
											<guid isPermaLink="false">news-31</guid>

											<pubDate>
													Fri, 19 Jun 2026 18:47:31 +0000
											</pubDate>

											<title>I Stored a Website in a Favicon</title>

											<link>https://www.timwehrle.de/blog/i-stored-a-website-in-a-favicon/</link>

											<description></description>

											<content:encoded><![CDATA[<p>A while ago I wrote about storing two bytes inside my mouse's DPI register. It wasn't useful. It wasn't practical. But it did something unfortunate to my brain. Once you've successfully hidden data somewhere it doesn't belong, you start looking at everything as potential storage.</p>
<p>A monitor is storage.</p>
<p>A keyboard is storage.</p>
<p>A BIOS splash screen is (maybe) storage.</p>
<p>A favicon is storage.</p>
<p>And yes, here we are.</p>
<p>Every website has a favicon. It's that little icon in your browser tab. Usually you upload it once and then never think about it again. But. A favicon is just an image. An image is just pixels. And pixels are just bytes.</p>
<p>So of course I wondered if I could store something inside one.</p>
<h2>The idea</h2>
<p>My first thought was steganography.&nbsp;</p>
<p>Steganography is basically about hiding data in an image without making it obvious. You take a perfect normal photograph and modify a few bits so it secretly contains a message.</p>
<p>The favicon itself (at least in my demo) doesn't need to look like an icon. It could become pure storage.</p>
<p>Every pixel has red, green and blue values. That's three bytes. If I wanted to store text, I could just take the UTF-8 bytes of the text and write them directly into the RGB channels.</p>
<p>The browser doesn't care what those bytes represent. To the browser they're colors. To me in this case they're HTML.</p>
<h2>Building a favicon website</h2>
<p>I started with a tiny HTML payload:</p>
<p></p><pre><code class="language-markup">&lt;h1&gt;Website in a Favicon&lt;/h1&gt; 
&lt;p&gt;
	Everything you're reading right now was decoded from favicon pixels.
&lt;/p&gt;</code></pre><p>
</p>
<p>The process is pretty straightforward.</p>
<p>First I convert the HTML into bytes using <code>TextEncoder</code>.</p>
<p>Then I prepend four bytes containing the payload length.</p>
<p>The length header is important because the image itself may contain unused pixels at the end. If there's no length value, there's no way to know where the real payload stops.</p>
<p>Then I just start filling pixels: the first byte becomes the red channel of the first pixel, the second becomes the green, the third becomes blue, and then the next pixel, and the next, and the next, until the whole HTML document exists as colored pixels. The result looks like visual noise.</p>
<h2>Very small</h2>
<p>What surprised me most wasn't that it worked, to be honest. It was how small the resulting image was.</p>
<p>The payload ended up being 208 bytes.</p>
<p>Adding the 4-byte header brings the total to 212 bytes.</p>
<p>Since every pixel stores three bytes, I needed:</p><ul><li data-list-item-id="e79cd1f956c2e09c552a9eba3c143b47a">212 bytes total</li><li data-list-item-id="e5776d44d6e6a190c1c75b695366af5a8">71 pixels</li><li data-list-item-id="e832ca7b05b9108449d222c0dd4e692f1">A square image large enough to contain them</li></ul><p>
</p>
<p>The smallest square that works is 9x9 pixels.</p>
<p>That's only 81 pixels.</p>
<p>The final stats looked like this:</p><ul><li data-list-item-id="e0e9c900397c047fcfc187c4e176e3c86">Payload: 208 bytes</li><li data-list-item-id="e2d7f982055971d6e5a148e52e35268b2">Image size: 9x9 pixels</li><li data-list-item-id="efa2a642f678e2c1e416d97c07b77d1d9">Capacity: 239 bytes</li><li data-list-item-id="e7f4cfa46278e3c1d03417240fd7c5929">Used: 87%</li></ul><p>
</p>
<p>Somehow a whole little website (okayy, html with some styling) fits inside an image that's smaller than the usual favicon.</p>
<h2>Reading the website back out</h2>
<p>Storing data is only half the problem. The other half is getting it back.</p>
<p>Browsers already have everything needed for this.</p><ol><li data-list-item-id="ef63ceb13364f475baa289d44777b0d7b">The favicon gets loaded as image.</li><li data-list-item-id="e0cdc4ee8ced6fcbd74a45545ef7662dc">The image gets drawn onto a canvas.</li><li data-list-item-id="e78f4117b1c70b71cfc1e136d7e91b022">The canvas API lets JavaScript read every pixel.</li></ol><p>
</p>
<p>Once I have the pixel data, I simply reverse the process.</p><ol><li data-list-item-id="e15bed40d2b83d542c34df753bbd04070">Read the RGB values.</li><li data-list-item-id="e48327da32d226284fc945655cf88ec2e">Reconstruct the byte array.</li><li data-list-item-id="e6cd2a03f841aa979e4306dbe1628507a">Read the first four bytes to determine the payload length.</li><li data-list-item-id="e2e9eff9afa5d17169b222ec577b2fce9">Extract the payload.</li><li data-list-item-id="e5fa53b42d0b05ad15145e7bc93f5562b">Decode the UTF-8 text.</li></ol><p>
</p>
<p>At that point I have the original HTML again.</p>
<p>The browser read a website out of its own favicon.</p>
<h2>The important catch</h2>
<p>The favicon doesn't actually contain the whole website itself.</p>
<p>It contains the content of a website.</p>
<p>You still need a tiny bootstrap loader to decode the image.</p>
<p>Without the JavaScript the favicon is just a PNG (which contains your website content).</p>
<p>For showing this scenario the site includes a "Render Website" button. It reads the favicon, decodes the HTML, and replaces the page with the reconstructed content.</p>
<h2>Is this useful?</h2>
<p>No, of course not.</p>
<p>The amount of data you can store is tiny. The page needs JavaScript to bootstrap itself. There are dozens of better ways to distribute a small HTML document.</p>
<p>But at the end its about testing the boundaries, right?</p>
<p>A favicon feels like a very specific thing. It's supposed to be an icon.</p>
<p>But at the end it can just be a PNG.</p>
<p>And a PNG file is basically just bytes.</p>
<p>And this is probably the smallest website I've built…</p>
<h2>Alternative approaches</h2><ul><li data-list-item-id="e8fb9e5dcb52858d7d06b29538d144fed">Store markup directly in SVG favicon and read it on page load.</li><li data-list-item-id="ef853c5b95070e140e7c63dd3fea8d4ad">Use PNG comment chunks like tEXt, zTXt and iTXt.</li><li data-list-item-id="e3818709cdee2aac2f17cb4b678f99274">Use the ico file format since it allows multiple icons with different resolutions.</li></ul><p>
</p>
<p>Here is the link to the site: <a href="https://www.timwehrle.de/labs/favicon-site/" target="_blank">https://www.timwehrle.de/labs/favicon-site/</a></p>
<p>And if you want to see how it works: <a href="https://github.com/timwehrle/favicon" target="_blank" rel="noreferrer">https://github.com/timwehrle/favicon</a></p>]]></content:encoded>

											
									</item>
							
									<item>
											<guid isPermaLink="false">news-30</guid>

											<pubDate>
													Wed, 17 Jun 2026 15:11:36 +0000
											</pubDate>

											<title>Maybe Shadow IT Is a Symptom</title>

											<link>https://www.timwehrle.de/blog/maybe-shadow-it-is-a-symptom/</link>

											<description></description>

											<content:encoded><![CDATA[<p>I recently heard from a colleague who built a small web application with Google AI Studio.</p>
<p>It wasn't a big project. He was annoyed by a repetitive task, so he spent a few hours building a tool that made his workflow much easier.</p>
<p>To be honest, I liked it.</p>
<p>It's satisfying to see someone remove a piece of friction from their day instead of just complaining about it.</p>
<p>The funny thing is, he wanted to share the tool with a colleague.</p>
<p>So he sent him the source code.</p>
<p>He was happy with that. His colleague would open it and everything would work just like it did on his machine, with no extra steps.&nbsp;</p>
<p>Of course, it didn't.</p>
<p>I don't think he had really thought about what was happening behind the scenes. I mean, why would he? The app worked. The problem was solved. That's usually where people stop thinking about software.</p>
<p>He realized that there's a difference between software that works for one person and software that works for multiple people. Yeah, for people who know what they're doing, this was pretty easy to see coming.</p>
<p>I liked his approach to the problem, though.</p>
<p>A few hours earlier, he was struggling.</p>
<p>A few hours later, he had found a solution.</p>
<p>The more I thought about it, the more it reminded me of discussions about shadow IT. For those who aren't tech-savvy, it's basically a term companies use when employees start using their own software, tools, or processes without going through the IT department.</p>
<p>Which, if I'm honest, is pretty much what my colleague had done.</p>
<p>People often ask why employees keep building their own tools, spreadsheets, scripts, databases, and now AI-generated applications.</p>
<p>But I'm not sure that's the most interesting question.</p>
<p>Most people don't wake up wanting to maintain software. They don't dream about version control, backups, access management, support requests, compliance reviews, or documentation. Well, maybe someone dreams about documentation, but I've never met them.</p>
<p>People usually just want to get their work done.</p>
<p>Some people will (understandably) do it themselves if it seems faster than going through the official process. I'm not a fan either. It's frustrating to wait for a simple process to finish (and then there are 20 more of them).</p>
<p>That doesn't mean the IT department is wrong, though.</p>
<p>As soon as my colleague tried to share his application, he ran into the kind of problem IT departments are supposed to solve.</p>
<p>How does someone install it?</p>
<p>Where does it run?</p>
<p>What happens when it breaks?</p>
<p>Who maintains it?</p>
<p>What happens when the person who built it leaves?</p>
<p>None of this was an issue when it was just his personal tool. But as soon as someone else wanted to use it, the answers suddenly mattered a lot.</p>
<p>That's probably why I have a hard time seeing shadow IT as the real problem.</p>
<p>It often feels more like a symptom.</p>
<p>People don't build their own solutions because they secretly want to become software developers.</p>
<p>Most of the time they build them because waiting feels more expensive. Maybe not financially. But in terms of time, frustration and actually getting work done.</p>
<p>The department wants a solution now.</p>
<p>Meanwhile, IT wants security, governance, maintenance, support, backups, access controls, and all the other boring things that only become important after something is successful.</p>
<p>Both sides are acting rationally.</p>
<p>They're just focusing on different things.</p>
<p>One side is trying to solve today's problem.</p>
<p>The other is trying to make sure today's solution doesn't become next year's problem.</p>
<p>Maybe that's why shadow IT never really goes away.</p>]]></content:encoded>

											
									</item>
							
									<item>
											<guid isPermaLink="false">news-29</guid>

											<pubDate>
													Sat, 13 Jun 2026 12:47:32 +0000
											</pubDate>

											<title>Good Work Doesn&#039;t Speak for Itself</title>

											<link>https://www.timwehrle.de/blog/good-work-doesnt-speak-for-itself/</link>

											<description></description>

											<content:encoded><![CDATA[<p>Some time ago, a colleague from another team asked me if I was actually good at my job. The question caught me off guard and I don't remember what I answered.</p>
<p>It feels uncomfortable to me to say that I'm good at my job. It feels like bragging. It makes it seem like I'm trying to make myself sound more important than I am. At the same time, it wouldn't have been honest to talk down my work. I stood there, realizing that a simple question didn't have a simple answer.</p>
<p>I kept (over-)thinking about it for a while afterwards.</p>
<p>Not about the question itself, but about why he had to ask it in the first place.</p>
<p>My colleague works on a different team. He doesn't see what I work on every day. He doesn't see the problems I solve. He doesn't see the decisions I make or the things I've built. So how would he know if I'm good at my job? On top of that, he obviously has no idea what I actually do all day.</p>
<p>The answer is pretty obvious. If I never talk about it, there's no way he could know.</p>
<p>I think many people know this feeling. You want to do good work, but you don't want to constantly talk about it. You don't want to put every small achievement on display. You don't want to be the person in every meeting bragging about their latest accomplishment. I wouldn't enjoy being that person either.</p>
<p>So you just work and work.</p>
<p>You do your tasks. You solve problems. You help colleagues. You make sure things keep working, and often before they stop working.</p>
<p>At some point, you realize that a large part of that work is basically invisible to everyone else.</p>
<p>For a long time, I thought that good work speaks for itself. It's a nice idea. If you're good at your job, the right people will notice.</p>
<p>But this only works sometimes in small teams.</p>
<p>The bigger an organization gets, though, the less true it becomes.</p>
<p>CEOs don't see eight hours of your workday (and they don't have to care, to be honest). Department heads don't either. Most of the time, they don't see even 1% of it. They only see the results (and that's probably the only thing they want to see). They see the final output of a long chain of work.</p>
<p>All the small decisions you made on the way usually disappear.</p>
<p>Nobody sees the bug you caught in time. No one sees the discussion that prevented a problem. No one sees the hour you spent simplifying something complicated. No one sees the ten things that didn't go wrong because you were paying attention.</p>
<p>And that's not even criticism.</p>
<p>It would be impossible to see everything.</p>
<p>In a company with hundreds or thousands of employees it's impossible to keep track of everyone's work. Sometimes I can't even keep track of my own work. Instead, people form their opinions based on what they can see and hear.</p>
<p>In that scenario, it's not only what you do that matters. It also matters what others know about your work.</p>
<p>In my opinion, that idea just feels wrong.</p>
<p>The work itself should matter, not the story around it.</p>
<p>Eventually, though, I had to admit that the two are connected.</p>
<p>If you never talk about your work you can't really be surprised when people know very little (or nothing) about it.</p>
<p>That doesn't mean you have to become a self-promoter. It doesn't mean celebrating every completed task or constantly marketing yourself.</p>
<p>There's a lot of space between bragging and being completely invisible.</p>
<p>You can talk about what you're working on. You can explain the problems you've solved. You can share things that nobody else gets to see.</p>
<p>Maybe that's actually part of the job even if many of us (or just me) don't like it.</p>
<p>The interesting thing is that we usually notice bragging much faster in ourselves than in other people. When someone explains what they've been working on in an easy-to-understand way, I usually don't think they're showing off. Well, it depends on how they say it, but usually I just think: Oh, that's interesting. I didn't know that.</p>
<p>It still feels different when it's me.</p>
<p>That said, I suppose you sometimes have to step outside your comfort zone and talk to people about your work.</p>]]></content:encoded>

											
									</item>
							
									<item>
											<guid isPermaLink="false">news-28</guid>

											<pubDate>
													Tue, 09 Jun 2026 15:47:20 +0000
											</pubDate>

											<title>The Microservice Overdose</title>

											<link>https://www.timwehrle.de/blog/the-microservice-overdose/</link>

											<description></description>

											<content:encoded><![CDATA[<p>Today I saw a familiar little software moment: someone suggested introducing another microservice.</p>
<p>It had its purpose and I would've made the same choice, maybe. But I recognised a pattern where systems introduce a new responsibility, and then, "new responsibility" started sounding suspiciously like "new service".</p>
<p>I like microservices. Which is probably why this stuck with me. Once a team has a few of them, every new idea begins to orbit the architecture. Need a feature? Service. Need a small extension point? Service. Need to store three values and call an API twice? Obviously, service. Preferably with its own repository, wait… We already have a monorepo. Then just a new folder, pipeline and a name that sounds like a Marvel character. I'm looking at you, <a href="https://www.youtube.com/watch?v=y8OnoxKotPQ" target="_blank" rel="noreferrer">Galactus</a>.</p>
<p>The uncomfortable part is that microservices are not bad. That would be too easy. They solve real problems: independent scaling, isolated deployments, clearer ownership, fault boundaries. At the right size, with the right team, under the right pressure, they make sense.</p>
<p>But sometimes we seem to skip the boring question: do we actually need this?</p>
<p>A modular component could be enough. A clean boundary inside the existing app could be enough. A plugin-style extension point could be enough. Build it so it can grow later, sure. But maybe don't immediately give it its own infrastructure passport and send it into production as a tiny nation-state.</p>
<p>There is this fantasy that everything will scale massively one day. The classic "when we have millions of users" argument. Which is technically possible, in the same way that I am technically one viral GitHub repo away from becoming a conference keynote speaker. Possible, yes. Planning your entire architecture around it today, questionable.</p>
<p>Modern software has a tendency to confuse seriousness with complexity. If a thing has message queues, distributed tracing, and twelve dashboards, it feels important. A simple module feels almost suspicious.</p>
<p>Maybe that is what bothers me: overengineering often looks responsible from a distance. Nobody gets blamed for choosing the architecture that sounds scalable. "We made it a microservice" has a professional smell to it. "We kept it simple because the problem was simple" sounds almost naive, even when it is probably the more thoughtful decision.</p>
<p>Still, I get the temptation. Microservices are satisfying. They create neat boxes. They promise separation.</p>
<p>Maybe the better question is not "Should this be a microservice?" but "What pain are we trying to avoid?". If the pain is deployment coupling, team ownership, scaling, or reliability boundaries, then maybe yes. If the pain is simply that the codebase feels a bit untidy, maybe the answer is a refactor, not a new distributed system. And yes, I hate refactors as well.</p>
<p>I did not learn anything new today. More like I re-noticed something old: software usually gets complicated one reasonable decision at a time.</p>]]></content:encoded>

											
									</item>
							
									<item>
											<guid isPermaLink="false">news-24</guid>

											<pubDate>
													Sat, 21 Mar 2026 20:09:52 +0000
											</pubDate>

											<title>What if I stored data in my mouse</title>

											<link>https://www.timwehrle.de/blog/what-if-i-stored-data-in-my-mouse/</link>

											<description></description>

											<content:encoded><![CDATA[<p>It started with a dumb idea.&nbsp;</p>
<p>I have a Logitech MX Vertical, which travels between my home machine, work laptop and other devices constantly. At some point I looked at it and thought: this thing has a flash memory. It has to, otherwise how does it remember the DPI setting between plugs. So what if I stored something in it?</p>
<p>Yea, I was bored.</p>
<p>The idea was to treat the mouse like a little USB drive. Since it physically travels between computers, it could technically carry data with it.</p>
<p>Logitech mice communicate using something called HID++, a protocol that they built on top of standard USB HID. It's partially documented by Logitech themselves and partly reverse engineered by the open source community. I wrote a Rust tool to enumerate every feature the mouse exposes. There are 33.</p>
<p>HID++ 2.0 works like this: every device has a feature table. Each entry maps a stable feature ID to a device-specific index. The ID is consistent across all Logitech devices. The index varies per model. So you first ask the device "where is feature <code>0x2201</code>?" and it tells you "index <code>0x12</code> on this mouse". Then you use that index for all subsequent calls. Every call is a short packet: report ID, device index, feature index, function ID, and up to 3 bytes of params. The response comes back in the same shape.</p>
<p>Most are undocumented. There are names like <code>EnableHiddenFeatures</code> and <code>TemplateBytesNVS</code>. That second one sounds exactly like what I wanted: non-volatile storage, index <code>0x1eb0</code>. I couldn't find any info on it in the docs, but I'm guessing it's something to do with configuration blobs for macros or button templates. Unfortunately, the mouse wouldn't respond to anything, so I couldn't find out.</p>
<p>I spent a while on <code>0x1c00</code> (the <code>PersistentRemappableAction</code>) first. Six slots, read/write flags, and so on. Turns out macOS's <code>IOHIDManager</code> blocks the longer HID++ report format you need to actually write to it. The OS just drops the packets. There was no error, no explanation, nothing. I found this out after writing a pile of probe code and staring at empty responses for longer than I'd like to admit. Yes, there are ways around <code>IOHIDManager</code>, like talking directly to the USB device via IOKit, but that's a different story.</p>
<p>Then I looked at the device name register. It looked promising and the write calls were accepted. But the mouse kept saying "MX Vertical" regardless of what I sent. It was just ghosting me.</p>
<p>What did worked was the DPI register (<code>0x2201</code>).</p>
<p>You can read two values from it:</p><ul><li data-list-item-id="e15a43fa00e897b31dd8cc5eac968b7bc">the current (active) DPI</li><li data-list-item-id="e264454f6384c5cf7af87518225607a37">a fallback/default DPI</li></ul><p>
</p>
<p>Setting DPI works via function <code>0x03</code>, and reading via <code>0x02</code>.</p>
<p>Here's the important (and updated) part:</p><ul><li data-list-item-id="e8de0826d2fad00c6b87a24f25c18e6ff">Writing DPI only updates the active DPI</li><li data-list-item-id="ec2ec9defc977b114e6cc771c29110843">The fallback/default DPI remains unchanged</li><li data-list-item-id="e34cba3a2369899701515309eb03b788a">On power cycles, the device restores the fallback value</li></ul><p>
</p>
<p>So while the DPI register accepts arbitrary <code>u16</code> values, they are not persisted across power cycles.</p>
<p>However, there is one interesting property:</p>
<p>As long as the mouse stays powered, the value survives switching computers. You can write a value on one device, move the receiver to another, and read it back.</p>
<p>So the "storage" is only:</p>
<p><i>2 bytes of cross-computer, session-scoped storage (while the mouse remains powered)</i></p>
<p>So the original idea: "using DPI as persistent storage" doesn't actually hold up. The only solution would be to "cache" and rewrite it on the mouse on power cycles, but that would defeat the idea.</p>
<p>I also tested a range of other features and write paths (including <code>0x1e</code>, <code>0x1f</code>, and several <code>0x18xx</code> config features). None of them affected the fallback DPI or exposed writeable persistent storage.</p>
<p>At this point, it looks like the default DPI is either:</p><ul><li data-list-item-id="ef5797a97e014efbcfde66cdda8de041a">stored in a part of firmware not exposed via HID++, or</li><li data-list-item-id="eaa05b7540d77c14767560dba2b1afd06">only writeable through vendor tooling / signed commands</li></ul><p>
</p>
<p>Even though the original goal didn't work out, the process was still worth it.</p>
<p>I learned how HID++ works. I learned how macOS manages HID devices at kernel level and where it draws lines. I learned that "feature table" and "feature index" are different things and that the IFeatureSet reverse lookup is apparently broken on this device. I learned that the device name register will politely accept your writes and then completely ignore them, which is a deeply relatable response.</p>
<p>None of the knowledge came from reading docs. The Logitech hidpp20 docs exist, but half the features are missing, so I had to try it out. It all was trial and error until it worked. But maybe don't do that with your BIOS.</p>
<p>The result is objectively useless. No hidden storage, no secret USB drive in a mouse. But that wasn't really the point. The point was seeing how far I could get.</p>
<p>The 2 bytes are still there. You just have to keep the mouse alive…</p>
<p>I will dig deeper tho, because the default DPI has to be somewhere in my mouse.</p>
<p>Code is here if you want to explore it yourself: <a href="https://github.com/timwehrle/mouse-fs" target="_blank" rel="noreferrer">https://github.com/timwehrle/mouse-fs</a>.</p>]]></content:encoded>

											
									</item>
							
					
			</channel>
	</rss>

