<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: HexShift</title>
    <description>The latest articles on Forem by HexShift (@hexshift).</description>
    <link>https://forem.com/hexshift</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3018589%2F6dd8d6a7-976d-4b0a-8762-74d27f5b9cdd.JPG</url>
      <title>Forem: HexShift</title>
      <link>https://forem.com/hexshift</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hexshift"/>
    <language>en</language>
    <item>
      <title>Master Frontend Development with React, HTMX, jQuery, and Advanced HTML Guides — Pay What You Want</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Tue, 05 Aug 2025 05:54:00 +0000</pubDate>
      <link>https://forem.com/hexshift/master-frontend-development-with-react-htmx-jquery-and-advanced-html-guides-pay-what-you-want-43e</link>
      <guid>https://forem.com/hexshift/master-frontend-development-with-react-htmx-jquery-and-advanced-html-guides-pay-what-you-want-43e</guid>
      <description>&lt;p&gt;Frontend development is constantly evolving. Whether you're diving into React Server Components, simplifying with HTMX, maintaining legacy jQuery systems, or perfecting advanced HTML forms, there's always more to learn.&lt;/p&gt;

&lt;p&gt;I've written a set of focused guides covering each of these areas. They're available as &lt;strong&gt;pay what you want&lt;/strong&gt;, which means you can read them for free or support the work if you find them valuable. Here’s a breakdown of what each guide offers.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/gucrf" rel="noopener noreferrer"&gt;&lt;strong&gt;Mastering React Server Components: A Pro Guide to Modern Full-Stack React (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;React Server Components allow developers to shift more rendering to the server, improving performance and simplifying the frontend stack. This guide explores how RSCs work, how to structure your applications for maintainability, and how to balance client and server responsibilities effectively.&lt;/p&gt;

&lt;p&gt;You’ll dive into practical examples using Suspense, server streaming, and hybrid rendering. The guide also highlights pitfalls to avoid when modernizing legacy code.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/fpjkm" rel="noopener noreferrer"&gt;&lt;strong&gt;HTMX Tutorial: Build Modern Web Apps Without JavaScript Frameworks (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;HTMX enables dynamic web interactions using nothing but HTML attributes. This guide walks you through creating rich frontend experiences with minimal JavaScript, using HTMX to handle everything from form submissions to content updates and modals.&lt;/p&gt;

&lt;p&gt;You'll learn how to build clean, fast-loading, progressively enhanced apps and integrate HTMX with your backend logic without relying on a frontend framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/aansez" rel="noopener noreferrer"&gt;&lt;strong&gt;Mastering jQuery Cross Browser Compatibility (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re maintaining older codebases or working with clients in regulated industries, jQuery is often still in play. This guide focuses on writing modern, reliable jQuery code that works across all major browsers and devices.&lt;/p&gt;

&lt;p&gt;You’ll explore best practices for events, DOM manipulation, polyfills, and graceful degradation, with practical tips on transitioning legacy projects toward a more modern stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/tfqqzf" rel="noopener noreferrer"&gt;&lt;strong&gt;Mastering Advanced HTML Forms: A Complete Guide to Building Dynamic, User-Friendly Forms (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Forms are core to user interaction, yet often overlooked. This guide dives into the deep end of HTML forms: advanced validation, dynamic fields, accessibility, and real-time feedback patterns.&lt;/p&gt;

&lt;p&gt;You'll learn how to use native browser capabilities to improve UX without heavy reliance on JavaScript, and how to ensure your forms are inclusive, performant, and a joy to use.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Pay What You Want?
&lt;/h2&gt;

&lt;p&gt;Each of these guides is available under a pay what you want model. You can download them for free, explore the content, and if they help you or save you time, you're welcome to come back and support them.&lt;/p&gt;

&lt;p&gt;If you like what you read, you can also leave a review or recommend them to other developers. Either way, thanks for checking them out!&lt;/p&gt;

&lt;p&gt;– Asher&lt;/p&gt;

</description>
      <category>htmx</category>
      <category>jquery</category>
      <category>react</category>
      <category>html</category>
    </item>
    <item>
      <title>Building Smarter Backends: Practical Guides You Can Read Free or Pay What You Want</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Mon, 04 Aug 2025 06:03:17 +0000</pubDate>
      <link>https://forem.com/hexshift/building-smarter-backends-practical-guides-you-can-read-free-or-pay-what-you-want-3bdh</link>
      <guid>https://forem.com/hexshift/building-smarter-backends-practical-guides-you-can-read-free-or-pay-what-you-want-3bdh</guid>
      <description>&lt;p&gt;Backend development is evolving fast. Whether you're scaling a real-time chat application, diving into WebSockets, or building your own Python web framework, there's always something new to learn. I’ve written a collection of in-depth guides designed to help backend developers sharpen their skills and get hands-on with modern tools and patterns.&lt;/p&gt;

&lt;p&gt;Each one is available as &lt;strong&gt;pay what you want&lt;/strong&gt;. That means you can download it for free or chip in any amount if you find it valuable.&lt;/p&gt;

&lt;p&gt;Here’s a look at the current collection.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/ahayiu" rel="noopener noreferrer"&gt;&lt;strong&gt;Building a Lightweight Python Web Framework from Scratch (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Want to know what really powers frameworks like Flask or FastAPI? This guide walks you through building your own minimal web framework using Python's standard library. You’ll learn how to implement routing, middleware, request parsing, and clean architecture principles step by step.&lt;/p&gt;

&lt;p&gt;It's for developers who want to demystify their stack and understand exactly how things work under the hood.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/zsnlw" rel="noopener noreferrer"&gt;&lt;strong&gt;Incorporating WebSockets with FastAPI Like a Pro (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;FastAPI supports WebSockets out of the box, but many developers only scratch the surface. This guide shows you how to use FastAPI for real-time apps like dashboards and chat systems.&lt;/p&gt;

&lt;p&gt;You’ll learn about async connection handling, dependency injection in WebSocket routes, authentication, pub-sub integration, and building reliable real-time pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/lshngk" rel="noopener noreferrer"&gt;&lt;strong&gt;Mastering Real-Time Chat Applications Like a Pro (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This guide breaks down how to design and deploy real-time messaging systems from scratch. You’ll explore architecture decisions, presence management, message delivery guarantees, and more.&lt;/p&gt;

&lt;p&gt;Whether you’re building a messaging feature for an app or something more ambitious, this guide gives you the strategies and mental models to do it right.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/ozkkph" rel="noopener noreferrer"&gt;&lt;strong&gt;Mastering Phoenix: A Practical Guide to Scalable, Secure, and Maintainable Applications (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Phoenix is one of the fastest, most resilient web frameworks available, and it runs on the Elixir language and BEAM VM. This guide walks through everything you need to build reliable and scalable Phoenix apps, including contexts, channels, LiveView, and integration with Elixir OTP.&lt;/p&gt;

&lt;p&gt;If you want to bring functional programming into your web projects, this is a great place to start.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://asherbaum.gumroad.com/l/fxmdfo" rel="noopener noreferrer"&gt;&lt;strong&gt;Phoenix LiveView: The Pro’s Guide to Scalable Interfaces and UI Patterns (2025)&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;LiveView makes it possible to build real-time, reactive interfaces in Phoenix without writing JavaScript. This guide focuses on UI architecture, event handling, component structure, and performance optimization.&lt;/p&gt;

&lt;p&gt;It’s a great complement to the core Phoenix guide, especially if you want to deliver responsive user experiences directly from the server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Pay What You Want?
&lt;/h2&gt;

&lt;p&gt;All of these guides are written for developers who want to learn by doing. Pay what you want means you’re free to explore without pressure. If something helps you, feel free to support it. If you’re just browsing or trying something new, take what you need.&lt;/p&gt;

&lt;p&gt;You’re also welcome to share them with others or leave a review. More backend content is coming soon.&lt;/p&gt;

&lt;p&gt;– Asher&lt;/p&gt;

</description>
      <category>python</category>
      <category>backend</category>
      <category>websocket</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Master Docker, DevOps, and Serverless Workflows with These Pay-What-You-Want Guides</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Sun, 03 Aug 2025 13:32:16 +0000</pubDate>
      <link>https://forem.com/hexshift/master-docker-devops-and-serverless-workflows-with-these-pay-what-you-want-guides-4gp8</link>
      <guid>https://forem.com/hexshift/master-docker-devops-and-serverless-workflows-with-these-pay-what-you-want-guides-4gp8</guid>
      <description>&lt;p&gt;If you're working with containers, secure deployments, or serverless workflows, you know that deep technical know-how pays dividends. I've created several hands-on, practical guides for devs and infrastructure engineers who want to level up their skills - and each one is &lt;strong&gt;pay what you want&lt;/strong&gt;. That means you can download them for free or tip a few bucks to support future content. Your call.&lt;/p&gt;

&lt;p&gt;Each guide is written with a clear structure, real-world examples, and a focus on getting things done fast. Here's a breakdown of what you'll get.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks – Hidden Features, Debugging Flows, and Real-World Performance Tuning (2025)&lt;/a&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This guide is your fast track into the internals of &lt;code&gt;containerd&lt;/code&gt;, the container runtime used under the hood by Docker, Kubernetes, and many production systems. While Docker abstracts much of it away, &lt;code&gt;containerd&lt;/code&gt; itself is a powerhouse that devs often overlook.&lt;/p&gt;

&lt;p&gt;In this PDF, I dive into lesser-known flags, configuration tweaks, and debugging techniques for diagnosing weird container behavior. You'll learn how to inspect snapshotters, navigate containerd’s gRPC API with &lt;code&gt;ctr&lt;/code&gt;, and trace system calls when containers misbehave. If you’ve ever hit a dead end while troubleshooting in Kubernetes, this is the guide you didn’t know you needed.&lt;/p&gt;

&lt;p&gt;Key sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time performance profiling with &lt;code&gt;perf&lt;/code&gt; inside namespaces&lt;/li&gt;
&lt;li&gt;Inspecting layered images for efficiency&lt;/li&gt;
&lt;li&gt;Debugging container startup failures without Docker&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qthnn" rel="noopener noreferrer"&gt;Using PCI-DSS Compliant Dockerized Environments Like a Pro (2025)&lt;/a&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Security is not optional - especially when you're dealing with payment data or regulated environments. This PDF walks you through what a PCI-DSS compliant Docker setup looks like, step by step.&lt;/p&gt;

&lt;p&gt;You’ll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure container isolation using user namespaces&lt;/li&gt;
&lt;li&gt;Apply AppArmor/SELinux profiles for PCI segmentation&lt;/li&gt;
&lt;li&gt;Manage secure image pipelines that stand up to audits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the PCI standard is massive, this guide filters the noise and gives you the implementation-ready practices. It’s perfect if you're a solo dev working with payment APIs, or part of a team responsible for cloud deployments.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/hbexs" rel="noopener noreferrer"&gt;Mastering Security &amp;amp; Isolation in Docker Like a Pro (2025)&lt;/a&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This one builds on the last PDF but broadens the scope beyond PCI into general-purpose security best practices for any production container setup.&lt;/p&gt;

&lt;p&gt;The guide takes a systematic approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding the Linux capabilities model&lt;/li&gt;
&lt;li&gt;Controlling the attack surface with &lt;code&gt;seccomp&lt;/code&gt; profiles&lt;/li&gt;
&lt;li&gt;Building hardened base images that reduce CVE exposure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also walk you through how to benchmark container startup time, analyze resource limits, and prevent privilege escalation inside multi-container apps.&lt;/p&gt;

&lt;p&gt;If you've ever copy-pasted a &lt;code&gt;Dockerfile&lt;/code&gt; from Stack Overflow and wondered if it was safe—this guide gives you the answers.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/gvetna" rel="noopener noreferrer"&gt;Building Serverless Workflows with AWS Lambda Like a Pro (2025)&lt;/a&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Containers aren’t always the best fit. Sometimes you want to spin up code on demand with zero ops overhead. That’s where AWS Lambda shines—and this PDF is your battle-tested walkthrough for getting it right.&lt;/p&gt;

&lt;p&gt;We start with basic deployment models and quickly move into real-world scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orchestrating multi-step workflows using AWS Step Functions&lt;/li&gt;
&lt;li&gt;Implementing Lambda layers for shared logic&lt;/li&gt;
&lt;li&gt;Debugging cold starts and optimizing memory for cost savings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll also learn how to secure your serverless apps using IAM least-privilege strategies and API Gateway rate limits.&lt;/p&gt;

&lt;p&gt;Bonus: I include a complete guide to mocking AWS services locally for integration tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Pay-What-You-Want?
&lt;/h2&gt;

&lt;p&gt;I believe technical knowledge should be accessible. You can download any of these guides for free if you’re just starting out, or throw in a tip if you find the content helpful. Either way, it helps me keep creating resources for the dev community.&lt;/p&gt;

&lt;p&gt;Whether you're deploying fintech microservices, spinning up chat apps, or trying to sleep at night knowing your infrastructure won’t break - you’ll find something useful in these guides.&lt;/p&gt;

&lt;p&gt;Feel free to share, remix, or reference them in your own work. And if you’d like to see a future guide on Kubernetes, Terraform, or CI/CD pipelines—let me know!&lt;/p&gt;




&lt;p&gt;✅ Download the full PDFs on Gumroad&lt;br&gt;&lt;br&gt;
💬 Questions or feedback? Drop a comment&lt;br&gt;&lt;br&gt;
💡 Got a topic request? I’m all ears&lt;/p&gt;

&lt;p&gt;Happy deploying,&lt;br&gt;
Asher&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>serverless</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>🔧 How to Debug containerd Like a Pro</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Thu, 31 Jul 2025 04:26:39 +0000</pubDate>
      <link>https://forem.com/hexshift/how-to-debug-containerd-like-a-pro-254o</link>
      <guid>https://forem.com/hexshift/how-to-debug-containerd-like-a-pro-254o</guid>
      <description>&lt;p&gt;containerd is fast and reliable, but when something goes wrong, it helps to know how to inspect its inner workings. Unlike Docker, containerd is more modular and transparent, which gives you greater control during troubleshooting — if you know where to look.&lt;/p&gt;

&lt;p&gt;In this guide, you'll learn practical debugging techniques for containerd. We’ll cover logs, runtime introspection, active tasks, snapshots, namespaces, and image metadata so you can diagnose issues with clarity and confidence.&lt;/p&gt;

&lt;p&gt;For more deep-dive strategies and expert-level tools, check out &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks&lt;/a&gt;&lt;/strong&gt; — a complete PDF guide with real-world workflows, performance tuning, and advanced containerd internals.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Start with containerd Logs
&lt;/h2&gt;

&lt;p&gt;Your first stop when debugging any containerd issue is the system logs. Use &lt;code&gt;journalctl&lt;/code&gt; to view live or historical logs for the containerd service:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo journalctl -u containerd -f&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To review logs from earlier in the day:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo journalctl -u containerd --since "6 hours ago"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Watch for errors related to image pulls, namespace issues, failed mounts, or runtime errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 List Active Tasks and Containers
&lt;/h2&gt;

&lt;p&gt;containerd separates running tasks from containers. A container definition may exist, but without a task, it is not running.&lt;/p&gt;

&lt;p&gt;To list all containers:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default containers list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To list running tasks:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default tasks list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If your container exists but is not listed as a task, it likely crashed or never started.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 View Task Details
&lt;/h2&gt;

&lt;p&gt;To debug a specific running task, inspect its metadata:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default task info &amp;lt;task-id&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You will see its process ID, runtime, snapshot, labels, and container association. If a container fails during startup, use:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr task metrics &amp;lt;task-id&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This may show CPU or memory limits that are being exceeded.&lt;/p&gt;




&lt;h2&gt;
  
  
  📂 Check Snapshots
&lt;/h2&gt;

&lt;p&gt;containerd manages container filesystems using snapshots. These are similar to layers and are often where file system errors occur.&lt;/p&gt;

&lt;p&gt;To list all snapshots:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default snapshots list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each snapshot has a parent-child relationship and is tied to a container’s root filesystem. If your container fails to mount, inspect its snapshot. You can remove a problematic snapshot with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default snapshots rm &amp;lt;snapshot-name&amp;gt;&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 Verify Namespace Isolation
&lt;/h2&gt;

&lt;p&gt;containerd stores containers, images, snapshots, and tasks per namespace. If you forget to specify the right namespace, it may look like things are missing.&lt;/p&gt;

&lt;p&gt;Check current namespaces:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr namespaces list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then list containers in a specific namespace:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace myspace containers list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To avoid confusion, always work within the correct namespace for your environment or script.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Inspect Image Metadata
&lt;/h2&gt;

&lt;p&gt;When an image pull fails or seems corrupted, check the metadata:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default image inspect docker.io/library/alpine:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This reveals layer digests, content descriptors, and configuration data. If the image cache is stale or broken, you can remove and re-pull the image:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace default image rm docker.io/library/alpine:latest&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo ctr --namespace default image pull docker.io/library/alpine:latest&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🧰 Enable Debug-Level Logs
&lt;/h2&gt;

&lt;p&gt;For persistent debugging, enable detailed logs in the containerd configuration.&lt;/p&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/containerd/config.toml&lt;/code&gt; and set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[debug]
  level = "debug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restart containerd:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl restart containerd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After that, logs will include additional diagnostic information, including pull retries, layer mounts, and runtime errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  📘 Conclusion
&lt;/h2&gt;

&lt;p&gt;Debugging containerd may seem low-level at first, but it quickly becomes intuitive when you learn where its components live and how to inspect them. With access to logs, tasks, snapshots, and namespaces, you can gain a complete picture of what is happening under the hood.&lt;/p&gt;

&lt;p&gt;These tools will help you resolve container startup failures, image inconsistencies, or runtime errors efficiently.&lt;/p&gt;

&lt;p&gt;For a full set of debugging playbooks, hidden features, and performance tricks, download &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks - Hidden Features, Debugging Flows, and Real-World Performance Tuning&lt;/a&gt;&lt;/strong&gt; — a PDF guide built for engineers running containerd in production.&lt;/p&gt;

</description>
      <category>containers</category>
      <category>docker</category>
      <category>kubernetes</category>
      <category>security</category>
    </item>
    <item>
      <title>🚀 Speed Up containerd Image Pulls with These Proven Techniques</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Thu, 31 Jul 2025 04:24:36 +0000</pubDate>
      <link>https://forem.com/hexshift/speed-up-containerd-image-pulls-with-these-proven-techniques-1jna</link>
      <guid>https://forem.com/hexshift/speed-up-containerd-image-pulls-with-these-proven-techniques-1jna</guid>
      <description>&lt;p&gt;Pulling container images quickly is critical for fast deployments, continuous integration pipelines, and scaling workloads in real time. containerd is efficient by default, but you can make it even faster with a few targeted adjustments.&lt;/p&gt;

&lt;p&gt;This article walks through several methods to accelerate image pulls using containerd. These techniques help reduce wait times, avoid redundant downloads, and improve performance across CI/CD, Kubernetes clusters, and edge devices.&lt;/p&gt;

&lt;p&gt;To unlock more expert-level performance tweaks and operational workflows, download &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks&lt;/a&gt;&lt;/strong&gt; — a premium PDF guide covering hidden features, real-world tuning, and powerful debugging flows.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Use Local Mirrors for Faster Access
&lt;/h2&gt;

&lt;p&gt;When containerd pulls an image from Docker Hub or a remote registry, latency and rate limits can slow things down. Setting up a local registry mirror brings the image source closer to your network.&lt;/p&gt;

&lt;p&gt;To configure containerd to use a local mirror, edit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/etc/containerd/config.toml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Look for the &lt;code&gt;[plugins."io.containerd.grpc.v1.cri".registry]&lt;/code&gt; section and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
  endpoint = ["http://your-local-registry:5000"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restart containerd:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl restart containerd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This directs image pulls through your local cache, significantly improving download speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Avoid Pulling Unused Tags
&lt;/h2&gt;

&lt;p&gt;Always use specific image tags. Avoid relying on the &lt;code&gt;latest&lt;/code&gt; tag unless you know it is what you want. Tags like &lt;code&gt;latest&lt;/code&gt; may change without warning and force an unnecessary image pull even if you already have the right image cached locally.&lt;/p&gt;

&lt;p&gt;Use pinned versions instead, such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alpine:3.19.1&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;nginx:1.25.3&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;node:20.11.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This ensures repeatable pulls and keeps your image layers cached.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧊 Enable Content Store Caching
&lt;/h2&gt;

&lt;p&gt;containerd maintains a content store that caches pulled layers. By default, this cache is kept on disk unless manually pruned.&lt;/p&gt;

&lt;p&gt;You can verify cached images with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr images list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To ensure you're getting cache hits, avoid pulling or running containers across multiple namespaces unless required. containerd stores snapshots and metadata per namespace, so repeating work across namespaces can duplicate data.&lt;/p&gt;

&lt;p&gt;Stick to a dedicated namespace like &lt;code&gt;ci&lt;/code&gt; or &lt;code&gt;prod&lt;/code&gt; for reusable workflows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace ci image pull docker.io/library/alpine:3.19&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Leverage Registry Prewarming
&lt;/h2&gt;

&lt;p&gt;In automated environments like CI/CD or autoscaling clusters, prewarm your node images with key container images before workloads land.&lt;/p&gt;

&lt;p&gt;This can be done during image bake steps or provisioning by including:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ctr image pull docker.io/library/python:3.12&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This ensures the container runtime does not need to fetch images during a cold start. Combine this with systemd units or cloud-init for automation.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛰️ Use Parallel Pulls with Containerd Snapshots
&lt;/h2&gt;

&lt;p&gt;containerd supports fetching image layers in parallel, which can dramatically reduce total pull time for large, layered images.&lt;/p&gt;

&lt;p&gt;This works best when used with containerd's native snapshotters like &lt;code&gt;overlayfs&lt;/code&gt; or &lt;code&gt;stargz&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To check your current snapshotter:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;containerd config dump | grep snapshotter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make sure &lt;code&gt;overlayfs&lt;/code&gt; is enabled and in use. If your image pulls still seem serial or slow, verify that DNS and networking are not rate-limiting outbound requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Layer Optimization in CI Workflows
&lt;/h2&gt;

&lt;p&gt;Build your images to maximize reuse of common layers. For example, avoid changing the base layer frequently. If your base layer changes every build, all downstream layers are invalidated.&lt;/p&gt;

&lt;p&gt;Split your builds so that dependencies install first, and your app code copies last. This approach preserves intermediate layers across builds, allowing containerd to cache and reuse existing content efficiently.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Clean Up Old or Unused Images
&lt;/h2&gt;

&lt;p&gt;containerd does not automatically remove old images. If your image cache becomes large and full of unused layers, performance may degrade.&lt;/p&gt;

&lt;p&gt;You can clean up with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr images prune&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo ctr snapshots cleanup&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Be careful with these commands in production environments, as they may remove layers still in use. Consider running cleanup in controlled intervals.&lt;/p&gt;




&lt;h2&gt;
  
  
  📘 Conclusion
&lt;/h2&gt;

&lt;p&gt;containerd is fast out of the box, but with some smart adjustments, you can push it even further. Use local mirrors, cache-aware tagging, efficient layering, and prewarming to reduce pull times and speed up your container workflows.&lt;/p&gt;

&lt;p&gt;For more tips like these, along with advanced techniques for debugging, introspection, and containerd's internals, download &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks - Hidden Features, Debugging Flows, and Real-World Performance Tuning&lt;/a&gt;&lt;/strong&gt;. It's packed with knowledge to help you squeeze every ounce of performance from containerd.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>docker</category>
      <category>containers</category>
      <category>security</category>
    </item>
    <item>
      <title>🧱 containerd vs Docker: What's Really Happening Under the Hood?</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Thu, 31 Jul 2025 04:22:46 +0000</pubDate>
      <link>https://forem.com/hexshift/containerd-vs-docker-whats-really-happening-under-the-hood-498a</link>
      <guid>https://forem.com/hexshift/containerd-vs-docker-whats-really-happening-under-the-hood-498a</guid>
      <description>&lt;p&gt;If you're familiar with Docker, you've already used containerd, whether you realized it or not. containerd is the container runtime that powers Docker's engine behind the scenes. When you work directly with containerd, you gain more control, improved performance, and greater flexibility for container-heavy workflows.&lt;/p&gt;

&lt;p&gt;This article explores how containerd compares to Docker, where it fits in the stack, and why many teams are moving toward it for CI/CD systems, edge deployments, and production-scale container orchestration.&lt;/p&gt;

&lt;p&gt;Looking for advanced containerd workflows, hidden commands, and tuning strategies? Check out &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks&lt;/a&gt;&lt;/strong&gt; — a downloadable PDF packed with expert tips and real-world techniques.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐳 Docker: Batteries Included
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt; is a full-featured platform for building, running, and managing containers. It includes the following components:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;docker&lt;/code&gt; CLI&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;code&gt;dockerd&lt;/code&gt;&lt;/strong&gt; daemon and API server&lt;br&gt;&lt;br&gt;
&lt;strong&gt;containerd&lt;/strong&gt; as its internal runtime&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dockerfile build system&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Networking and volumes support&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Image and registry management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This all-in-one toolkit makes Docker ideal for local development and prototyping. However, in large-scale production environments, the Docker daemon can introduce unnecessary complexity and overhead.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ containerd: Lean and Purpose-Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;containerd&lt;/strong&gt; is a focused, high-performance container runtime. It handles fewer tasks than Docker but does so with precision:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pulling and pushing images&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Snapshot and image layer management&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Running containers using runc&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Streaming logs and managing lifecycle events&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;containerd does not include Dockerfile support or a build system. It was designed to be embedded into other systems like Kubernetes or used directly in environments that require minimal overhead and maximum control.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What Really Happens When You Run &lt;code&gt;docker run&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;When you run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run alpine&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here's what takes place under the hood:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; The Docker CLI communicates with the &lt;code&gt;dockerd&lt;/code&gt; daemon&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;dockerd&lt;/code&gt; passes instructions to containerd&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; containerd pulls the image and starts the container using &lt;code&gt;runc&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Docker handles networking and volume configuration&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 5:&lt;/strong&gt; Output is streamed from containerd back to your terminal&lt;/p&gt;

&lt;p&gt;By using containerd directly, you bypass many of these layers and interact more closely with the runtime environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Why Use containerd Directly?
&lt;/h2&gt;

&lt;p&gt;Use containerd if:&lt;/p&gt;

&lt;p&gt;You need fine-grained control over containers, snapshots, and image caching.&lt;br&gt;&lt;br&gt;
You are building custom CI/CD pipelines and want lightweight tooling.&lt;br&gt;&lt;br&gt;
You are deploying containers on edge devices or stripped-down servers.&lt;br&gt;&lt;br&gt;
You need better insight and debugging options at the runtime level.&lt;/p&gt;

&lt;p&gt;containerd avoids opinionated defaults and offers more freedom to design your infrastructure your way.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Working with &lt;code&gt;ctr&lt;/code&gt;: The containerd CLI
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pull an image:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace devbox image pull docker.io/library/alpine:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run a container:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace devbox run -t --rm docker.io/library/alpine:latest alpine-test /bin/sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;List running containers:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr --namespace devbox containers list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check active namespaces:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ctr namespaces list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All &lt;code&gt;ctr&lt;/code&gt; commands require you to specify a namespace. If you forget, containers and images may appear to be missing.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 Docker for Developers, containerd for Deployments
&lt;/h2&gt;

&lt;p&gt;Many teams prefer Docker for development because it is user-friendly and fast to start with. But in production, containerd offers advantages that are hard to ignore.&lt;/p&gt;

&lt;p&gt;It launches containers faster, integrates directly with Kubernetes via CRI, and avoids the extra abstraction of the Docker daemon. containerd is also more transparent and modular, making it easier to monitor and debug.&lt;/p&gt;

&lt;p&gt;A common pattern is to develop with Docker and deploy with containerd. This keeps local workflows simple while ensuring performance and control in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  📘 Conclusion
&lt;/h2&gt;

&lt;p&gt;containerd is not a replacement for Docker. It is the runtime underneath it. But when used directly, containerd offers new levels of speed, clarity, and control for those managing containers at scale.&lt;/p&gt;

&lt;p&gt;By cutting out the Docker layer, you reduce complexity, improve cold start times, and gain deeper insight into how your containers behave.&lt;/p&gt;

&lt;p&gt;If you're ready to go beyond surface-level usage and unlock advanced containerd capabilities, download &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/qscwsu" rel="noopener noreferrer"&gt;containerd Power Hacks - Hidden Features, Debugging Flows, and Real-World Performance Tuning&lt;/a&gt;&lt;/strong&gt;. It is designed for engineers and operators who want to master containerd in real-world production environments.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>docker</category>
      <category>containers</category>
      <category>security</category>
    </item>
    <item>
      <title>How to Stop Pop‑Ups and Annoying Ads on an Older Windows XP or Windows 7 PC</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Tue, 22 Jul 2025 11:40:35 +0000</pubDate>
      <link>https://forem.com/hexshift/how-to-stop-pop-ups-and-annoying-ads-on-an-older-windows-xp-or-windows-7-pc-5g4i</link>
      <guid>https://forem.com/hexshift/how-to-stop-pop-ups-and-annoying-ads-on-an-older-windows-xp-or-windows-7-pc-5g4i</guid>
      <description>&lt;p&gt;Pop‑ups and unwanted ads can make using your older PC frustrating and slow. These ads may appear in your browser, as system notifications, or even on your desktop. They can disrupt your browsing, slow down performance, and sometimes spread malware. Fortunately you can reclaim control of your computer by following simple steps tailored for Windows XP and Windows 7.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand Where Ads Come From
&lt;/h2&gt;

&lt;p&gt;Ads and pop‑ups originate in several ways. Some come from websites you visit. Others come bundled with free software. Some may result from adware or spyware infections. Identifying the source helps you know how to stop them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove Adware and Malware
&lt;/h2&gt;

&lt;p&gt;First start with a full system scan. If you do not have antivirus software or malware removal tools installed, get one such as Malwarebytes Free. Run a full system scan and clean any threats it finds. Once the scan is complete, reboot your computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reset Your Web Browser
&lt;/h2&gt;

&lt;p&gt;Sometimes browser settings are hijacked by adware. Resetting can clear unwanted toolbars, extensions, and startup pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internet Explorer&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Click Tools, then Internet Options. Under the Advanced tab click Reset. Confirm by clicking Reset again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firefox&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Click the menu icon, open Help, then choose Troubleshooting Information. Click Refresh Firefox to restore default settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome or Chromium-based browsers&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Click the menu icon, open Settings, then scroll down and click Advanced. Under Reset settings click Restore settings to their original defaults.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install a Pop‑Up Blocker
&lt;/h2&gt;

&lt;p&gt;Modern browsers include built-in pop‑up blockers. Make sure yours is active.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internet Explorer&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Click Tools, then Pop‑up Blocker settings, and set it to High.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firefox or Chrome&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Pop‑ups are blocked by default. You can enhance protection with extensions like uBlock Origin or Adblock Plus. Visit the add‑ons page and install the extension, then restart your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clear Temporary Files and Cache
&lt;/h2&gt;

&lt;p&gt;Temporary files may store unwanted ad scripts. Cleaning your browser cache can improve performance.&lt;/p&gt;

&lt;p&gt;In your browser settings find options related to privacy or history. Select to clear cache and cookies. Doing this regularly helps maintain speed and privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check Installed Programs
&lt;/h2&gt;

&lt;p&gt;Many free utilities install adware without making it obvious. Open Control Panel and go to Programs and Features or Add or Remove Programs. Look for anything unfamiliar or installed recently. Uninstall anything suspicious, and restart your computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review Browser Extensions
&lt;/h2&gt;

&lt;p&gt;Extensions may display ads or redirect pages. In Internet Explorer click Tools then Manage Add‑ons to disable or remove unknown items. In Firefox open Add‑ons from the menu and review Extensions or Plugins. In Chrome go to Settings, open Extensions, and remove unwanted items.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a Hosts File to Block Ads
&lt;/h2&gt;

&lt;p&gt;You can block known ad servers by editing your hosts file.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;&lt;br&gt;
&lt;code&gt;C:\Windows\System32\drivers\etc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the file named &lt;code&gt;hosts&lt;/code&gt; with Notepad (as administrator). At the bottom, add lines like this:&lt;br&gt;&lt;br&gt;
&lt;code&gt;127.0.0.1 ads.example.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each line should redirect an ad server to your own machine so the ads never load. Save the file and restart your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adjust Security and Privacy Settings
&lt;/h2&gt;

&lt;p&gt;Tighten your browser’s security settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internet Explorer&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Go to Internet Options, open the Security tab, and set the Internet zone to Medium-High.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firefox&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Open Options, go to Privacy and Security, and set Tracking Protection to Strict.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid Risky Websites and Downloads
&lt;/h2&gt;

&lt;p&gt;Some ads appear when visiting less reputable sites. Avoid these and only download software from official sources. When installing programs, choose the Custom or Advanced option to deselect bundled offers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Your Software Updated
&lt;/h2&gt;

&lt;p&gt;While XP and older browsers may no longer receive updates, you can still update antivirus, malware removal tools, and supported browsers. Staying current reduces vulnerabilities that adware exploits.&lt;/p&gt;




&lt;p&gt;By following these steps you can get rid of unwanted ads and pop‑ups on your older PC. You can enjoy a cleaner, faster, and safer browsing experience on Windows XP or Windows 7.&lt;/p&gt;

&lt;p&gt;For an in‑depth guide covering security, backups, and device support for older systems, see the &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/kpxlmv" rel="noopener noreferrer"&gt;Windows XP and Windows 7 Survival Guide: How to Keep Your Old PC Safe and Running in 2025&lt;/a&gt;&lt;/strong&gt;. You pay once and own the guide forever.&lt;/p&gt;

&lt;p&gt;Thank you for reading. If you found this useful, please leave a comment, like the article, and subscribe for more free content.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Speed Up a Slow Windows XP or Windows 7 PC</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Tue, 22 Jul 2025 11:38:24 +0000</pubDate>
      <link>https://forem.com/hexshift/how-to-speed-up-a-slow-windows-xp-or-windows-7-pc-3n0c</link>
      <guid>https://forem.com/hexshift/how-to-speed-up-a-slow-windows-xp-or-windows-7-pc-3n0c</guid>
      <description>&lt;p&gt;If your older computer feels like it is crawling, taking minutes to start and lagging while you browse or type, you are not alone. Many people still using Windows XP or Windows 7 have noticed a sharp drop in speed over time. The good news is that you can improve performance without replacing your machine. This guide walks through practical, safe steps to speed up a slow XP or Windows 7 PC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Restart Your Computer
&lt;/h2&gt;

&lt;p&gt;It may sound obvious, but many users leave their computer running for days or even weeks. A simple restart clears memory, closes background tasks, and can instantly improve speed. Make it a habit to restart your computer every day or two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disable Startup Programs
&lt;/h2&gt;

&lt;p&gt;Too many programs running at startup can overwhelm an older computer. You can stop unneeded software from launching automatically.&lt;/p&gt;

&lt;p&gt;On Windows XP:&lt;br&gt;
Click &lt;strong&gt;Start&lt;/strong&gt;, then &lt;strong&gt;Run&lt;/strong&gt;, type &lt;code&gt;msconfig&lt;/code&gt; and press Enter. Click the &lt;strong&gt;Startup&lt;/strong&gt; tab and uncheck items you do not need. Leave antivirus checked, but most others like toolbars or updaters can be disabled.&lt;/p&gt;

&lt;p&gt;On Windows 7:&lt;br&gt;
Click &lt;strong&gt;Start&lt;/strong&gt;, type &lt;code&gt;msconfig&lt;/code&gt; into the search box, press Enter, and go to the &lt;strong&gt;Startup&lt;/strong&gt; tab. Uncheck unnecessary items.&lt;/p&gt;

&lt;p&gt;Restart your computer after making changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uninstall Unused Programs
&lt;/h2&gt;

&lt;p&gt;Old programs take up space and may run in the background. Removing them helps free memory and disk space.&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;Control Panel&lt;/strong&gt;, then &lt;strong&gt;Add or Remove Programs&lt;/strong&gt; (XP) or &lt;strong&gt;Programs and Features&lt;/strong&gt; (Windows 7). Sort by installation date or size. Remove anything you no longer use or recognize, except system tools or drivers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clean Up Temporary Files
&lt;/h2&gt;

&lt;p&gt;Windows stores temporary files for updates, browsing, and software use. Over time, these pile up and slow your system.&lt;/p&gt;

&lt;p&gt;On Windows XP:&lt;br&gt;
Click &lt;strong&gt;Start&lt;/strong&gt;, go to &lt;strong&gt;Run&lt;/strong&gt;, type &lt;code&gt;cleanmgr&lt;/code&gt; and press Enter.&lt;/p&gt;

&lt;p&gt;On Windows 7:&lt;br&gt;
Click &lt;strong&gt;Start&lt;/strong&gt;, type &lt;code&gt;Disk Cleanup&lt;/code&gt; in the search bar, and select the app. Let it scan, then tick all boxes and click OK.&lt;/p&gt;

&lt;p&gt;You can also manually delete temp files by opening &lt;strong&gt;Run&lt;/strong&gt; and typing &lt;code&gt;%temp%&lt;/code&gt; and deleting everything in that folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defragment the Hard Drive
&lt;/h2&gt;

&lt;p&gt;Over time, files on your hard drive become fragmented, meaning they are broken into small pieces scattered across the disk. This slows down access times.&lt;/p&gt;

&lt;p&gt;On Windows XP:&lt;br&gt;
Go to &lt;strong&gt;Start &amp;gt; All Programs &amp;gt; Accessories &amp;gt; System Tools &amp;gt; Disk Defragmenter&lt;/strong&gt;. Select your drive and click &lt;strong&gt;Defragment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On Windows 7:&lt;br&gt;
Click &lt;strong&gt;Start&lt;/strong&gt;, type &lt;code&gt;Defragment&lt;/code&gt; in the search box, then choose &lt;strong&gt;Disk Defragmenter&lt;/strong&gt;. Click &lt;strong&gt;Defragment disk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This process can take an hour or more, so plan to run it when you do not need the PC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check for Malware and Viruses
&lt;/h2&gt;

&lt;p&gt;Malware is a common cause of slowdowns. Even if you have antivirus software, it may not catch everything.&lt;/p&gt;

&lt;p&gt;If you do not have antivirus software, install one. Good free choices for older systems include Avast (older versions), AVG, or Microsoft Security Essentials (for Windows 7).&lt;/p&gt;

&lt;p&gt;Run a full system scan and remove any threats found.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disable Visual Effects
&lt;/h2&gt;

&lt;p&gt;Windows XP and Windows 7 include visual effects like fading menus and transparent windows that slow down performance on older hardware.&lt;/p&gt;

&lt;p&gt;To disable them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows XP:&lt;/strong&gt;&lt;br&gt;
Right-click &lt;strong&gt;My Computer&lt;/strong&gt;, choose &lt;strong&gt;Properties&lt;/strong&gt;, click the &lt;strong&gt;Advanced&lt;/strong&gt; tab. Under &lt;strong&gt;Performance&lt;/strong&gt;, click &lt;strong&gt;Settings&lt;/strong&gt;. Choose &lt;strong&gt;Adjust for best performance&lt;/strong&gt;, or manually disable individual items.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows 7:&lt;/strong&gt;&lt;br&gt;
Click &lt;strong&gt;Start&lt;/strong&gt;, right-click &lt;strong&gt;Computer&lt;/strong&gt;, choose &lt;strong&gt;Properties&lt;/strong&gt;, then &lt;strong&gt;Advanced system settings&lt;/strong&gt;. Under &lt;strong&gt;Performance&lt;/strong&gt;, click &lt;strong&gt;Settings&lt;/strong&gt; and select &lt;strong&gt;Adjust for best performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Click OK to apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Increase Virtual Memory
&lt;/h2&gt;

&lt;p&gt;Virtual memory is hard drive space used like RAM when your physical memory runs low. If set too low, your system can slow down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows XP and 7:&lt;/strong&gt;&lt;br&gt;
Right-click &lt;strong&gt;My Computer&lt;/strong&gt; or &lt;strong&gt;Computer&lt;/strong&gt;, choose &lt;strong&gt;Properties&lt;/strong&gt;. Click &lt;strong&gt;Advanced system settings&lt;/strong&gt;. Under &lt;strong&gt;Performance&lt;/strong&gt;, click &lt;strong&gt;Settings&lt;/strong&gt;, then go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and click &lt;strong&gt;Change&lt;/strong&gt; under Virtual Memory.&lt;/p&gt;

&lt;p&gt;Uncheck &lt;strong&gt;Automatically manage&lt;/strong&gt; (Windows 7). Choose &lt;strong&gt;Custom size&lt;/strong&gt;. A good rule is 1.5 times your RAM for the initial size and 3 times for the maximum.&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Set&lt;/strong&gt;, then OK, and restart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scan for Hard Drive Errors
&lt;/h2&gt;

&lt;p&gt;A failing hard drive can slow down your PC. To check for errors:&lt;/p&gt;

&lt;p&gt;Open &lt;strong&gt;Command Prompt&lt;/strong&gt; and type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chkdsk /f&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Press Enter. It may ask to schedule the check for the next restart. Press Y and restart your computer.&lt;/p&gt;

&lt;p&gt;This process will find and fix file system problems that could be causing delays.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Software Updated
&lt;/h2&gt;

&lt;p&gt;Though your operating system may no longer receive updates, other software like browsers and drivers should still be updated. Using outdated software can lead to bugs and slower performance.&lt;/p&gt;

&lt;p&gt;Update your web browser to a lightweight, current version such as Firefox ESR or a legacy Chromium build that still works with your system.&lt;/p&gt;




&lt;p&gt;By following these steps, your old Windows XP or Windows 7 PC should feel more responsive. You do not need to replace it just because it runs slowly. Often, with just a few changes, your computer can work well for years to come.&lt;/p&gt;

&lt;p&gt;For a full guide on keeping older PCs secure, updated, and functional in 2025 and beyond, check out the &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/kpxlmv" rel="noopener noreferrer"&gt;Windows XP and Windows 7 Survival Guide: How to Keep Your Old PC Safe and Running in 2025&lt;/a&gt;&lt;/strong&gt;. You pay once and keep the guide forever.&lt;/p&gt;

&lt;p&gt;Thank you for reading. If this article helped, please comment, like and subscribe for more free content.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Fix a Windows XP or Windows 7 PC That Won’t Boot</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Tue, 22 Jul 2025 11:36:52 +0000</pubDate>
      <link>https://forem.com/hexshift/how-to-fix-a-windows-xp-or-windows-7-pc-that-wont-boot-3nb9</link>
      <guid>https://forem.com/hexshift/how-to-fix-a-windows-xp-or-windows-7-pc-that-wont-boot-3nb9</guid>
      <description>&lt;p&gt;If your computer turns on but does not boot into Windows XP or Windows 7, it can be worrying. However, you do not necessarily need a new computer. This guide walks you through common reasons for boot failure and how to fix them yourself, even if you are not very technical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the Basics
&lt;/h2&gt;

&lt;p&gt;First, check whether the computer is receiving power. Are the lights on? Do you hear the fan running? If not, check the power cable, wall socket, and power strip. If it seems completely dead, try another power cord or outlet.&lt;/p&gt;

&lt;p&gt;If the computer powers on but gets stuck on a black screen or shows a Windows error message, continue with the steps below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Safe Mode
&lt;/h2&gt;

&lt;p&gt;Safe Mode loads only the essential parts of Windows. To try it, restart your computer and press the &lt;strong&gt;F8&lt;/strong&gt; key repeatedly as it starts. If you see a black screen with white text offering boot options, select &lt;strong&gt;Safe Mode&lt;/strong&gt; using the arrow keys, then press Enter.&lt;/p&gt;

&lt;p&gt;If Safe Mode works, your problem might be caused by a driver or program that runs during normal startup. You can use Safe Mode to uninstall recently added software or run system restore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Last Known Good Configuration
&lt;/h2&gt;

&lt;p&gt;While on the same F8 boot options screen, you can also try &lt;strong&gt;Last Known Good Configuration&lt;/strong&gt;. This option loads the last successful boot settings. If your problem began recently, this can often fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check for Bootable Devices
&lt;/h2&gt;

&lt;p&gt;If your computer tries to boot from the wrong device, it will fail. Unplug any USB drives, CDs, DVDs, or external hard drives, then restart the computer. Sometimes a USB stick can confuse the system into trying to boot from it.&lt;/p&gt;

&lt;p&gt;You can also enter your BIOS or boot menu by pressing &lt;strong&gt;F2&lt;/strong&gt;, &lt;strong&gt;F10&lt;/strong&gt;, &lt;strong&gt;DEL&lt;/strong&gt;, or &lt;strong&gt;ESC&lt;/strong&gt; as the computer starts, depending on the brand. Look for an option labeled &lt;strong&gt;Boot Order&lt;/strong&gt; and make sure the internal hard drive is listed first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run Startup Repair (Windows 7 Only)
&lt;/h2&gt;

&lt;p&gt;If you have a Windows 7 installation DVD or USB drive, insert it and restart your computer. Press a key when prompted, then choose &lt;strong&gt;Repair your computer&lt;/strong&gt; instead of Install Now. Select &lt;strong&gt;Startup Repair&lt;/strong&gt; from the list of recovery tools.&lt;/p&gt;

&lt;p&gt;Startup Repair will scan for issues and attempt to fix them automatically. This does not work on Windows XP, but XP users can run a similar tool called Recovery Console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the Recovery Console (Windows XP)
&lt;/h2&gt;

&lt;p&gt;To use this tool, you need a Windows XP CD. Insert it and boot from the CD. When you reach the setup screen, press &lt;strong&gt;R&lt;/strong&gt; to launch the Recovery Console. You will be asked to choose your Windows installation and enter your administrator password.&lt;/p&gt;

&lt;p&gt;At the prompt, try the following commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;chkdsk /r&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;fixboot&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;fixmbr&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type one command at a time and press Enter after each. These commands check for hard drive errors, rewrite the boot sector, and fix the master boot record.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Restore
&lt;/h2&gt;

&lt;p&gt;If you can get into Safe Mode or use your Windows installation media, you may be able to use System Restore. This rolls your system settings back to an earlier time when the PC was working.&lt;/p&gt;

&lt;p&gt;In Safe Mode:&lt;br&gt;&lt;br&gt;
Go to Start, type &lt;strong&gt;System Restore&lt;/strong&gt;, and follow the prompts. Choose a restore point from before your problem started.&lt;/p&gt;

&lt;p&gt;From Windows 7 recovery tools:&lt;br&gt;&lt;br&gt;
Select &lt;strong&gt;System Restore&lt;/strong&gt; and pick a suitable restore point.&lt;/p&gt;

&lt;p&gt;System Restore does not delete personal files but it will remove recently installed drivers and software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove New Hardware or Software
&lt;/h2&gt;

&lt;p&gt;Have you recently added new hardware like a printer, graphics card, or USB device? Try disconnecting it. New devices can conflict with older systems, especially if drivers are not properly installed.&lt;/p&gt;

&lt;p&gt;Similarly, if you recently installed a new program or update, it may have caused the issue. Boot into Safe Mode and uninstall the software from &lt;strong&gt;Control Panel &amp;gt; Programs&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scan for Malware
&lt;/h2&gt;

&lt;p&gt;Malware can sometimes damage your boot sector or critical Windows files. If you can get into Safe Mode with Networking, download a reputable tool like Malwarebytes, install it, and run a full scan.&lt;/p&gt;

&lt;p&gt;You can also create a bootable antivirus CD or USB on another computer and use it to scan your troubled machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reinstall Windows (Last Resort)
&lt;/h2&gt;

&lt;p&gt;If nothing else works and you have backed up your important files, reinstalling Windows might be your only option. For Windows XP or Windows 7, insert the installation disc or USB, boot from it, and follow the steps to do a clean install.&lt;/p&gt;

&lt;p&gt;Be sure to choose the option to format the hard drive only if you are sure all your data is backed up elsewhere.&lt;/p&gt;




&lt;p&gt;If you have followed these steps, you now understand several ways to recover a non-booting XP or Windows 7 computer. These systems can be stubborn, but most problems are fixable with patience and care.&lt;/p&gt;

&lt;p&gt;For more support and complete step-by-step instructions to keep your old system working safely, check out the &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/kpxlmv" rel="noopener noreferrer"&gt;Windows XP and Windows 7 Survival Guide: How to Keep Your Old PC Safe and Running in 2025&lt;/a&gt;&lt;/strong&gt;. You pay once and keep the guide forever.&lt;/p&gt;

&lt;p&gt;Thank you for reading. If you found this article helpful, please comment, like and subscribe for more free content.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Scaling MediaWiki Extensions in High-Traffic Environments</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Mon, 21 Jul 2025 20:54:45 +0000</pubDate>
      <link>https://forem.com/hexshift/scaling-mediawiki-extensions-in-high-traffic-environments-4l6d</link>
      <guid>https://forem.com/hexshift/scaling-mediawiki-extensions-in-high-traffic-environments-4l6d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;MediaWiki is a capable platform, but when used in high-traffic environments or enterprise deployments, performance bottlenecks can appear quickly, especially when extensions are involved. Many developers write extensions that work well locally or on small sites, only to find that under real-world usage, these same extensions cause slow pages, increased memory consumption, and excessive load on the database.&lt;/p&gt;

&lt;p&gt;This article addresses the specific challenges of scaling MediaWiki extensions. We will cover how to identify performance problems, techniques for writing efficient code, and best practices for integrating with MediaWiki’s caching, job queue, and database layers. By the end, you will understand how to write extensions that scale horizontally and handle thousands of requests per minute without failing under pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Profiling and Benchmarking
&lt;/h2&gt;

&lt;p&gt;Before optimizing anything, you must know where the bottlenecks lie. MediaWiki includes a built-in profiling system. Set &lt;code&gt;\$wgDebugToolbar = true&lt;/code&gt; and &lt;code&gt;\$wgDebugProfiling = true&lt;/code&gt; in &lt;code&gt;LocalSettings.php&lt;/code&gt; to view detailed breakdowns of execution time, memory usage, and database queries in the debug toolbar.&lt;/p&gt;

&lt;p&gt;For finer-grained measurement, insert profiling markers in your code using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Profiler::instance()-&amp;gt;scopedProfileIn( __METHOD__ );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use these markers in hooks or controller methods to see how your custom logic affects overall performance. Avoid measuring performance based on load times in the browser alone. Backend performance must be tracked using logs and proper instrumentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoiding Expensive Queries
&lt;/h2&gt;

&lt;p&gt;Database performance is often the primary constraint. A common anti-pattern is looping over large result sets or joining MediaWiki core tables in complex ways. Use MediaWiki’s &lt;code&gt;SelectQueryBuilder&lt;/code&gt; instead of raw SQL whenever possible. It provides safer abstraction and better integration with replication-aware read and write connections.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$dbr-&amp;gt;query( "SELECT * FROM page WHERE page_namespace = 0" );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$res = MediaWikiServices::getInstance()-&amp;gt;getDBLoadBalancer()-&amp;gt;getConnection( DB_REPLICA )-&amp;gt;newSelectQueryBuilder()-&amp;gt;select( [ 'page_id', 'page_title' ] )-&amp;gt;from( 'page' )-&amp;gt;where( [ 'page_namespace' =&amp;gt; 0 ] )-&amp;gt;caller( __METHOD__ )-&amp;gt;fetchResultSet();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Always benchmark the execution plan of queries using &lt;code&gt;EXPLAIN&lt;/code&gt; in the MySQL shell or MediaWiki’s query profiler. Avoid full table scans, unindexed fields, or frequent queries to volatile data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using ObjectCache
&lt;/h2&gt;

&lt;p&gt;MediaWiki provides a powerful caching layer abstracted through &lt;code&gt;ObjectCache&lt;/code&gt;. Instead of recomputing results or querying the database, store expensive results in cache and reuse them when needed. Use &lt;code&gt;WANObjectCache&lt;/code&gt; to ensure consistency across multiple web servers and request contexts.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$cache = MediaWikiServices::getInstance()-&amp;gt;getMainWANObjectCache();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$key = $cache-&amp;gt;makeKey( 'myextension', 'expensive-result', $user-&amp;gt;getId() );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$data = $cache-&amp;gt;getWithSetCallback( $key, 3600, function () use ( $user ) { return computeExpensiveResult( $user ); } );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This pattern caches the result for an hour and recomputes only if needed. Use it for rendering large tables, user-specific dashboards, or API responses.&lt;/p&gt;

&lt;p&gt;Avoid using &lt;code&gt;APCBagOStuff&lt;/code&gt; or &lt;code&gt;HashBagOStuff&lt;/code&gt; in production. These are in-memory caches that do not scale across servers. Rely instead on &lt;code&gt;RedisBagOStuff&lt;/code&gt; or &lt;code&gt;MemcachedBagOStuff&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  JobQueue for Deferred Processing
&lt;/h2&gt;

&lt;p&gt;When a user action triggers something expensive, such as sending emails, updating logs, or writing to external APIs, avoid doing it synchronously. Instead, use MediaWiki’s JobQueue. Define a custom job by extending &lt;code&gt;Job&lt;/code&gt; and register it in your extension.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;class MyExpensiveJob extends Job { public function run() { expensiveWork(); return true; } }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Queue the job with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JobQueueGroup::singleton()-&amp;gt;push( new MyExpensiveJob( $title, [ 'user' =&amp;gt; $user-&amp;gt;getId() ] ) );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Jobs run asynchronously via &lt;code&gt;runJobs.php&lt;/code&gt; or Redis queues. Monitor the job backlog and error logs. If your job fails silently or throws exceptions, they will appear in &lt;code&gt;jobqueue.log&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  File and Output Caching
&lt;/h2&gt;

&lt;p&gt;For static or semi-static content, consider using file-based output caching. Store generated HTML fragments in the file system or a persistent cache and serve them directly to improve performance. This is especially useful for infoboxes, timelines, or statistical dashboards that only change occasionally.&lt;/p&gt;

&lt;p&gt;Use MediaWiki’s &lt;code&gt;OutputPage::addHTML&lt;/code&gt; and &lt;code&gt;OutputPage::enableClientCache&lt;/code&gt; to fine-tune how your extension affects the page cache. Avoid disabling caching globally unless absolutely necessary. Integrate with &lt;code&gt;ParserCache&lt;/code&gt; if your extension outputs parser content.&lt;/p&gt;

&lt;p&gt;If your extension is modifying content that is cached, like templates or categories, use the correct parser options and cache keys. Otherwise, MediaWiki may serve stale or incorrect content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limiting API Load
&lt;/h2&gt;

&lt;p&gt;If your extension exposes custom API endpoints, ensure they are fast and not easily abused. MediaWiki provides throttling hooks and rate limiting via &lt;code&gt;$wgRateLimits&lt;/code&gt;. Avoid exposing raw database results or non-paginated content.&lt;/p&gt;

&lt;p&gt;Paginate results with continuation parameters:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$this-&amp;gt;setContinueEnumParameter( 'offset', $newOffset ); $this-&amp;gt;getResult()-&amp;gt;addValue( null, 'continue', [ 'offset' =&amp;gt; $newOffset ] );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For expensive calculations, defer to jobs or cache the output. Consider introducing an &lt;code&gt;async=true&lt;/code&gt; flag for large responses so that clients poll for results later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazy Loading and ResourceLoader Optimization
&lt;/h2&gt;

&lt;p&gt;Extensions that ship JavaScript and CSS should use ResourceLoader properly. Avoid loading scripts on every page if they are only used on special pages or specific namespaces. Register modules conditionally in hooks like &lt;code&gt;BeforePageDisplay&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if ( $title-&amp;gt;inNamespace( NS_SPECIAL ) ) { $out-&amp;gt;addModules( 'ext.myextension.special' ); }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bundle small scripts together but avoid overly large payloads. Use &lt;code&gt;targets&lt;/code&gt; to scope modules to desktop or mobile. For dynamic interactions, use &lt;code&gt;mw.loader.using&lt;/code&gt; to lazy-load modules only when needed.&lt;/p&gt;

&lt;p&gt;Minimize expensive client-side DOM manipulation. If your extension relies on AJAX or dynamic content, ensure that your JavaScript only runs when the relevant elements are present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horizontal Scaling Considerations
&lt;/h2&gt;

&lt;p&gt;If your MediaWiki instance runs on multiple servers or in a Kubernetes cluster, ensure your extension does not rely on file system writes or session data stored locally. Use shared storage via Swift or S3 for uploads, and manage sessions with Redis or Memcached.&lt;/p&gt;

&lt;p&gt;For logging or debugging, do not write to local &lt;code&gt;tmp&lt;/code&gt; or &lt;code&gt;logs&lt;/code&gt; directories. Instead, use MediaWiki’s &lt;code&gt;LoggerFactory&lt;/code&gt; to write logs to centralized systems like syslog, ELK stack, or structured JSON logs.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$logger = LoggerFactory::getInstance( 'MyExtension' ); $logger-&amp;gt;info( 'User submitted form', [ 'user' =&amp;gt; $user-&amp;gt;getName() ] );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This ensures logs are aggregated and searchable without depending on local file access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Best Practices
&lt;/h2&gt;

&lt;p&gt;Avoid deploying large changes or new extensions directly to a production wiki. Use a staging environment and run MediaWiki’s test suite, especially if you modify existing hooks or services. Use &lt;code&gt;phpunit&lt;/code&gt; to run extension-specific tests.&lt;/p&gt;

&lt;p&gt;For schema changes, always follow the migration pattern:&lt;/p&gt;

&lt;p&gt;Add nullable fields&lt;br&gt;&lt;br&gt;
Backfill data using maintenance scripts&lt;br&gt;&lt;br&gt;
Make schema required only after validation&lt;/p&gt;

&lt;p&gt;Coordinate database updates with DBAs if using replication or shared clusters.&lt;/p&gt;

&lt;p&gt;Use deployment tools like &lt;code&gt;Scap&lt;/code&gt; or &lt;code&gt;Helm&lt;/code&gt; for MediaWiki deployments. Ensure your extension uses proper versioning and has rollback capability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring and Alerting
&lt;/h2&gt;

&lt;p&gt;After deployment, monitor your extension using logs, performance dashboards, and metrics. Integrate with Prometheus or StatsD to emit metrics like request time, cache hit rate, or job failures.&lt;/p&gt;

&lt;p&gt;Add profiling hooks in key execution paths:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;wfProfileIn( __METHOD__ ); // Do work wfProfileOut( __METHOD__ );&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Track user-reported errors in a structured way using MediaWiki’s &lt;code&gt;LoggerFactory&lt;/code&gt; or third-party tools like Sentry. Do not rely on browser console logs or guesswork.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Scaling MediaWiki extensions is not just about writing code that works. It requires thoughtful design, attention to performance, and deep integration with MediaWiki's infrastructure. Avoid expensive operations, defer work to jobs, use caching layers effectively, and always test under real-world load conditions.&lt;/p&gt;

&lt;p&gt;The techniques covered here from internal caching to API optimization and asynchronous job processing form the backbone of reliable and scalable extension development. They will allow your extension to perform under the demands of enterprise wikis, multi-user portals, and global deployments.&lt;/p&gt;

&lt;p&gt;If you want to go deeper and learn how to build and maintain advanced MediaWiki extensions with confidence, download &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/mhmvp" rel="noopener noreferrer"&gt;Mastering MediaWiki Extensions: Beyond the Manual&lt;/a&gt;&lt;/strong&gt;. This guide is packed with proven solutions, patterns, and architecture insights not found in the official documentation.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>webdev</category>
      <category>programming</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Building a Real-Time Notification System in MediaWiki Using Extension Hooks and WebSockets</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Mon, 21 Jul 2025 20:47:52 +0000</pubDate>
      <link>https://forem.com/hexshift/building-a-real-time-notification-system-in-mediawiki-using-extension-hooks-and-websockets-2jlg</link>
      <guid>https://forem.com/hexshift/building-a-real-time-notification-system-in-mediawiki-using-extension-hooks-and-websockets-2jlg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;MediaWiki provides an excellent foundation for collaborative publishing, but it lacks native real-time functionality. Editors must manually refresh pages to check for changes, and administrators are not immediately notified of critical edits or vandalism. This article demonstrates how to build a real-time notification system for MediaWiki using extension hooks, a message broker like Redis, and a WebSocket server. The implementation remains modular and decoupled, enabling flexible integration and scaling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Real-Time Notifications Matter in MediaWiki
&lt;/h2&gt;

&lt;p&gt;In collaborative environments such as knowledge bases, wiki farms, or moderated documentation portals, visibility into changes as they occur is critical. While MediaWiki includes the Echo extension for notifications, it does not provide real-time push functionality. Instead, Echo uses a polling model or relies on email, which introduces latency and reduces responsiveness.&lt;/p&gt;

&lt;p&gt;By integrating a backend message queue with WebSocket delivery, we can push immediate updates to connected users when changes happen on the wiki.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Overview
&lt;/h2&gt;

&lt;p&gt;This solution consists of three major components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A MediaWiki extension that listens to hooks like &lt;code&gt;PageContentSaveComplete&lt;/code&gt; and emits update events.&lt;/li&gt;
&lt;li&gt;A message broker such as Redis, which serves as a relay point.&lt;/li&gt;
&lt;li&gt;A WebSocket server that listens for messages and pushes them to clients in real time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design pattern decouples the wiki from the real-time delivery layer, improving maintainability and performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the MediaWiki Extension
&lt;/h2&gt;

&lt;p&gt;Begin by creating a new extension folder in your MediaWiki installation, for example &lt;code&gt;RealTimeNotify&lt;/code&gt;. Inside this folder, create an &lt;code&gt;extension.json&lt;/code&gt; file to define metadata, classes, and hooks.&lt;/p&gt;

&lt;p&gt;Set the type to &lt;code&gt;extension&lt;/code&gt;, and under &lt;code&gt;Hooks&lt;/code&gt;, declare the hook handler for &lt;code&gt;PageContentSaveComplete&lt;/code&gt;. In &lt;code&gt;AutoloadClasses&lt;/code&gt;, link your PHP class such as &lt;code&gt;RealTimeNotifyHooks&lt;/code&gt; to a path like &lt;code&gt;includes/RealTimeNotifyHooks.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In your hook class, define a static method called &lt;code&gt;onPageContentSaveComplete&lt;/code&gt;. This hook provides access to the edited &lt;code&gt;WikiPage&lt;/code&gt;, the &lt;code&gt;User&lt;/code&gt;, and other contextual information. Capture the page title using &lt;code&gt;$wikiPage-&amp;gt;getTitle()-&amp;gt;getPrefixedText()&lt;/code&gt; and get the editor's username with &lt;code&gt;$user-&amp;gt;getName()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the JSON Message Payload
&lt;/h2&gt;

&lt;p&gt;To push an update to the broker, convert the event into a JSON object with keys such as &lt;code&gt;page_title&lt;/code&gt;, &lt;code&gt;user_name&lt;/code&gt;, &lt;code&gt;timestamp&lt;/code&gt;, and &lt;code&gt;summary&lt;/code&gt;. Use the PHP &lt;code&gt;json_encode()&lt;/code&gt; function to serialize the array.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$data = [ 'page_title' =&amp;gt; $title, 'user_name' =&amp;gt; $username, 'timestamp' =&amp;gt; wfTimestamp( TS_ISO_8601, time() ), 'summary' =&amp;gt; $summary ];&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$message = json_encode($data);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This message will be forwarded to the broker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to Redis
&lt;/h2&gt;

&lt;p&gt;MediaWiki does not ship with built-in support for Redis publishing, so install a PHP Redis client such as &lt;code&gt;phpredis&lt;/code&gt; or &lt;code&gt;predis/predis&lt;/code&gt;. Once installed, use the Redis client inside your hook:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$redis = new Redis();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$redis-&amp;gt;connect('127.0.0.1', 6379);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$redis-&amp;gt;publish('mediawiki:notifications', $message);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line will publish the edit event to a channel named &lt;code&gt;mediawiki:notifications&lt;/code&gt;, which external subscribers can listen to.&lt;/p&gt;

&lt;p&gt;If you prefer reliability and delivery acknowledgment, RabbitMQ is a suitable alternative, using the PHP &lt;code&gt;php-amqplib/php-amqplib&lt;/code&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSocket Server with Node.js
&lt;/h2&gt;

&lt;p&gt;On the subscriber side, run a WebSocket server that connects to Redis and broadcasts messages. One of the simplest implementations uses Node.js and the &lt;code&gt;ws&lt;/code&gt; and &lt;code&gt;ioredis&lt;/code&gt; modules.&lt;/p&gt;

&lt;p&gt;Set up a WebSocket server on port 8080 and connect to the Redis channel. When a message is published to &lt;code&gt;mediawiki:notifications&lt;/code&gt;, the server reads it and sends it to all connected clients.&lt;/p&gt;

&lt;p&gt;In the handler, iterate over all clients in &lt;code&gt;wss.clients&lt;/code&gt;, and for each one that is open, call &lt;code&gt;client.send(message)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This approach allows the WebSocket server to act as a translator between Redis events and browser-based JavaScript listeners.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Frontend Integration
&lt;/h2&gt;

&lt;p&gt;Create a JavaScript file in your extension, such as &lt;code&gt;modules/ext.realtimenotify.js&lt;/code&gt;. This script should be loaded through ResourceLoader.&lt;/p&gt;

&lt;p&gt;Inside the script, open a WebSocket connection to the server:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const socket = new WebSocket('ws://yourdomain.com:8080');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add a listener:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;socket.onmessage = function (event) { const data = JSON.parse(event.data); mw.notify("Page edited: " + data.page_title + " by " + data.user_name, { autoHide: true }); };&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This displays a popup notification to the user when a change is pushed from the backend.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;extension.json&lt;/code&gt;, register this file under &lt;code&gt;ResourceModules&lt;/code&gt; and ensure it loads conditionally based on user preferences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a User Preference
&lt;/h2&gt;

&lt;p&gt;Not all users may want real-time notifications. You can make it configurable using the &lt;code&gt;GetPreferences&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;Inside your extension class, implement &lt;code&gt;onGetPreferences&lt;/code&gt;. Add a boolean toggle named &lt;code&gt;enable_realtime_notify&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, in &lt;code&gt;BeforePageDisplay&lt;/code&gt;, check the user's preference:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if ( $user-&amp;gt;getOption( 'enable_realtime_notify' ) ) { $out-&amp;gt;addModules( 'ext.realtimenotify' ); }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This ensures that only users who have opted in receive notifications and frontend load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging and Debugging
&lt;/h2&gt;

&lt;p&gt;To assist with troubleshooting, add a custom log group in &lt;code&gt;LocalSettings.php&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$wgDebugLogGroups['realtimenotify'] = '/var/log/mediawiki/realtimenotify.log';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then use &lt;code&gt;wfDebugLog&lt;/code&gt; in your hook:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;wfDebugLog('realtimenotify', "Notification sent for " . $data['page_title']);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To debug Redis, use the command-line client: &lt;code&gt;redis-cli SUBSCRIBE mediawiki:notifications&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This confirms whether messages are published as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication and Security
&lt;/h2&gt;

&lt;p&gt;When exposing a WebSocket server, always consider access control. For private wikis, you may want to authenticate WebSocket connections via short-lived tokens or signed URLs.&lt;/p&gt;

&lt;p&gt;A simple token can be generated server-side and passed via a query parameter:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const socket = new WebSocket('ws://yourdomain.com:8080?token=xyz');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The WebSocket server should validate the token against the MediaWiki session or via a custom API call.&lt;/p&gt;

&lt;p&gt;Avoid sending private user information in payloads. Sanitize summaries and usernames before broadcasting. For additional protection, consider using HTTPS with a reverse proxy that terminates TLS and performs access control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling the Architecture
&lt;/h2&gt;

&lt;p&gt;For high-traffic wikis, you may need to scale components independently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Redis Cluster or Sentinel for high availability&lt;/li&gt;
&lt;li&gt;Run multiple WebSocket server instances and load balance them with Nginx or HAProxy&lt;/li&gt;
&lt;li&gt;Persist messages temporarily in queues if no clients are connected&lt;/li&gt;
&lt;li&gt;Integrate analytics or logging services to monitor delivery latency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RabbitMQ with durable queues and dead-lettering provides more reliability than Redis pub/sub. Choose the broker based on your tolerance for message loss and operational complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;This system does not guarantee delivery unless a reliable queue system is used. Redis pub/sub drops messages if no subscriber is listening. The frontend implementation uses the browser's native WebSocket interface and may not reconnect automatically on failure unless explicitly coded.&lt;/p&gt;

&lt;p&gt;Also note that browser notifications via &lt;code&gt;mw.notify&lt;/code&gt; are transient and not stored. For persistent alerts, you would need to integrate this system with the Echo extension or a database-backed log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Real-time notifications can greatly improve the responsiveness and interactivity of your MediaWiki installation. By combining core extension hooks with Redis, WebSockets, and simple JavaScript, you can enable instant feedback for editors and admins alike. This system is especially useful in dynamic or moderated wikis where knowing about changes the moment they happen is essential.&lt;/p&gt;

&lt;p&gt;If you want to go deeper into advanced MediaWiki extension development — including job queues, caching strategies, hook orchestration, and deployment tooling — check out &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/mhmvp" rel="noopener noreferrer"&gt;Mastering MediaWiki Extensions: Beyond the Manual&lt;/a&gt;&lt;/strong&gt;. This expert-level guide explains how to push MediaWiki beyond its defaults and build scalable, powerful functionality that goes far beyond what the manual provides.&lt;/p&gt;

</description>
      <category>websockets</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Boost Your MediaWiki with Custom Parser Functions and Hooks Integration</title>
      <dc:creator>HexShift</dc:creator>
      <pubDate>Mon, 21 Jul 2025 20:42:19 +0000</pubDate>
      <link>https://forem.com/hexshift/boost-your-mediawiki-with-custom-parser-functions-and-hooks-integration-7dh</link>
      <guid>https://forem.com/hexshift/boost-your-mediawiki-with-custom-parser-functions-and-hooks-integration-7dh</guid>
      <description>&lt;p&gt;Custom parser functions and hooks are powerful tools for MediaWiki developers aiming to extend functionality with precise control. Leveraging these mechanisms helps you integrate deeply with the core while maintaining clean, maintainable code. This detailed tutorial walks through creating a custom parser function and hook integration in MediaWiki, and explains best practices around security, performance, and maintenance.&lt;/p&gt;

&lt;p&gt;A parser function in MediaWiki allows you to introduce new syntaxes in wiki markup. A simple example is building a function that calculates and displays the square of a number. You register the function via &lt;code&gt;extension.json&lt;/code&gt;, mapping a key such as "square" to a PHP handler class. In your class method, you accept the parser, frame, and parameters. Use &lt;code&gt;intval&lt;/code&gt; to sanitize input and call &lt;code&gt;return intval( $params[0] ) * intval( $params[0] )&lt;/code&gt;. Registering it makes the wiki recognize syntax like &lt;code&gt;{{#square: 5}}&lt;/code&gt; and output “25”.&lt;/p&gt;

&lt;p&gt;Creating a hook requires a similar setup. Hooks allow your code to run at specific points, such as when a page is displayed or when content is saved. Registering involves adding entries in &lt;code&gt;extension.json&lt;/code&gt;, for example &lt;code&gt;SkinTemplateNavigation:showView&lt;/code&gt;. Inside the hook handler you can modify the navigation links or add custom links. Use OutputPage methods with caution, and ensure you return true to allow other handlers to run.&lt;/p&gt;

&lt;p&gt;Let us build a combined use case. Suppose you want to add a feature that logs the length of content saved and displays a warning if a threshold is exceeded. Start by writing a parser function &lt;code&gt;lengthWarning&lt;/code&gt; that returns an empty string during rendering, but registers the value in parser cache. Then register a &lt;code&gt;PageContentSaveComplete&lt;/code&gt; hook. Inside the hook you access &lt;code&gt;$content = ContentHandler::getContentText( $contentObj )&lt;/code&gt;. Use &lt;code&gt;strlen&lt;/code&gt; to calculate length. If length exceeds a threshold (for example 20000 characters), write a log entry to a custom table or logging channel. Use &lt;code&gt;MediaWikiServices::getInstance()-&amp;gt;getDBLoadBalancer()-&amp;gt;getConnectionRef( DB_PRIMARY )&lt;/code&gt; to record length. You can also call &lt;code&gt;$out-&amp;gt;addHTML&lt;/code&gt; or &lt;code&gt;$out-&amp;gt;addWarning&lt;/code&gt; to surface a notice on the next page view.&lt;/p&gt;

&lt;p&gt;You will need to define a database table for tracking saved lengths. Place SQL schema in &lt;code&gt;sql/lengthlog.sql&lt;/code&gt; and register in &lt;code&gt;extension.json&lt;/code&gt; under &lt;code&gt;loadExtensionSchemaUpdates&lt;/code&gt;. This ensures maintenance/update.php executes your table creation code.&lt;/p&gt;

&lt;p&gt;Allow configuration by adding settings in &lt;code&gt;extension.json&lt;/code&gt;, such as &lt;code&gt;"LengthWarningThreshold": 20000&lt;/code&gt;. Use ConfigFactory to load with &lt;code&gt;MediaWikiServices::getInstance()-&amp;gt;getConfigFactory()-&amp;gt;makeConfig( 'myextension' )-&amp;gt;get('LengthWarningThreshold')&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Testing is vital. Write unit tests for your parser function in &lt;code&gt;tests/phpunit/ParserFunctionTest.php&lt;/code&gt;, and simulate hook handling in &lt;code&gt;tests/phpunit/LengthWarningHookTest.php&lt;/code&gt;. Use mocks for database and content, and verify that logging occurs when threshold breached and does not occur otherwise.&lt;/p&gt;

&lt;p&gt;Performance matters. Use &lt;code&gt;wfDebugLog&lt;/code&gt; to record debug messages only when needed. Wrap database writes in conditionals and avoid repeated writes during transactional saves. Use object cache to reduce redundant queries.&lt;/p&gt;

&lt;p&gt;Register your extension with proper namespace in &lt;code&gt;extension.json&lt;/code&gt;, add i18n for messages, and document parser usage and hook behavior. Provide example markup in documentation pages.&lt;/p&gt;

&lt;p&gt;Distribute your extension with version control, semantic version tags, and follow MediaWiki coding standards. Encourage community feedback and iterate on code.&lt;/p&gt;

&lt;p&gt;This walkthrough gives you a robust foundation for building custom parser functions and hooks in MediaWiki. These patterns pave the way for powerful yet maintainable enhancements. For more advanced integration patterns, caching strategies, and best practices, check out &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/mhmvp" rel="noopener noreferrer"&gt;Mastering MediaWiki Extensions: Beyond the Manual&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating High Performance Data APIs with MediaWiki and ServiceLayer Patterns
&lt;/h2&gt;

&lt;p&gt;MediaWiki serves well as both a publishing platform and a backend content store. Exposing structured content via custom RESTful APIs allows external applications, mobile clients, or chatbots to access page data in structured JSON. Implementing a high performance API in MediaWiki requires adhering to ServiceLayer patterns, handling caching, routing, security, and output formatting carefully. This article covers building such APIs step by step.&lt;/p&gt;

&lt;p&gt;Service classes in MediaWiki hold reusable logic separated from controllers. Define your service in &lt;code&gt;src/ServicePageApi.php&lt;/code&gt;. This class accepts a Title object and extracts data such as title text, summary, categories, revision ID, and metadata by calling &lt;code&gt;PageProps::getProperties&lt;/code&gt;. It returns an associative array. Register your service by adding an entry to extension.json under &lt;code&gt;Services&lt;/code&gt;, mapping an interface to your class.&lt;/p&gt;

&lt;p&gt;Create a controller in &lt;code&gt;src/PageApiController.php&lt;/code&gt;. Extend &lt;code&gt;ApiBase&lt;/code&gt;. Implement &lt;code&gt;execute()&lt;/code&gt; to parse input via &lt;code&gt;$params = $this-&amp;gt;extractRequestParams()&lt;/code&gt;, get a Title via &lt;code&gt;Title::newFromText( $params['page'] )&lt;/code&gt;, call the service layer via MediaWikiServices, and output JSON with &lt;code&gt;$this-&amp;gt;getResult()-&amp;gt;addValue( null, $this-&amp;gt;getModuleName(), $data )&lt;/code&gt;. Register parameters and permission checks so only read permission is needed.&lt;/p&gt;

&lt;p&gt;Add routing via &lt;code&gt;$wgRestConfig['pageapi']&lt;/code&gt;. Use &lt;code&gt;'{page}' =&amp;gt; 'MyExtension\\PageApiController::execute'&lt;/code&gt;. This enables API endpoints like &lt;code&gt;/api/rest_v1/pageapi/FrontPage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To handle reliability and performance integrate caching. Use FastFileCache or MediaWiki object cache. For GET requests, use &lt;code&gt;$cache-&amp;gt;getWithSetCallback('pageapi:'.sha1($title-&amp;gt;getFullText()), function () use ($title, $service) { return $service-&amp;gt;getPageData( $title ); }, 600 );&lt;/code&gt;. This caches JSON output for 10 minutes.&lt;/p&gt;

&lt;p&gt;Protect from unauthorized access by registering permissions such as &lt;code&gt;api-read&lt;/code&gt;. Apply &lt;code&gt;$this-&amp;gt;checkPermissions()&lt;/code&gt; and use CSRF tokens for write endpoints. Configure API module rights in &lt;code&gt;extension.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Document your API using Swagger or OpenAPI. Register documentation entry by adding Swagger YAML in &lt;code&gt;module&lt;/code&gt; metadata with descriptions, parameter schemas, and examples. Provide reference docs on a wiki page.&lt;/p&gt;

&lt;p&gt;Test your API with PHPUnit and integration tests. Use &lt;code&gt;$this-&amp;gt;runApi( 'get', [ 'page' =&amp;gt; 'Main Page' ] )&lt;/code&gt; and verify JSON structure. Simulate cache flows by clearing object cache or setting stale values.&lt;/p&gt;

&lt;p&gt;For batch data extraction, implement pagination with continuations. Accept parameters such as &lt;code&gt;limit&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt;. In caching logic, key results accordingly. Avoid stale data by purging cache when relevant changes occur—use &lt;code&gt;Hook::register('PageContentSaveComplete', ...)&lt;/code&gt; to clear cache for edited titles.&lt;/p&gt;

&lt;p&gt;Monitor usage with logging. Add &lt;code&gt;$wgDebugLog&lt;/code&gt; entries for API hits, cache metrics, and errors. Use Prometheus exporter extension to expose metrics.&lt;/p&gt;

&lt;p&gt;Extend your API to support embedded HTML or charts. For example, create a second endpoint that returns HTML rendered via &lt;code&gt;Parsoid&lt;/code&gt; by calling Rest API internally. Cache results separately.&lt;/p&gt;

&lt;p&gt;Register ResourceLoader modules for any UI components in your API documentation. Provide interactive playground pages under &lt;code&gt;Special:MyExtension&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Deploy your extension with semantic versioning and provide clear upgrade instructions for new endpoint versions. Use &lt;code&gt;hookLoadExtensionSchemaUpdates&lt;/code&gt; for any schema changes.&lt;/p&gt;

&lt;p&gt;By modularizing logic into service layers, handling cache, and creating robust controllers, your MediaWiki installation can expose clean, performant, secure JSON APIs. These APIs serve as reliable data sources for downstream systems. Explore &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/mhmvp" rel="noopener noreferrer"&gt;Mastering MediaWiki Extensions: Beyond the Manual&lt;/a&gt;&lt;/strong&gt; for deep dives into API versioning strategies, token revocation, and advanced caching methods.&lt;/p&gt;




&lt;h2&gt;
  
  
  Orchestrating MediaWiki Job Queues for Scalability and Background Processing
&lt;/h2&gt;

&lt;p&gt;MediaWiki job queues enable delayed execution of expensive or asynchronous tasks. Using job queues effectively improves page response times and allows background processing at scale. This tutorial explains how to define custom jobs, configure queue runners, monitor performance, and integrate priority logic.&lt;/p&gt;

&lt;p&gt;A job is defined by implementing MediaWiki’s Job interface or extending Job. Define your custom job in &lt;code&gt;src/MyTaskJob.php&lt;/code&gt;. Store payload in the constructor. Implement &lt;code&gt;run()&lt;/code&gt; to access necessary services, perform tasks such as sending emails, regenerating caches, or external API calls. Return true on success or false to retry.&lt;/p&gt;

&lt;p&gt;Register the job in &lt;code&gt;extension.json&lt;/code&gt; under Jobs section. Use a unique label and PHP class mapping.&lt;/p&gt;

&lt;p&gt;To enqueue a job, inject the job queue service via &lt;code&gt;MediaWikiServices::getInstance()-&amp;gt;getJobQueueGroup()&lt;/code&gt; and call &lt;code&gt;enqueue&lt;/code&gt; with group name and job instance. The job will execute asynchronously.&lt;/p&gt;

&lt;p&gt;Configure your cron or systemd to run &lt;code&gt;runJobs.php&lt;/code&gt;. To prioritize certain groups, configure &lt;code&gt;$wgJobTypes\Tests&lt;/code&gt; with weights. For example assign group 'high' weight 100 and 'low' weight 10.&lt;/p&gt;

&lt;p&gt;Batch enqueueing is possible. Use &lt;code&gt;enqueueBatch&lt;/code&gt; with arrays of jobs to reduce lock contention.&lt;/p&gt;

&lt;p&gt;Monitor job queue status via database table job. Inspect delays and backlog with queries. For long running jobs, consider partitioning work across multiple job instances and using continuation patterns.&lt;/p&gt;

&lt;p&gt;Protect against DB contention by using transactions in run(), and respecting retry limits. Use &lt;code&gt;runOnUpdatesOnly&lt;/code&gt; for jobs triggered by update scripts to avoid race conditions.&lt;/p&gt;

&lt;p&gt;Implement test suites under &lt;code&gt;tests/phpunit/MyTaskJobTest.php&lt;/code&gt;, mocking database and external services. Use InMemoryCache to simulate logic.&lt;/p&gt;

&lt;p&gt;For real time error reporting, add &lt;code&gt;$wgDebugLog['myextension'][] = 'MyTaskJob';&lt;/code&gt; entries. Notify admins with email or webhook on job failures.&lt;/p&gt;

&lt;p&gt;Scale job workers horizontally. Use multiple CLI workers. Ensure each node connects to same job table or Redis backend. Use &lt;code&gt;$wgJobTypeConf&lt;/code&gt; to distribute load.&lt;/p&gt;

&lt;p&gt;Job queue integration improves user experience by deferring non critical work. Tasks like sitemap generation, file cleanup, or API ingest become manageable in background.&lt;/p&gt;

&lt;p&gt;For advanced patterns such as long-running tasks, failure escalation, transactional retries, and cross site job coordination, see &lt;strong&gt;&lt;a href="https://asherbaum.gumroad.com/l/mhmvp" rel="noopener noreferrer"&gt;Mastering MediaWiki Extensions: Beyond the Manual&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>wiki</category>
      <category>parser</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
