Category: Work

  • What Happens When You Move 1,000 Servers to cgroup v2

    What Happens When You Move 1,000 Servers to cgroup v2

    We’ve been running a large-scale Kubernetes cluster on Scientific Linux 7 for years. It works. It’s stable. Nobody complains. So naturally, we decided to migrate everything to Debian 12.

    I’m leading this migration at Automattic, and it involves moving over a thousand servers to a completely new OS stack. New kernel, new cgroup version, new assumptions about how your containers actually use resources. The goal is straightforward: modern infrastructure, better tooling, fewer surprises down the road.

    The surprises showed up immediately.

    The Problem Nobody Warns You About


    cgroups are the Linux kernel feature that controls and limits how much CPU, memory, and other resources a process can use.

    Here’s the thing about cgroup v1 (the old way): CPU limits are soft. If your container says it needs 2 CPUs but the host has 16 CPUs sitting idle, the kernel lets your container burst way past its limit. Everyone’s happy. Your monitoring looks clean. Your apps run fine.

    cgroup v2 (the new way) doesn’t do that. CPU limits are hard. You asked for 2 CPUs? You get 2 CPUs. Doesn’t matter if the host is 80% idle. The CFS quota enforcer will throttle your container the moment it tries to exceed its allocation.

    This distinction matters a lot more than it sounds like.

    Comparison of CPU throttle rates between cgroup v1 (Scientific Linux 7) and cgroup v2 (Debian 12), showing respective rates of 0.32% and 42.6%, along with syn drops and queue overflows.

    0.32% to 42.6%

    We had an nginx ingress controller handling external traffic for hundreds of millions of requests. The config was simple: 4 nginx workers, 2 CPU limit. On Scientific Linux 7, the throttle rate was 0.32%. Basically nothing. Health checks passed. Latency was fine. Life was good.

    On Debian 12 with cgroup v2, the same config produced a 42.6% throttle rate. The host CPU was 76.9% idle. Plenty of headroom. But the container couldn’t touch it.

    Here’s what happened in sequence:

    1. 4 nginx workers competing for 2 CPUs worth of quota
    2. Workers hit the CFS bandwidth limit and get throttled
    3. Throttled workers can’t call accept() fast enough
    4. TCP listen backlog (default 511) overflows
    5. Kernel starts dropping SYN packets
    6. Health checks time out
    7. Pod restarts

    Same code. Same config. Same hardware. Completely different behavior.

    It Wasn’t Just Nginx

    Once we started looking, the pattern was everywhere. Workloads that had been “fine” for years were suddenly gasping for air:

    • A core platform service: 99% throttled
    • A search task manager: 100% throttled in prod, 99% in dev
    • A log pruning job: 100% throttled
    • Stream processing workers: 97-100% at their memory limits
    • Various sidecars (auth proxies, metrics exporters): 95-100% memory utilization

    None of these had ever raised an alert on Scientific Linux 7. They were all quietly bursting past their stated limits, and nobody knew because nobody had a reason to look.

    The Fix

    The fix itself is boring. Bump the CPU limit to match the actual workload. For the nginx ingress, we went from 2 to 8 CPUs (2 per worker). Throttle rate dropped to 0.4%. Health checks passed. Done.

    The interesting part is the discovery process. You can’t just do a blanket “double all the limits” because some workloads genuinely don’t need more. You have to look at each one, understand what it’s actually doing, and set appropriate limits based on real usage instead of inherited guesses from three years ago.

    We ended up writing a tracker script that generates tab-separated output we could paste into a spreadsheet. For each workload: current CPU request, current limit, actual throttle rate, memory utilization. Sort by throttle rate descending. Start at the top and work your way down.

    The Lesson

    If you’re planning a migration from an older Linux distribution to something running cgroup v2 (which is basically everything modern at this point: Debian 12+, Ubuntu 22.04+, Fedora, RHEL 9), here’s what I’d tell you:

    Audit your resource limits before you migrate, not after. Every container that’s been happily bursting on cgroup v1 is going to get a rude awakening on v2. The workload hasn’t changed. The enforcement has.

    Run something like this on your current cluster:

    # Check container CPU throttle rates
    kubectl top pods --containers -A | sort -k4 -rn | head -20

    Or better yet, if you have Prometheus:

    rate(container_cpu_cfs_throttled_periods_total[5m])
    /
    rate(container_cpu_cfs_periods_total[5m])
    * 100

    Anything above 10-15% is a candidate for a limit bump. Anything above 50% is going to have a bad time on cgroup v2.

    The Bigger Picture

    This was just one of the problems we hit during the migration. There were kernel regressions that spawned 8,000+ kworkers and pegged a node at load 8,235 for 46 minutes. There were firewall rule asymmetries that broke cross-node metrics scraping. There were StatefulSet race conditions where Kubernetes would grab the wrong persistent volume if you weren’t fast enough.

    Each one of those is its own story. But the cgroup v2 throttling issue is the one I think most people will run into first, and it’s the easiest to miss because everything looks fine until it suddenly doesn’t.

    The migration is still ongoing. Over a thousand servers, hundreds of stateful workloads, and a lot of tar pipes between machines that can’t SSH to each other. I’ll write more about it as we go.

    If you’re doing something similar, I’d love to hear about it. Hit me up on Twitter/X or LinkedIn.

  • What I’m using

    What I’m using

    One of the challenges of working remotely is that you lose the benefit of “over-the-shoulder” learning. You don’t get to see what tools your coworkers are using or pick up on small productivity hacks just by being near them. So, I wanted to write this post to share some of the stack and software I use every day – my daily drivers – in hopes that it might help someone else out there level up their workflow or solicit feedback on what you are using and level up mine 🙂

    Basic Stack

    I use a 16″ Macbook Pro with an M3 chip (48G RAM/1TB SSD) as my primary work machine. I find Macs to be unparalleled in laptop user experience. The keyboard is excellent, the trackpad second to none, the display is great, and the fingerprint reader integrating with everything is an awesome bonus.

    I used to be a guy that had to have a “command center” – multiple monitors, a fancy mechanical keyboard, an expensive mouse, and everything arranged just so. But I found that I lost a little productivity if I was at a meetup, traveling, in a data center, or really doing anything except being in my command center. I just accepted this – I’m less productive when I’m not at home.

    Then I talked to a colleague, Demitrious Kelly one late night, and he was telling me about how he only uses his MacBook because “it’s the tool I always have”. This statement caught me completely off guard, because I expected someone like him to have a crazy setup to produce the kind of work he does – tiene mucho talento. But he challenged me to try using only the Mac.

    That was about six years ago, and I’ve exclusively used my MacBook for work since then with nothing else, no peripherals. Since then, it doesn’t matter if I’m at home, on a plane, at a conference, or in a car – my output is the same. That simple statement revolutionized the way I work:

    I use Firefox as my preferred browser because it’s open source and Google has enough of my data without including everything from my browser. Mozilla changed the longstanding “Copy Link Address” hotkey from “A” to “L” in Firefox 88 which really, really disrupted my workflow, so I wrote an extension to change it back which I can’t live without: https://addons.mozilla.org/en-US/firefox/addon/link-copy/. In addition to this extension, I use the Alfred Browser Integration (more on that later) and Proxy SwitchyOmega which is a tool that allows you to create proxy rules based on hostname or IP which is critical for systems tasks like interacting with servers via IPMI… and that’s it for browser extensions.

    I use iterm2 as my terminal emulator because it kicks serious ass and is easily one of the best free pieces of software I’ve ever used. Some configurations I like for using it include setting the terminal backscroll to 50,000 lines (from 1,000) profiles > {profile} > terminal, a hotkey to send iterm2 to the back of all windows or bring it to the front (I use control + z), and this tab style arrangement for windows:

    I use ctrl+tab to cycle through the tabs or option + {number} to jump to a specific window. You can do all kinds of other cool stuff with iterm2 as well, broadcast commands to all windows, anything you can imagine really. It’s really well designed software and I highly recommend donating to the developers for the incredible gift they have provided nerds everywhere simple smile.

    I use zsh as my shell since it’s the default in MacOS (though I write all my scripts in bash) and some small customization via oh-my-zsh but really only for visual stuff like easier to read text and git information on my prompt:

    In general, I try REALLY HARD to try and stick with the defaults wherever possible. This is because I work on servers and docker containers and kuberenetes pods and other remote hosts where the state and configuration of said host machine is often unknown and may not even be modifiable at all. So, much like the laptop theory, I try to learn and get proficient with the tools I will always have. I don’t need the fancy stuff from oh-my-zsh to work on a remote machine, but I might suffer if I spent time getting used to fzf for file browsing, for example.

    This of course brings me to my default editor. I use vim:

    Vim is pretty much available everywhere by default and it always works the same – it’s the tool I always have. This is good. On my Macbook I have shellcheck integrated, but it’s not really a requirement — and that’s it for plugins. For vim preferences, I’ll use the defaults in most cases or some very basic .vimrc customization if it’s a long term host like the servers in my homelab, but again, I try not to do too many things that will make me useless or less productive if I don’t have them. Here’s a link to my very simple/basic dotfiles.

    Software

    One recurring theme about the software I use – I try to avoid SaaS at all costs. In general, if I can’t pay for it once and have it forever – options to pay to upgrade major versions are okay if the software is good enough – but paying monthly or it stops working? no. If I can’t find this or something that doesn’t need my specific need, I usually write a small program that does it. For example:

    HackerNewsIcon – A macOS menu bar app I wrote that monitors Hacker News for top posts. Displays trending articles and notifies you when a new post reaches your set score threshold:

    My colleague Chris Laffin somehow found this gem of a text editor app called TextMate which is another incredible piece of free software probably only second to iterm2 in the value it provides for its price. He put me and a few other systems folks onto it and we’ve been using it ever since. Native, performant, awesome. I use this like a scratch pad to hold temporary information or perform work that works better in a visual environment where it’s a better buffer than vim – and there are usually plenty of use cases for this: log files, for example.

    Alfred – can’t live without this one, and I know most of my fellow Automatticians already use this or know about it. Alfred is basically my go-to for everything. I use it as a spotlight replacement and basically as the interface to my machine in parallel with my terminal. I can press command+space and instantly open any file on my system, run a translation, run something through an LLM (locally via ollama or remote), search anything in MGS/Slack/Matticspace, lock my machine… it’s basically how I use my computer. I also have hundreds of snippets for anything I have to type more than a few times including long terminal commands, common troubleshooting instructions, hell, even typing wp; expands to WordPress.com simple smile. As mentioned previously, I also have the browser integration installed so I can search any of my open browser tabs through this interface. As anyone who has went down a troubleshooting rabbit hole knows, this is a game-changer. Need to go back to that collins tab you were looking at 20 tabs ago? command + space then tab collins — game. changer.

    Adium – I use this as a WordPress.com Jabber client to monitor p2s and get an instant notification when a new post, comment, etc is propagated. I get a lot of comments on how fast I reply or react to posts. This is my secret sauce 🙂

    Magnet – I use this as a window manager. In general my screen is chaotic and and not all organized, but I have the magnet keyboard shortcuts memorized to quickly arrange something side by side or in quadrants if needed. I think MacOS might do window management by default now, but I’m used to Magnet and it was a one time purchase / not SaaS so I reap the benefit of being used to it and owning it forever 🙂

    Pixelmator Pro – It’s like photoshop except maybe better and it was a one time purchase 🙂 — totally worth it. I use it for all my image generation needs. Well, almost all…..

    ffmpeg – I mean this thing does everything. Video conversion, image conversion, video to gif, all kinds of other weird stuff. You may not know how to do it, but ffmpeg supports it

    Amphetamine – this thing is cool. It keeps your mac display awake for however long you set it. I love software like this. It does one thing, does it well and does it reliably. I don’t want to modify my mac settings to do stuff, like keep the mac from sleeping when I’m running a time machine backup, so I set Amphetamine to 6 hours and lock my machine. Easy. Done. Never thought about it twice.

    k9s – k9s is a TUI interface for managing a kubernetes cluster. This thing is invaluable and every day I pay homage to my colleague Chad or teaching me about it. I used to use Lens, but then they wanted money so I converted and haven’t looked back:

    Wireshark – The industry standard tool for analyzing packets. Use it all the time in debugging.

    ntfy.sh – This thing is a pretty cool notification app. I use it sometimes to send non-sensitive information to my phone. do thing; when done curl -d "$HOSTNAME thing is done" ntfy.sh/rudy_notification and I get a notification on my phone when thing is done. Cool.

    Textual 7 – I use textual as do most other folks in systems at Automattic to interface with IRC. It’s a native app and I’ve tried lots of others and this thing seems to be the best. Per channel notifications based on string matches is the number one thing that makes this thing useful to me. The interface is also compact and easy to use.

    Some other things obviously should go without saying – like yes I’m using Slack as my ephemeral communication tool and Homebrew as my Mac package manager. Yes I use Spotify to listen to music (one of the only app-based subscriptions I have!!!).

    And that’s pretty much it. One of the first concepts taught when I was learning how to program computers was KISS, or, Keep it Simple, Stupid! and I’ve tried to carry this advice throughout my career and life when it comes to tech. Abstraction kills, simplicity scales, always apply first principles to every problem.

    I would love to field questions about anything I’ve written here or hear from you about the software you can’t live without. Feel free to DM me or, even better, leave a comment here to discuss so all may benefit 🙂

    This post was not written with the assistance of AI 🙂

  • #wwwp5K!

    I’m out here in Washington, D.C. for the next few weeks for work, but when I saw my work was putting on a 5k event for charity ( #wwwp5k ) you know I had to find the time:

    I love working for a company that puts these types of events on and can’t wait to participate in more!

  • Chi City & Maine 2020

    Chi City & Maine 2020

    I was recently in Chicago for work then met up with my wife & family in Maine. I didn’t get out much in Chicago, I was pretty busy with work – but when I did get out, here are the pictures I snapped:

    Left side view of downtown Chicago from the hotel, Lake Michigan in the back
    Right side view of downtown Chicago from the hotel
    View of the Chicago skyline from a friend’s house that I met up with for lunch
    Dearborn Station in Downtown Chicago
    The Chicago Tribune was right behind the place I rented a U-Haul from 😄
    Hotel Lounge
    Dearborn St. Downtown Chicago
    Chicago Stock Exchange & CoreSite data center
    CoreSite Data Center
    “Epic Burger” in Downtown Chicago. One of the best burgers I’ve ever had.
    Civil unrest and covid-19 had a lot of the city closed down and/or boarded off
    Breakfast @ Meli Cafe

    That was pretty much it for Chicago. Also have a few pictures from Maine. It was an amazing time of year to visit as the leaves were changing over and the weather wasn’t cold yet.

    The leaves were beautiful
    The dock
    Walks through the woods
    Fishing on a paddle boat with my trusty companion 🐕
    Out on the boat
    Caught a bunch of Pickrel and Yellow Perch
    Walks through the woods
    Bar Harbor, Maine
  • Svelte is cool

    Svelte is cool

    I am always looking into other languages and frameworks for learning and new projects. I have been more interested in the web space lately after porting Draw! from C to web using Web Assembly, and have been curious how other tools in the space have been progressing as well.

    Not to begin a holy war, but I have never been a fan of React. Aside from the super-mega-corporation thing, I have never found it intuitive, easy, or fun to use. Angular? *laughs* 🤣. I have been seeing Vue seemingly becoming more popular as of late.

    So on Friday in the #developers Slack channel at work I asked a simple question:

    A very interesting discussion about frameworks and web development in general ensued. I love chatting about theory, opinions, and perspective on all things programming, and it was really cool to hear folks whom I consider some of the top developers in the industry contribute to the discussion.

    Along the way, two of my teammates brought up https://svelte.dev/. I had not seen it before, and the second I clicked the link I thought: “this is so cool!” I thought the syntax looked pretty straightforward, it looked intuitive, and I love the idea of less boilerplate *cough* react *cough* and no virtual DOM.

    While we talked about lots of other stuff during the discussion, I decided to spend part of my weekend refactoring one of my web apps – https://strong.rudyfaile.com – using Svelte. Previously this application was written in PHP (and I blogged a bit about it here.)

    I had been thinking about refactoring the program for some time, mainly because it doesn’t really need to make a request to the server after it loads since all of the data could be available on the front end, so sending a form -> POST request every time the program generated simply wasn’t ideal. So this application was a prime candidate for the work.

    Here was sort of how the old architecture worked. A full reload was required every time the user needed new information from the application:

    And here was the intention for the refactor:

    I found it surprisingly easy and straightforward to learn Svelte. I would honestly say there wasn’t even that much of a learning curve. I didn’t really watch a tutorial or dig too deep into it. I just checked out some of the examples and built a brand new project with npm and started hacking away, occasionally checking the Svelte docs to achieve a desired result.

    As much as I hate the bloatiness and general misuse and abuse of npm, it is pretty nice to start a project with a one-liner and have a live hot-reload development server up and running.

    so easy!

    Not too long later I had the entire app done and ready to replace the PHP app on the server. Building for production was trivial with npm run build – the kicker? The built files to be hosted on the web server were only .10Mb (100 kb!) larger than the previous files on the server!!

    Now that’s a bloat I can get behind! While I don’t think I’ll be npm install savemeplz for every single project in the future, I definitely will be using Svelte again sometime soon. Stay tuned 🤠!

  • Building an “easy” web application

    Building an “easy” web application

    I decided to spend my Fourth of July weekend transforming a small Python utility I wrote a couple of years ago for work. The idea was simple: make the tool more accessible for co-workers who use it by turning it into a web application.

    The premise of the tool is extremely simple. It automates the sending of multiple cURL requests to a WordPress site’s xmlrpc.php file with some extra QOL features.

    The purpose of automating the sending of multiple requests is that a single cURL request may succeed, but the WordPress mobile app and Jetpack do not make single requests – they make many requests and need to be in constant communication with that file. A single request might succeed, but many can fail due to rate limiting, bandwidth or other hosting limitations. It is impossible to fully diagnose a possible XML-RPC issue without performing a test like this.

    The utility works just fine, but I thought converting it to a web app would make it easier for folks to use. My first thought was to simply write a PHP script to make the POST request then return the results to the client. It probably would have taken all of 30 minutes but I thought “nah that’s too much work for a simple app….” So I thought I’ll just port the Python script into a web app using a Python web framework. Django is far too much for something like this, so I started looking at Flask. Even Flask seemed a bit overkill for a one-file project; thankfully there’s Bottle which is a “micro-framework” similar to Flask.

    I decided to spin up a Bottle app which is ridiculously easy and had a working version of the script running on a web page in about an hour.

    It worked just fine, but I wasn’t sure I liked the idea that the user would have to wait during the request for the script to complete all n number of requests before the results page loaded. I also thought that JavaScript might be a better solution in general: I could just make the requests via JavaScript and append the results to the DOM as they came in. I wouldn’t even need a server component. It would be so simple…

    The first thing I did was re-write the request using JavaScript’s Fetch API. This took a little while because I needed to refresh on Async Functions and Promises. I feel like every time I look at JavaScript it’s different 😭. After translating the request to a JavaScript acceptable request:

    let mySite = document.getElementById('siteURL');
        
        let myRequest = await fetch(mySite, {
            headers: {
                "Content-Type": "text/xml",
                "User-Agent": "Jetpack by WordPress.com",
            },
            body : '<?xml version="1.0"?><methodCall><methodName>demo.sayHello</methodName><params></params></methodCall>',
            method: "POST",
        });

    The next step was to wrap it into an Async function for looping:

    const MyAsyncFunc = async () => {
    event.preventDefault(); //don't reload the page
    }

    And then wrap the previous code into a loop and append the results to the DOM.

    const MyAsyncFunc = async () => {
    event.preventDefault(); //don't reload the page
    
      for (let i = 0; i < 50; i++){
        
        let mySite = document.getElementById('siteURL');
        
        let myRequest = await fetch(mySite, {
            headers: {
                "Content-Type": "text/xml",
                "User-Agent": "Jetpack by WordPress.com",
            },
            body : "<?xml version=1.0?><methodCall><methodName>demo.sayHello</methodName><params></params></methodCall>",
            method: "POST",
        });
    
        //console.log("Request #" + i + "HTTP Response: " + myRequest.status + " " + myRequest.statusText);
    
        document.getElementById("results").innerHTML += `<div>${"Request # " + (i + 1) + " | HTTP Response: " + myRequest.status + " " + myRequest.statusText}</div>`;
        }
    }

    This worked GREAT except:

    The request was coming from a different origin than the server, so it was blocked by CORS which is a security feature imposed by all modern browsers. From the wiki:

    Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.

    A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos. Certain “cross-domain” requests, notably Ajax requests, are forbidden by default by the same-origin security policy. CORS defines a way in which a browser and server can interact to determine whether it is safe to allow the cross-origin request. It allows for more freedom and functionality than purely same-origin requests, but is more secure than simply allowing all cross-origin requests.

    Cross-origin resource sharing

    Shit. I was never going to be able to be in control of the server from which the client request originated, since this tool in essence needs to be able to query any WordPress site. I understand the security implementations, but was kind of frustrated. I could get exactly what I needed in one cURL request, now I had to find a way to work around this. After some discussion on the Handmade Network, I confirmed that the request could be made from node or another tool on the server where CORS doesn’t exist for the request to the target WordPress site, and I would control the CORS between the client and the server.

    This quickly became more complicated than it needed to be. I could have just run the information through the back end and load it into a new route but that would be just like the Python solution. The idea was to run the request async and append the results to the DOM.

    Of course, the actual request would look something like this:

    Except it’s even more complicated because you can’t just pass something to the server like that and get it back asynchronously…. you have to set up an API! So I set up a small REST API to receive a GET request appended to the URL as the URL. Then sent that URL off in a fetch request, then sent the promise back to the client as the response data:

    app.get("/:url", (req, res, next) => {
        var recievedURL = req.params.url;
        console.log("Got URL: " + recievedURL);
        fetch(recievedURL, {
            headers: {
                "Content-Type": "text/xml",
                "User-Agent": "Jetpack by WordPress.com",
            },
            body : '<?xml version="1.0"?><methodCall><methodName>demo.sayHello</methodName><params></params></methodCall>',
            method: "POST",
            mode: "cors"
        }).then(data => res.send(data));
        console.log("Sent Data");
    });

    Yeah, it was messy as shit. It was also getting harder and harder to debug as JavaScript has no timeout functionality I would have had to wrap that request in another promise. It was all just so needlessly complicated and frustrating. I kept going back to my command line and running that single cURL request, getting exactly what I needed, and getting pissed.

    Ultimately I decided that the node app + REST API was just more trouble than it was worth. Two packages installed and I had a bloaty node_modules directory with 73 folders and 335 files.

    I hate node.

    Ultimately I said “screw it” and decided the whole API approach for this one-page app was WAY more trouble than it was worth. I would have had to maintain the client, server, and node packages because you know those things have to be updated every 9 minutes or you have a security vulnerability 🙄.

    So, 72 hours later and I was back to where I started, with my simple yet effective one file bottle app. The source is 6kb and can handle what it needs to, the error logging is verbose and it works how I expect it to. The tradeoff? People have to wait 1-30 seconds for the request to complete or timeout, so I added a GIF to help them with the wait:

    Three days wasted. I should have just written the PHP script 😢.

    My friend & co-worker Brooke helped put some simple styling on it (also helped with my workout program design) and I think the final result looks pretty sleek:

    I also got to do all of the fun systems stuff like remember how Apache works, update certbot from ACME v1, and play with the virtual hosts file which is always a good time.

    I spent some serious time on input sanitation and error catching, so it should be interesting to see how people break it 🙂

  • The Krimm

    With 2020 leaving me unsure if the Mayans were off by eight years, I have been doing whatever I can to stay busy. Aside from pouring myself into work, I have been working on my small game Draw! and tackling my project backlog.

    One of the things my wife used to subscribe to was something called “The Skimm”. The Skimm was basically an aggregation of news that would get emailed to you every day. She really liked it, but I thought I could make something better for her. This was in 2015 so in true husband fashion, I took care of it in 2020.

    Introducing, the Krimm

    The Krimm (Kristen + Rudy Skimm) is similar to the Skimm, except heavily customized to my wife’s liking. Every morning at 8:30am, she gets an email with the top three news stories in each category she’s interested in, which includes a summary and a link to the full story. What I like in particular is the sources tend to be diversified, and the lack of images allows me to fit more information on the screen and her to be more objective as she’s choosing which stories look interesting hopefully based on substance rather than imagery.

    How does it work?

    It’s very simple. All I did was SSH into one of my servers and install Jarun’s “googler” utility which I use often and highly recommend. One of the flags on the library is to pull results from news sources only. Perfect.

    From there, I made two simple bash scripts. One to run the utility for what she wants:

    simplicity scales

    and a one-liner to send the content of the generated text file to our emails with the subject “Today’s Krimm! 2020-06-01” (or whatever the date is 🙂) using postfix.

    So, pretty simple. From there I set up a simple cron to run the make_file script at 8:29am at our local time in the system’s time and then I fire off the postfix email script at 8:30am.

    So now, every day at 8:30am my wife gets a customized news feed from Google news consisting of the top 3 stories in the world from different sources based on keywords she’s interested in:

    That’s it?

    That’s it. It took me about an hour start to finish to hack this together, and she is satisfied with the result. I subscribed myself as well because well, hey, it’s pretty useful!

    What else have you been doing?

    Trying to stay sane. I have a really nice post in the works that I’ve been meaning to make about an enlightening conversation I had with one of my co-workers at Automattic. In the meantime, I also had the pleasure of interviewing the lead of the Handmade Network on their podcast:

    Which was very insightful and a lot of fun! Highly recommend the Handmade Network as always. Catch my post on Handmade here.

  • Out with the old, in with the new.

    Out with the old, in with the new.

    I’ve been at Automattic about two years now, and it’s been long past due for me to upgrade my company-issued MacBook Pro. When I first started at Automattic, I opted for the 13″ fully upgraded model. I didn’t want a big and bulky 15″ and I definitely didn’t want the touch bar. I really like tactile keys and the difference in power wasn’t going to be that significant. Plus, it was less bulky.

    My 13″ MBP ended up serving me well in my first two years. Here is a top-shot in all its glory in the machine’s last day of service:

    rudy faile's 13" macbook pro
    Farewell, good buddy 👋

    I was due for a replacement in the middle of this year (2019) but decided to wait because there were rumors of Apple releasing a 16″ model which had numerous improvements over the existing 15″ models. For starters, it was bringing back the ESC key (less touch bar = good!) While I wish they would offer a tactile key option, this was better than nothing. Furthermore, they brought back the scissor keyboard! This one actually feels less mushy than the older ones feel, especially after you’ve gotten used to the butterfly mechanism of the 2016-2018 models, but it’s a short adjustment period. Lastly, I found that while I enjoyed the portability and power-in-a-small-package of my 13″ little beast, I was ultimately less productive due to lack of screen real estate.

    All of these factors led me to wait for the possible release of the 16″ MacBook Pro. My patience, it seems, paid off as Apple announced the 16″ model on November 15th. I made my order that day and it arrived to my door about a week later.

    I couldn’t find a case at first since it was so new. Even though the chassis was supposedly the same size, I had read multiple reports that cases from the 15″ would not fit on the 16″. Eventually, to my satisfaction, I ended up stumbling across this heavy duty case from i-Blason which is perfect for me because I have a tendency to drop expensive things.

    I still have room for a couple more stickers😄

    The specs are:

    • Operating System: MacOS Catalina
    • Processor: 2.4 GHz 8-Core Intel Core i9
    • Memory: 32GB 2667 Mhz DDR4
    • Graphics: AMD Radeon Pro 5500M
    • Storage: 1TB SSD

    All in all, this thing is a beast and I’m really happy to have it. If I dislike two things about it, it’s the bulkiness of it and the touch bar. God, I hate the touch bar. I’ve hacked it a little to remove anything useful unless I touch the function key. Otherwise, I’m constantly hitting it by mistake starting up programs or changing the display brightness or some other arbitrary change within the software I’m running I had no intention of making. It makes me really happy that I opted for the last MacBook Pro without a touch bar the last go around.

    Other than that, this thing has breezed through everything I’ve thrown at it. An 8 core i9 with turbo boost up to 5Ghz is just nuts. I can’t even get the fans to spin in the performance of daily tasks. I have to really try. I stand firmly behind the statement that Apple makes the best Laptops, Tablets, and Phones at the time of this post. I still think Microsoft has them beat in desktop computing.

    Lastly, and perhaps most important: migration assistant is a dream. If you haven’t used it, it basically takes your entire operating system and puts it on your new computer. It’s almost unreal how good it is. Turn on your computer, see how you have files laid out, configurations made just so and everything just the way you want it? Migration assistant puts that into a new machine for you. It’s very altered carbon-esque in the way it makes you feel like your hardware is just a shell for the operating system and the accompanying files, folders, and software – which is eternal. Seriously, if there’s one thing I would do if I worked at Microsoft is figure out a way to make a migration-like tool that’s even half as good as migration assistant is. Your software comes over with the same configuration, your files come over, the terminal is set up on the same git branch I left off on, I didn’t even have to log back into my Gmail because my browser and cookies came over. That’s how good it is.

  • WordPress.com vs WordPress.org

    WordPress.com vs WordPress.org

    On top of working for Automattic on WordPress.com and our other products, I spend a lot of time volunteering in the open-source WordPress community, sometimes referred to as WordPress.org.

    Now, if you aren’t familiar with the differences with WordPress.com and WordPress.org, it goes like this: Once upon a time there was this fellow named Matt Mullenweg. He and Mike Little released the open-source WordPress software in 2003. WordPress initially started out as blogging software but eventually evolved into a rich and the most widely used content management system (CMS) in the world.

    So what is WordPress.org?

    So, we know WordPress is the software itself. WordPress.org refers to the open source community that supports, develops, and maintains the WordPress software. No single person or entity is in charge and anyone can contribute.

    Now, anyone can download this free software, and install it on a web host or local server. You can hack it, break it, bundle it up and redistribute it (within the parameters of the licensing) and essentially do whatever you want with it.

    Here’s the tricky part

    You still have to find a web host (unless you’re going to run the web server out of your house, which isn’t advisable.) There are lots of hosts out there, with all sorts of different features. WordPress.org has a few recommended hosts here. This is the part where I think people get most confused.

    So, you’ve purchased hosting somewhere, installed WordPress, registered a domain, and connected it to the site. Now you’re setting up the site and you have a question. Who do you ask? WordPress.com right? Wrong!

    WordPress is open-source software. It’s developed, maintained, and supported by the WordPress.org community. You can ask for help on the WordPress.org forums (and there are lots of helpful volunteers!) or the developer of a specific plugin or theme, but that’s it!

    What about my host? They might be able to help. However, most hosts are there to help you with the actual configuration of the web server, and not a whole lot beyond that. There are exceptions to this rule, and hosts like Bluehost have support for the WordPress software, but for the most part, you’re on your own.

    This has its benefits. You’re virtually unlimited in what you can do with your site, the sky (and your hosting restrictions) are the limit.

    Here’s what most people don’t know, though:

    Sure, you can host a site for dirt cheap but it’s probably shared hosting and the bandwidth is likely not great either. How much web storage do you have? If something breaks, what’s the support like? If they’re charging you for SSL, get out. An SSL certificate costs no one anything and it’s a bogus charge, in my opinion.

    In terms of bandwidth: you may not think this is important but if you ever have more than one person connecting to your site, it’s a concern. Take a look, for example, of 50 simulated requests to this site:

    50 requests served in about 5 seconds. I could run that script all day without any issues.

    Let’s compare this to what some other hosts might look like:

    How much do you know about software, web development, security? These are legitimate concerns that any reasonable site owner should have. Remember how I said you’re virtually unlimited in what you can do? You’re also responsible for the security of your site and keeping things up to date. It takes work. Because WordPress is open-source software, hackers find vulnerabilities all the time. These are often patched in WordPress core before they have any real effect on people, but folks install plugins made by third party developers and/or fail to update core and get exploited. Happens every day.

    If you’re a web developer who absolutely knows what they’re doing, this may not be a concern for you. But for the average user, this is a really big deal.

    Enter WordPress.com

    Remember Matt Mullenweg? Shortly after founding WordPress he started his own company, called Automattic, which makes a product called WordPress.com among many others. Automattic is passionate about making the web a better place. The vast majority of its work is available to the public under the GPL, and they heavily contribute to the WordPress.org community and open-source WordPress software.

    So what is WordPress.com?

    WordPress.com at its core is a hosting service like some we’ve discussed above, but it’s really much more than that. It’s a fully managed, site building service, it’s a domain registrar, it’s an all-in-one platform for you to publish your message to the world. It’s much, much more.

    So right out of the gate: You can start on WordPress.com for free. Granted of course, you’ll be using a subdomain on a free site, and some other restrictions, but you can still start writing content, uploading pictures and customizing a theme and site for free. I’m not really aware of another hosting service that will give you a space to host a site for free, especially not a WordPress installation, and especially not with unlimited bandwidth. So that’s nice.

    You can upgrade to a paid plan anytime, or start out with one, and the benefits are massive. On top of all of the features listed at https://wordpress.com/plans you get:

    • Access to run ads with one click (monetization)
    • Unlimited Bandwidth (seriously, it’s blazing fast too)
    • Updates and security all managed for you (this is huge)
    • Real-time backups
    • Free domain for the first year
    • 24/7 support

    Speaking of support: The support at WordPress.com is no joke. These aren’t folks reading off a script, these are bloggers, developers, designers, marketers… in fact, every single person that works at Automattic does a support rotation at least once a year (including Matt himself!)

    Well, we tried.

    There’s also a dedicated team of folks 300+ strong who guide, troubleshoot, live and breathe WordPress all day long. These folks, called Happiness Engineers (👋) do just that by providing world class guidance and troubleshooting day in and day out for our 156 Million+ users across our products. We’ll show you how to set up a WordPress site, we’ll walk you through theme setup, we’ll write CSS for you, we’ll provide advice and best practices for SEO, and we’ll do it all in real time – all for as little as $5, or $8 a month on a Personal or Premium plan.

    We’re also a well-established entity. We’ve been around for 14 years now and we aren’t going anywhere. If you aren’t satisfied with your purchase we have a 30 day no-questions-asked refund policy at WordPress.com on all WordPress.com Products and 5 days for domains.

    We keep things secure. All updates to WordPress core (the open source software) are automatically applied to your WordPress.com site in addition to our proprietary software and most if not all features of the Jetpack plugin (another product we make) see: social media sharing, static file hosting, lazy loading images, video players, advanced SEO, eCommerce tools, premium themes, the list goes on…

    So why doesn’t everyone use WordPress.com?

    Because it has its pros and cons. I’d honestly say (and I look at thousands of sites a month) that for 90% of folks, it’s exactly what you need. You can’t out-scale us. If you get really big, we even have a VIP platform where we have clients like Time, CNN, Variety, People, New York Post, Capital One, even Facebook. Is your site getting more clicks than Time Magazine? Probably not.

    However, that remaining 10% of folks do need the extensibility that is simply much easier on a self-hosted solution. Especially for developers. They may have a client with specific needs. WordPress is powerful, but requires an advanced knowledge of web development to really get in there and work requirements out around a client. If you need to heavily modify or extend the software’s functionality – a self-hosted solution is probably the way to go.

    Lastly, there are a lot of myths floating around.

    Common Myths:

    “You don’t own your site at WordPress.com”

    This simply isn’t true. I don’t know how this rumor got started but I see it everywhere. Some hosts/platform might hold your site and/or content hostage, but we don’t. At My Sites > Settings > Export we provide the option to Export all (or specific) text content (pages, posts, feedback) from your site and also the option to Download all the media library files (images, videos, audio and documents) from your site.

    We also explicitly say this in our Terms of Service:

    Our service is designed to give you as much control and ownership over what goes on your website as possible and encourage you to express yourself freely. You own all content you post to your website.

    https://en.wordpress.com/tos/ Section 7: Service Specific Terms

    “You can’t use plugins”

    This actually used to be true, and still is for non-Business or eCommerce plans but this is because of the way the site architecture is set up on lower-than-business plans. With a WordPress.com Business plan you can install plugins, upload custom themes, have unlimited storage and bandwidth and literal 24/7 real time support among a plethora of other ridiculous features at $25 a month.

    “I need a website, not a blog”

    While WordPress itself started out as blogging software, it’s now a very robust CMS and this is true on .com and .org. At WordPress.com, we use “website” and “blog” as interchangeable terms. All of our themes can be used for either a website or a blog. Our default layout is a blog-style format. Take a look at this video tutorial for a walkthrough on how to change your theme’s layout to a website-style format.

    At the end of the day:

    WordPress.com and WordPress.org both have their pros and cons. WordPress.com is sort like having an apartment. You can’t put in a swimming pool, but if something breaks or you need something you’ll get expert help at no additional cost to you. If you aren’t sure how to paint the walls of your apartment, we’ll buy the paint and show you how. WordPress.org is sort of like owning a house. Sure you can knock down that wall to join two rooms but it’s on you if the house falls, as well.

    That’s a pretty base comparison, but hopefully you get the point. Ultimately, it’s your choice. I hope this post was able to clear a few misconceptions surrounding these two platforms for you.

    Do you have any other questions? Let me know!

  • Automattic Grand Meetup 2018 – Orlando, Florida

    Automattic Grand Meetup 2018 – Orlando, Florida

    Recently Automattic had it’s annual Grand Meetup in Orlando, Florida.

    My colleague ClickySteve‘s pictures tell the story better than I ever could.

    Check it out here: Automattic Grand Meetup 2018 – Orlando, Florida