<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tech on Tim&#39;s log</title>
    <link>https://luu.is/en/tags/tech/</link>
    <description>Recent content in Tech on Tim&#39;s log</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>© 2026 Hi, I&#39;m Tim</copyright>
    <lastBuildDate>Thu, 11 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://luu.is/en/tags/tech/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>How we accidentally poisoned our sister brand&#39;s ad campaigns with a rogue tracking tag</title>
      <link>https://luu.is/en/posts/rogue-tracking-tag-sister-brand-ads/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/rogue-tracking-tag-sister-brand-ads/</guid>
      <description>&lt;p&gt;I was sitting with a lukewarm cup of coffee on a Tuesday morning, running what I figured would be a boring, 10-minute tag audit on our main e-commerce site. Then Google Tag Assistant flagged something that made no sense. Alongside our own Google Ads tag, a second tag with the ID &lt;code&gt;AW-987654321&lt;/code&gt; was firing on every single page view.&lt;/p&gt;
&lt;p&gt;That second ID belonged to our sister brand. They are a smaller, lower-priority setup under our corporate umbrella, selling a very similar catalog of products. I hopped over to their domain, loaded their home page, and watched the exact reverse happen: our primary brand&amp;rsquo;s tag, &lt;code&gt;AW-123456789&lt;/code&gt;, was firing over there. Visitors looking at our high-margin main line were being quietly tagged for our cheaper secondary line, and vice versa. I had that familiar cold-sweat moment where you assume your browser cache is lying to you; I cleared everything, opened 3 incognito windows, and watched the exact same thing happen.&lt;/p&gt;</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/rogue-tracking-tag-sister-brand-ads/cover.png" />
    </item>
    
    <item>
      <title>When Plesk traffic doesn&#39;t match Analytics: finding a WordPress compromise</title>
      <link>https://luu.is/en/posts/wordpress-compromise-plesk-traffic-analytics-discrepancy/</link>
      <pubDate>Mon, 08 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/wordpress-compromise-plesk-traffic-analytics-discrepancy/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;The number that started it 
    &lt;div id=&#34;the-number-that-started-it&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700&#34;
            style=&#34;text-decoration-line: none !important;&#34; href=&#34;#the-number-that-started-it&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;





    
    
    &lt;picture&gt;
        &lt;source srcset=&#34;https://luu.is/en/posts/wordpress-compromise-plesk-traffic-analytics-discrepancy/section-01_hu_2ad6845b19630141.webp&#34; type=&#34;image/webp&#34;&gt;
        &lt;img src=&#34;https://luu.is/en/posts/wordpress-compromise-plesk-traffic-analytics-discrepancy/section-01.png&#34; alt=&#34;Illustration for The number that started it&#34; &gt;
    &lt;/picture&gt;


Plesk was showing &lt;code&gt;7294.2 MB/month&lt;/code&gt; of traffic for one of our internal WordPress sites — which would have made it one of the busiest domains on the server, except Google Analytics and Cloudflare both said the site was nearly dead. A handful of real visits, nothing more.&lt;/p&gt;</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/wordpress-compromise-plesk-traffic-analytics-discrepancy/cover.png" />
    </item>
    
    <item>
      <title>Your .gitignore won&#39;t save you from AI coding assistants</title>
      <link>https://luu.is/en/posts/securing-codebases-ai-agents/</link>
      <pubDate>Sat, 30 May 2026 17:30:01 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/securing-codebases-ai-agents/</guid>
      <description>AI coding agents are runtimes with root-level terminal access. If you rely on file-level ignore lists to protect your secrets, you are one bad stack trace away from leaking live production credentials to third-party model providers.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/securing-codebases-ai-agents/cover.png" />
    </item>
    
    <item>
      <title>Stop defaulting to the most powerful model for rule-based tasks</title>
      <link>https://luu.is/en/posts/choosing-the-right-model-size-rule-based-tasks/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/choosing-the-right-model-size-rule-based-tasks/</guid>
      <description>A high-capability model nearly shipped wrong information to real customers — not because it failed, but because it reasoned past a clear policy. The fix was a smaller, more predictable model. Here is what that taught me about model selection.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/choosing-the-right-model-size-rule-based-tasks/cover.png" />
    </item>
    
    <item>
      <title>When you push an AI coding agent too hard, it starts optimizing for the wrong thing</title>
      <link>https://luu.is/en/posts/ai-coding-agent-reward-hacking-anthropic-research/</link>
      <pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/ai-coding-agent-reward-hacking-anthropic-research/</guid>
      <description>Anthropic&amp;rsquo;s interpretability research on internal activation patterns helps explain a pattern most AI coding tool users have hit: the agent passes all the tests, but the code is quietly broken. Here&amp;rsquo;s what that means for how you run these sessions.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/ai-coding-agent-reward-hacking-anthropic-research/cover.png" />
    </item>
    
    <item>
      <title>The AI apprenticeship model: building senior talent in the age of automation</title>
      <link>https://luu.is/en/posts/ai-apprenticeship-model-building-senior-talent/</link>
      <pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/ai-apprenticeship-model-building-senior-talent/</guid>
      <description>AI isn&amp;rsquo;t eliminating junior engineering roles — it&amp;rsquo;s removing the accidental training system most companies relied on. Here&amp;rsquo;s the business model for rebuilding it deliberately, with measurable economics and a 90-day pilot structure.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/ai-apprenticeship-model-building-senior-talent/cover.png" />
    </item>
    
    <item>
      <title>The hidden friction of running a hybrid B2B trade portal</title>
      <link>https://luu.is/en/posts/avoiding-traps-hybrid-architectures-b2b-portal/</link>
      <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/avoiding-traps-hybrid-architectures-b2b-portal/</guid>
      <description>Decoupling our B2B customer portal from WordPress saved us from a massive database migration, but it introduced a complex web of logic drift and cache lag. Here is how we managed the coordination overhead.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/avoiding-traps-hybrid-architectures-b2b-portal/cover.png" />
    </item>
    
    <item>
      <title>WordPress staging that actually mirrors production: what it took to get there</title>
      <link>https://luu.is/en/posts/wordpress-staging-mirrors-production/</link>
      <pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/wordpress-staging-mirrors-production/</guid>
      <description>Most WordPress staging setups test the wrong layer. This is what I learned building a production-fidelity workflow on a real Plesk server — including a Cloudflare incident that looked exactly like a WordPress problem until it didn&amp;rsquo;t.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/wordpress-staging-mirrors-production/cover.png" />
    </item>
    
    <item>
      <title>Plugin drift comes from duplication, not carelessness — here&#39;s how we fixed it</title>
      <link>https://luu.is/en/posts/wordpress-custom-plugin-separate-repos-git-subtree/</link>
      <pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/wordpress-custom-plugin-separate-repos-git-subtree/</guid>
      <description>Three sites, three slightly different copies of the same plugin, no clear canonical version. This is how we untangled it using Git subtree and wp-config.php constants — and what the process revealed about how plugin drift actually happens.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/wordpress-custom-plugin-separate-repos-git-subtree/cover.png" />
    </item>
    
    <item>
      <title>Building a one-way CMS sync workflow that doesn&#39;t bite you later</title>
      <link>https://luu.is/en/posts/cms-staging-one-way-sync-workflow/</link>
      <pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/cms-staging-one-way-sync-workflow/</guid>
      <description>Most CMS staging failures are workflow failures, not technical ones. This covers the design decisions, the bash automation, and the wp_options audit that turned out to be the real work.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/cms-staging-one-way-sync-workflow/cover.png" />
    </item>
    
    <item>
      <title>The SPA pendulum: why we stopped building everything as an application</title>
      <link>https://luu.is/en/posts/spa-pendulum-ssr-vs-spa-architectural-shift/</link>
      <pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/spa-pendulum-ssr-vs-spa-architectural-shift/</guid>
      <description>For a decade, SPAs were the default answer regardless of the problem. Most teams paid for that overcorrection slowly. Here is how the trade-offs actually look, what the shift back to SSR is really about, and how to make the architecture call at the start of a project.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/spa-pendulum-ssr-vs-spa-architectural-shift/cover.png" />
    </item>
    
    <item>
      <title>Why the AI playbook breaks when you scale past a few developers</title>
      <link>https://luu.is/en/posts/why-the-ai-playbook-breaks-when-you-hit-1000-people/</link>
      <pubDate>Wed, 28 Jan 2026 08:30:05 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/why-the-ai-playbook-breaks-when-you-hit-1000-people/</guid>
      <description>What works for a solo developer or a team of 10 falls apart at enterprise scale. Here is how the bottleneck shifts from personal tooling to messy data pipelines and organizational coordination as you grow.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/why-the-ai-playbook-breaks-when-you-hit-1000-people/cover.png" />
    </item>
    
    <item>
      <title>When bumping PHP memory isn&#39;t enough: tracing serialized cache bloat in a page builder</title>
      <link>https://luu.is/en/posts/php-memory-serialized-cache-bloat-page-builder/</link>
      <pubDate>Wed, 14 Jan 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/php-memory-serialized-cache-bloat-page-builder/</guid>
      <description>A WordPress 500 traced to PHP memory looked like a simple limit bump — until the real cause turned out to be a page builder serializing large CSS blobs into the object cache on every request.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/php-memory-serialized-cache-bloat-page-builder/cover.png" />
    </item>
    
    <item>
      <title>That 4 MB `options:notoptions` key is why your WordPress site throws a 500 every ten days</title>
      <link>https://luu.is/en/posts/wordpress-redis-options-notoptions-memory-spike-500-error/</link>
      <pubDate>Mon, 12 Jan 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/wordpress-redis-options-notoptions-memory-spike-500-error/</guid>
      <description>An intermittent WordPress 500 that cleared on refresh turned out to be a single 4 MB Redis key growing without a TTL. Here is what the big-keys scan showed, why the mechanism is easy to miss, and the three config changes that stopped it.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/wordpress-redis-options-notoptions-memory-spike-500-error/cover.png" />
    </item>
    
    <item>
      <title>The silent memory leak: debugging intermittent 500s in WordPress Redis caching</title>
      <link>https://luu.is/en/posts/silent-memory-leak-wordpress-redis-500-errors/</link>
      <pubDate>Mon, 12 Jan 2026 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/silent-memory-leak-wordpress-redis-500-errors/</guid>
      <description>A WordPress site was throwing intermittent 500 errors every ten days. The cache flushed clean each time, which masked the real problem: a single Redis key growing to 4MB and occasionally tipping PHP memory over the edge.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/silent-memory-leak-wordpress-redis-500-errors/cover.png" />
    </item>
    
    <item>
      <title>WooCommerce slows down under concurrency, not under load</title>
      <link>https://luu.is/en/posts/woocommerce-scaling-concurrency-bottlenecks/</link>
      <pubDate>Thu, 04 Dec 2025 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/woocommerce-scaling-concurrency-bottlenecks/</guid>
      <description>The WooCommerce performance failures that actually hurt at scale don&amp;rsquo;t show up in standard audits. They live in plugins doing unbounded per-request work that looks harmless at five requests per second and falls apart at twenty.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/woocommerce-scaling-concurrency-bottlenecks/cover.png" />
    </item>
    
    <item>
      <title>Debugging a persistent WordPress backdoor</title>
      <link>https://luu.is/en/posts/wordpress-backdoor-mu-plugins-persistent-compromise/</link>
      <pubDate>Wed, 03 Dec 2025 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/wordpress-backdoor-mu-plugins-persistent-compromise/</guid>
      <description>A WordPress site was reinfecting itself after every cleanup. The culprit was a self-healing backdoor in mu-plugins that reconstructed itself from an encoded payload stored in the database. Here is how I found it, killed it, and what I missed the first time.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/wordpress-backdoor-mu-plugins-persistent-compromise/cover.png" />
    </item>
    
    <item>
      <title>The mailflow rule I wrote quarantined a client&#39;s shipping invoice — here is what I missed</title>
      <link>https://luu.is/en/posts/mailflow-rule-quarantined-shipping-invoice-arc-dkim/</link>
      <pubDate>Fri, 03 Oct 2025 01:52:14 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/mailflow-rule-quarantined-shipping-invoice-arc-dkim/</guid>
      <description>A mailflow rule meant to catch spoofed mail started blocking legitimate transactional email from a third-party shipping provider. The regex logic was sound in isolation. The infrastructure gap it exposed was not.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/mailflow-rule-quarantined-shipping-invoice-arc-dkim/cover.png" />
    </item>
    
    <item>
      <title>Dissecting a WordPress compromise: from obfuscated code to hardened infrastructure</title>
      <link>https://luu.is/en/posts/wordpress-compromise-obfuscated-code-hardened-infrastructure/</link>
      <pubDate>Mon, 18 Aug 2025 00:00:00 +0000</pubDate>
      
      <guid>https://luu.is/en/posts/wordpress-compromise-obfuscated-code-hardened-infrastructure/</guid>
      <description>A WordPress site on our infrastructure was compromised via an abandoned theme. This is a walkthrough of how I found the malicious code, what it was actually doing, and the harder question I still can&amp;rsquo;t fully answer: whether any real damage was done before we found it.</description>
      <media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://luu.is/en/posts/wordpress-compromise-obfuscated-code-hardened-infrastructure/cover.png" />
    </item>
    
  </channel>
</rss>
