Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: servers

  • Review: DesktopServer

    Review: DesktopServer

    I’ve been a MAMP user for years, but at WordCamp Chicago, Suzette Franck handed me a thumbdrive with free version of DesktopServer on it. Interested (and not just because a thumbdrive with an app on it is the way I expect to be handed software today), I installed it once I got back to my office.

    Installation and Setup

    You can’t run the zip from the the thumbdrive. It’s a 250meg drive with only 50 megs to spare, so because a Mac is silly, I had to copy the files locally and then unzip. It would be ‘better’ (and this is subjective) if the drive had the installer apps instead of the zips. That said, I know they were copying the zips to the thumbdrives manually so I totally give them a pass.

    Once I did unzip it, it said it would have to restart. So I shut down everything, installed, and … no restart. I think it was a poor choice of words:

    ds-restart

    Right, clearly I wasn’t paying attention. Still, it’s a strange thing to warn when it didn’t actually happen! Now, I know what they meant is this:

    ds-start-admin

    I hate that MAMP does this too, and have long used the MAMP No Password app to work around this. I’d love to see that added to Desktop Server.

    There were a lot of click-throughs, but that it let me add and create a dev website, complete with the hosts file, was nice. I liked that I was able to easily tell it to install in Sites (where I like my sites!), but I didn’t like that it’s bundled with WordPress 3.5.1:

    installnewsite

    Actually I don’t like that it’s bundled with WordPress. Blasphemy! But really, it would be killer if it could just have a dropdown of options: WordPress, Drupal, etc. Then when it runs, it grabs from the latest build. WordPress does this with latest.zip. Drupal doesn’t. Didn’t know that. You should, Drupal! For now, people have come up with an interesting wget based solution, so that would be an awesome thing to add. But I clicked WP (vs nothing), which is the default. I was directed to my site, where all I had to fill in was username and such. All the DB work was done!

    Using DesktopServer

    At this point, I was done so I closed DesktopServer.

    done

    My site, elftest.dev, was up and running and it was easy to use. Perfect! Seriously, at this point it just worked. If I wanted to spin up another site, that was easy too.

    Sadly, it’s not easy to make a subdomain site ala Multisite. I wanted to add ‘foo.elftest.dev’ and I tried to select this be installed in elftest.dev, but got this instead:

    subdomain

    That’s okay for me, I know how to use my hosts file, but it would be nice to have this more accessible. After all, the draw of DesktopServer is that it’s easy right?

    Shutting down DesktopServer

    Here it’s weird. I had shut down the app, because it was done. But doing this only closes the app, not the Apache instance, so I had to reopen (and ‘reboot’ it with Admin rights again) to be presented with this:

    shutdown

    Now I could shut down.

    Conclusions

    It’s a split decision. When I’m using the “MAMP no password” app, it’s certainly easier to activate and deactivate MAMP. However, DesktopServer wins with ease to spin up new sites. For someone like me, who needs to quickly test sites for customers and likes to use foo.dev or foo.loc to test, this is great. I don’t need to hassle with anything, just turn it on, add a site, done. DesktopServer is a little in the middle between easy for newbies and awesome for devs. It’s got a lot of room where I could see it growing, and that’s enough to keep me using it

    The downsides are:

    • Have to ‘restart’ the app with my admin password.
    • Can’t fully customize the website location
    • Can’t customize the TLD (no example.co.dv to test an example.co.uk site, and yes I do that)
    • No menu-bar tool to activate/deactivate

    I’m going to keep using it, of course. The benefit of a fast spin-up of new sites, for what I do with testing people’s sites and fixing them at work, wins hands down.

  • WordPress False Security

    WordPress False Security

    False Security
    Credit: Grafitti Verite
    I wrote this months before the botnet attack of April 2013, but I kept putting off posting it. Clearly now is the time! So since people often ask me if I do certain things to protect my site, here’s what I don’t and do do.

    What I don’t do

    • Hide the WP version in my HTML
    • Remove readme.html
    • Hide login error messages
    • IP blocking*
    • Use a different prefix for your DB
    • Move wp-config.php*

    I don’t bother with the readme or the WP version because it doesn’t matter. People don’t actually search for ‘Who’s using WP 3.4.2? I’ll attack them!’ They let slip their dogs of kiddie cracker war and bury us in traffic. I learned that lesson with the TimThumb debacle. My server got slaughtered by people not searching for TimThumb, but slinging attacks at me as if I had it installed! Even better? They didn’t bother to differentiate where my install where WP was in a subfolder (domain.com/wp/) and just attacked domain.com/wp-content/themes directly. The same thing happened with the recent botnet attacks. Basically people are going to attack me, assuming I’m vulnerable. It’s only when I’ve pissed someone off directly that I’d worry about having a specific version being an issue. And since I keep up to date with upgrades and patches, I don’t worry so much at all.

    The error messages thing stems from people worrying that failed logins to WP will tell you that you got the username or password wrong. So if I login as Lpstenu, it’ll say ‘ERROR: Incorrect username.’ That apparently spooks people, thinking that if you know that you’ve gotten a right username, you’ll hammer that. Do me a favor. Go to yourdomain.com/?author=1 and what happens?(This doesn’t work on this domain because I created it back when WP defaulted your first user to ‘admin.’ I made a second ID and deleted that one.) That’s how much effort it takes to find your username, folks. It’s even easier when you look at this post and see the author name, and a link to it, right there in front of you. Your username isn’t a secret. It’s dead easy to get. I’m not wasting time hiding something that easy to find.

    That’s not really a valid “security” improvement, anyway. It’s irrelevant whether the attacker knows what he got wrong, as it provides no extra information that would help him to get in. Furthermore, the usernames are exposed in dozens of other places already as I showed you before. I often argue that you can’t remove doors: everyone has to be able to get into a house, so we put locks on our doors as deterrents, and signs up to say we’re watched by ATD or whomever. All of those can be circumvented, and you still have a door. Most crime is prevented by deterrents, however (a sufficiently motivated and skilled person will work around anything), so really all we do is make things inconvenient enough that they go somewhere else.

    Locking CablesPart of security is knowing where to spend your time. Make a better mousetrap and you get smarter mice, true, but if you still want to get rid of the mice where do you start? I start with not hiding the obvious. Here’s my username, here’s my login location. They’re standard on most websites, because people have to be able to log in. Now when I really have a locked down site where I want no one but me to log in, I use .htaccess to limit login to just my IPs. This is a (minor) problem when I’m on the road, but I can always SSH in to fix that. Most of the time, though, I trust in my firewall, my server, and the basic security of WP to be enough.

    IP blocking is totally useless to me. With a caveat. I use CSF and ModSecurity on my server which will block by IP if you hit very specific abuse parameters, including my newer ModSec rules for protecting logins. However I don’t pay much attention to it, save to whitelist my commonly used IPs. The point of the firewall is not to stop people I know are bad, but to dynamically catch them in the act, block them on the fly, and then let that IP gracefully expire after a certain amount of time. Years ago I may have had to use .htaccess for that, manually updating it to block specific IPs, but software’s come a long way, and letting the right tool do that job is huge. If you only have .htaccess, well, you can use some .htaccess protection of logins, or you can use Perishable Press’s 5G Blacklist. As I tell people frequently, you never know where legit traffic is coming from, don’t be foolhardy.(True story. A customer at work insisted he did too know better, and blocked China and India traffic. Then he went there on vacation and was pissed he couldn’t log in. Yes, I mentioned I had warned him before.)

    Curiously controversially, I don’t mess with the DB prefix. I use wp_ much for the same reason I never move my wp-content folder unless I’m using CDN (and even then…) : Poorly written plugins and themes will kill me, and people can view my source code or use DB insertion calls in their code. They don’t have to know my prefix, and in fact, best coding practices are intended to work no matter where the folder is or what you use as a prefix. The other reason is I’m exceptionally lazy, and the less I have to remember that I did ‘differently’ in case of an emergency, the easier my life is. This is important when I’m ever hacked (yes, when), because I can restore faster from scratch if I didn’t go nuts reinventing the wheels or moving things around. Rebuilding a wp-config.php is very easy if I only have to change passwords and user IDs, after all.

    Similarly, I don’t move my wp-config.php in most cases. I do on my localhost instance (so I can wipe the folder and DB and start over easily), but really it’s impractical in other situations for me. I think it would be safer to move it out of a web-accessible folder, and when possible I do that (sometimes I have WP in a subfolder) but I have other things I can do to protect that file.

    What I Do

    Besides a massive amount of work keeping my server up to date and tuning my firewall, I do some things that anyone using WordPress can do:

    Stupid Security

    • .htaccess protect wp-config.php
    • Lock file permissions
    • Prevent plugins from writing to wp-config.php and .htaccess
    • Prevent folder content browsing (for images mostly, but also plugins)
    • Use strong passwords for WP/FTP/SQL accounts
    • Use one-time passwords for WP/SQL/FTP/SSH accounts

    I protect my wp-config.php from direct access with a really simple .htaccess directive:

    <files wp-config.php>
    order allow,deny
    deny from all
    </files>
    

    I think nginx is this:

    location ~* wp-config.php { 
        deny all; 
    }
    

    This means you can’t see https://halfelf.org/wp-config.php in your browser. It’s pretty minor, in so far as things go.

    I lock down my file permissions as tight as I possibly can. Nothing is set to 777, and my .htaccess isn’t writable. This means if I use a plugin that wants to edit my .htaccess (or wp-config), I have to do it manually. This is good, in my opinion. I always know exactly what I’m doing. In my .htaccess I also have Options -Indexes, which stops people from being able to browse empty folders (this is important for plugins that don’t have an index.php file). Since I’m using SVN and Git, I also prevent people from seeing those:

    	RewriteRule ^(.*/)?(\.svn|\.git)/ - [F,L]
    	ErrorDocument 403 "Access Forbidden"
    

    My passwords are stupid complex. I haven’t the foggiest idea what they are thanks to 1Password. I also don’t reuse passwords. This is very important for how my server is setup, as DSO requires you to enter in passwords to upgrade WordPress. While I can use my main account, I actually created an FTP only account for each and every website on my server, and then I hard coded that (and it’s password) into my wp-config file. So yes, I have a DB password (each account is used once for each DB) and an FTP password (again, one account for each account) in my config. And no, I’m not worried about that. Sometimes I have a generic SQL ID for all DBs under one account, though that’s a tiny bit more risky.

    But, most importantly, I try to cure myself of being stupid. I don’t log in to my site via non-secure ways (SSH & SFTP only). The passwords I use for my login (which is not SSL protected on WP) are one-account/one-use. I try never to log in on someone else’s computer. I don’t do admin work on potentially unsafe wifi. You see, the greatest security risk in the world isn’t the software you’re using, it’s you. You do stupid things, like recite your credit card info (or password) over your cellphone while on a train trying to get your host to reboot a server. You use Starbucks’s wifi to pay your bills. You talk about how your mother changed her name.

    Social engineering is way more dangerous than any server hack, and when it’s down to the wire, that’s what I’m more worried about. After all, I have good backups of my files.

  • Trading APC for Zend

    Trading APC for Zend

    zend-optimizerThe last thing I did before Passover was a totally unannounced, not telling anyone, surprise flip from my old standby, APC, to the new hotness, Zend.

    As of PHP 5.5, Zend Optimizer+ will be included. Back in 2009, I decided to use APC for a couple reasons: It was made by the PHP blokes and it worked well with mod_php and MediaWiki. Since PHP decided to change, I joined in. Why the change? Zend went open source.

    Installing Zend

    I grabbed the latest tagged version from the official GitHub repository, since I don’t cotton to using bleeding edge all the time.

    $ wget https://github.com/zend-dev/ZendOptimizerPlus/archive/v7.0.1.zip
    $ unzip v7.0.1
    $ cd ZendOptimizerPlus-7.0.1/
    $ phpize
    $ ./configure
    $ make
    $ make install
    

    That gave me the final output of: Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20100525/ You want to hang on to that path, because we’re going to edit php.ini and put this in below the line for IonCube, if you have that installed:

     zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/opcache.so
    

    Replace the path with your own.

    I also followed their advice on the recommended config and put this in my php.ini as well:

    [Zend]
    opcache.memory_consumption=128
    opcache.interned_strings_buffer=8
    opcache.max_accelerated_files=4000
    opcache.revalidate_freq=60
    opcache.fast_shutdown=1
    opcache.enable_cli=1
    

    Since I had APC there before, I removed all those lines while I was at it. Restarted PHP (well, httpd in my case, I like a clean slate) and I was done.

    Cleanup

    As I mentioned before, I removed the APC lines while I was in the php.ini and, since I installed it via a downloaded pecl, I just removed the apc.so file from the same folder where opcache.so was installed.

    On WordPress, I also removed the APC Object Cache Backend plugin from the two sites that had it, since I’m not using APC. There doesn’t appear to be an equivilent for Zend, but I may or may not need that.

    For MediaWiki, I had to edit LocalSettings.php and remove $wgMainCacheType = CACHE_ACCEL; as that’s no longer being used. Then I went into my maintenance folder and ran php rebuildLocalisationCache.php --force to flush everything and my errors went away. MediaWiki has a pretty different cache method than other apps, and for yonks flat out didn’t work with Zend. It does now, and there seemed to be no speed loss without an OpCode cache.

    None of my other apps seemed to care, so I moved on to see how this all played out.

    Results

    Much like the ManageWP guys, I saw an immediate drop in memory and CPU. And I’m still on PHP 5.4! There was an initial spike while I was mucking around, which I expected, and then everything dropped. Some things did not so much drop as level out and change my ‘spike’ range. Normally my load average for 1 minute would spike at 0.8 or so every hour. Now it’s spiking at 0.5, give or take, which is a success in my book.

    Load Avg 5min - Post Zend
    Can you guess when Zend went on?

    Before someone points out that, hey, this is hardly a real check, I want to note that I was having one of those 200% traffic days. Actually I was having a few of them in a row, and I know it’s going to go up from there. Here’s a quick look at my traffic:

    traffic ga-traffic

    The real test will be tonight and tomorrow, though, as I push some large data (videos) on a popular topic, but frankly, this is looking good.

    The benchmarks used in the ticket to include Zend in PHP (why are they using WP 2? I have no idea) were startling compared to normal PHP. Compared to APC it’s a minimal kick in the pants, but the assurance of bundling to come speaks for itself. This is where PHP is going.

    APC v Zend Benchmarks
    Credit: Dimitry

    I’m not yet on PHP 5.5, but I’ve already found that 5.4 is a notable kick to my speed. Zend took me from a B to an A in PageSpeed and YSlow (when you tell YSlow that I’m a small blog and not Amazon). Also it ‘feels’ faster, which is totally subjective, but still a valid remark. The site feels fast, it doesn’t hang (yet) and it didn’t crash over Passover!

    Former bbPress regular, _ck_, went and wrote a neat little Control Panel for Zend Optimizer+ which I snagged and tossed into my secret bin for poking at later.

    Since I’m the Zend Rookie, anyone have any tips and tricks for configuring it to make it sing? Remember, I don’t just use WordPress on this box!

  • I Don’t Understand CloudFlare

    I Don’t Understand CloudFlare

    If you know the answer to all this, I’d love to hear it, because I can’t figure this out. What’s the real point of CloudFlare?

    Fairly recently I was reading Tony Perez’s post about CloudFlare vs Incapsula vs ModSecurity. As regular readers may know, I am frenemies with Mod_Security. I often want to kill it with fire, but I never disable it entirely because it protects my site from hackers. By using Mod_Security I limit my chances of having Bobby Tables kill my site.

    Using Mod_Security gives you some protection from simple SQL injections, but also XSS attacks. You can integrate it with things like Project Honeypot. As they put it:

    ModSecurity™ is an open source, free web application firewall (WAF) Apache module. With over 70% of all attacks now carried out over the web application level, organizations need all the help they can get in making their systems secure. WAFs are deployed to establish an external security layer that increases security, detects and prevents attacks before they reach web applications. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and real-time analysis with little or no changes to existing infrastructure.

    And you know what? It really does all that.

    So what’s CloudFlare? It’s an intermediary between your site and the world which caches your site, compresses data, and gives people the fastest version of your site. In the event your site is down, they’ll serve cached versions. They even give you a pretty picture.

    CloudFlare

    The first time I heard about this, I arched my eyebrows in surprise and confusion. I’m going to make my site faster by putting more layers between the reader and my content? That means instead of just relying on my server and host to be fast, serve compressed pages, keep the lights on, keep a speedy connection to the Intertubes, and do all the things that needs to happen for the magic pipe between my website and you guys, I’m doing all that and trusting someone new to help me do it better. Interesting, Captain. How are they doing this?

    squire3 CloudFlare has a few tricks to do this: CDN (content loads faster if it’s stored local to the people visiting the site), content optimization (minimizes and compresses page content), security (protecting you from DDOS and SQL injection), and analytics.

    Except when I look at that list I think that I already use mod_pagespeed to minimize and compress my content, mod_security to protect me (also Config Server Firewall for the DDoS stuff), and analytics is done by my server or Google. For me, that means the only thing they’re offering that I don’t have is a CDN. I read up on CloudFlare’s CDN, and they tout not having the weight of 15 years legacy crap. That’s a tricky edge to dance on, since they also don’t have the experience of those 15 years, or the network. In fact, looking at their network map, they have nothing in South America. Guess what the number two location is for people visting my sites? Brazil.

    And this, my children, is why you study your stats to understand who is visiting your site, where from, why, and with what browsers. Right away I can see that CloudFlare, while interesting, doesn’t seem to have any benefit for me. If I decide that I want a CDN, it’ll probably cost me around $30 more a month, minimum, for my sites and what they have on them today. Oh but wait, you say, CloudFlare is free?

    Yeaaaah. I don’t trust free services very much. A free app, once I download it and put it on my server, I keep. A free service is hosted on someone else’s server, at their whimsy, and is supported as they see fit. Yes, this means I don’t trust Facebook or Twitter. A free service is interesting only in that it lets me try it before I buy it, and for that, I approve of how CloudFlare does it. But the problem is today I went to a website and saw this:

    cloudflareddos

    What did I do? I didn’t visit this website. They can brag about the whole 30ms response time all they want, but if I went to a website and hit a barrier like that, I stop because it’s getting in the way of my surfing. That was my initial quandary about CloudFlare after all. How can it provide all these awesome things without getting in the way? And it can’t for everyone. At first I thought it was because I was going through bit.ly and it worried I was a spammer (okay, fair enough), so I tried manually, and it was the same problem. I just went to the page normally now, and it’s been well more than “5 seconds” and the site still hasn’t loaded.

    I fundamentally dislike anything that causes my users to do ‘more’ to get to my content. I think that it’s more harmful than a slow site, and it’s more harmful than letting these bad eggs visit my site. The right place to block a naughty person is when they’re doing something naughty. If my IP is a range of DDoS attackers, that’s one thing. You shouldn’t be detecting as the page loads, delaying me almost 30 seconds, and then loading the page. This delay is supposedly for my protection (me the site runner, not the visitor). Okay then, what are they protecting me from?

    Part of CloudFlare’s service is something called a Web Application Firewall (WAF), which is fancy-speak for saying their computer looks at what people are coming to your site to do, what data they’re sending, and tries to figure out if they’re nice visitors (which it should let through) or naughty hackers (which it should block).(From WP Shine Cloudflare: Early Reports Question Effectiveness as Website Security Tool)

    WAF came up before, with Mod_security. And at this moment, I go to a picture. Here’s what Tony parsed from the data:

    Screen Shot 2013-03-20 at 10.10.03 AM

    He asked on Google+ what we took from that article, and my reply was “That the months I spent mastering mod_security was totally worth it.” If you don’t trust Tony’s numbers, you can read the full report on slideshare for yourself. Tony has the same feelings about Captcha as I do, by the way, though less strongly. I despise it more than I hate hotlinkers, and I hate hotlinking. Captchas are the worst barrier between content and consumer that was ever invented. They don’t work, they’re not accessibility friendly, and they are rarely implemented well. Hotlinking may be theft, but Captchas are shouting “No soup for you!”

    Which brings me to my point.

    What is CloudFlare doing? In plain english, can someone explain to me how it would benefit me? Ignoring the CDN aspect, the only WAF part I can see benefiting me is that CloudFlare (and Incapsula for that matter) essentially crowdsource the list of people who are ‘bad’ and shouldn’t access my site. Which is cool, and that I certainly like. It’s sort of like a Project Honeypot for baddies (and by the way, that would be a nice feature). Having the world bring in the list of bad people, as well as their patterns, and sharing that back out is a great way to keep everyone up to date quickly and seamlessly.

    I really just can’t see why I’d ever want to use CloudFlare. It would certainly be a cheap and easy way to put some possible gain on my site, but in the long run I feel that managing these things myself (or hiring someone to do it) would be a better business solution. It saves me from the dread blackbox spam killer, which means I always know what’s going on. Now I know not everyone is capable of handling all this themselves, but from what I’ve seen, most webhosts already have mod_security running. So lets drop the WAF argument from the table, and we come down to the best thing CloudFlare’s doing is acting as a CDN and compressing content. That’s not good enough for me. At that point, you may as well use Google’s PageSpeed Service

    I’m sure there are great reasons for using CloudFlare, but I just can’t see it.

    Quick ETA… Talking to a coworker, it occurred to us that I may just not be their audience. I’m too big already and I took care of most of what they do. I can look at this and think “If I just have a small site and I want to speed it up on a shared server where I have no root nothings” then it looks way more reasonable. But I’m not.

  • Cacheless (or not)

    Cacheless (or not)

    ETA: As of a month later, I’ve actually switched from APC to Zend Optimizer+

    FilesDon’t get me wrong, I love caching. I love W3 Total Cache (I’m willing to spend my ‘free time’ testing it, after all), and WP Super Cache saved my life once. So why, on a day where I got a 400-600% uptick in traffic (not a joke), did I turn all my caching off? I’m daring, and a little crazy, but I wanted to see if it could be done. I would not have tried this if I was on a smaller server: if you’re getting as much traffic as I am, and you’re on shared hosting, you really need to move to a VPS or Dedicated Server if you want to turn off caching via plugins. It’s not to say that caching is better or worse than not-caching, or vice versa, or that one is a rich-man/poor-man equivalent of the other. Caching plugins are an inexpensive way to speed up your site, and if you can’t afford a bigger server they will buy you the time you need to figure out a better solution. Even with a good plugin and setup, if you get hammered with a lot of traffic, you will crash your site unless the server’s optimized too. Again, what I’ve done is not something I’d try on a low-end server with high traffic.

    When I started measuring the effectiveness of all this, I used:

    To understand what caching is and why we use it, it’s good to understand the basic concepts, and to start by looking at what caching plugins are, how they work, and where their pitfalls are.

    • There are parts of your website that don’t change often (images, javascript, CSS, etc).
    • You want the user to only download what’s changed.

    That sounds easy, but WordPress isn’t static HTML, it’s PHP, and that means every time you visit the page, it runs various proceses to give you the latest and greatest files. The problem with this dynamic code is where content changes rapidly (think ‘comments’ or ‘forums’ or ‘BuddyPress Groups’). Suddenly caching ‘pages’ as wholesale chunks of html doesn’t help if you have to re-cache when someone leaves a remark. Add in the possibility of 4 or 5 people commenting at once, for 12 hours, and now you’re risking a thrashing situation where you keep trying to cache, but it keeps flushing. This is why most people use plugins that handle things elegantly, or try to, where the ‘static’ part of the page (sidebar, etc) are HTMLized, but the dynamic part is left alone. This helps when you have a portion of every page is dynamic, like a shopping cart with a ‘Your order…’ box.

    StorageBut the downside is that you have to write fancy code that remains dynamic portions, and while it certainly can be done, it’s not fun, and let’s be honest, a theme developer doesn’t know which cache you’re going to use, so how can it write the right way for that? The only way to make a truly dynamic and cachable site is to do it from day one, with your theme, server, and plugins all crafted to provide the best experience. And then we have reality, which is we start with something simple, wake up to something large, and experience growing pains.

    Accepting the fact that we’re not starting from nothing, that we have an existing site with content and activity, the first thing most people do is install a plugin. Now, back to what I said before, this isn’t a bad thing. It’s a good first step and will buy you time. It’ll also show you where you need to go. If you don’t have server root access, this may be a your limit, too, as some of the other things I like to do to speed things up without a cache will require it (or you’ll have to ask your hosts and they may tell you to upgrade).

    If you’re going to use a plugin, WP Super Cache (WPSC) and W3 Total Cache (W3TC) are the best two. W3TC is way more advanced, and has a lot of extra bells and whistles, but personally I find that once you can master it, you’re well on your way. Remember though, you’re sacrificing a lot of control here by using a plugin. They’re going to, by their nature, cache everything they can, and we’re back to where we were with the dynamic site generation issue. W3TC has a bunch of extra .htaccess/nginx rules which parse data before you hit WordPress. WPSC can do that, or use PHP (which is slower).

    The dynamic nature of my site is what drove me away from caching plugins. I use other CMS tools, and for my infrequently updated Wiki and ZenPhoto Gallery, where content is very much static, caching makes perfect sense. But when I want to run a simple community site with WordPress, I have to consider all aspects of user experience. Speed is hugely important, but so is the user getting the content they want. Stale content is a killer.

    The reason I decided to see if my site ran slower without caching was that I was reinstalling caching and I thought “This is a perfect time to benchmark.” When I did I was astounded. There was very little difference in a benchmark test. Really no difference between at all, since it was within the results of each other, but I neglected to save the results at the time. I did however snap a picture of my server load(The unrelated part is where I was uploading 10megs of media. Unrelated.):

    load-graph

    Browser Caching is the first thing to tweak, as that tells browsers to cache content. The way this works is your .htaccess tacks on extra information while content like images and CSS are being downloaded, to say “This content is good for X days.” With WordPress, you don’t have to worry about changing the CSS, as most themes and plugins are extra smart, in that they append a version to the end of your CSS like this: style.css?ver=1.9.1 That 1.9.1 is the version of Genesis I’m running, so when that changes, the version changes, and browsers see it as a new file and re-download. That’s pretty cool. (I do wish that child themes pulled in their version, so you could increment that way.) We still have to tell the broswers to cache, and for how long, so near the top of my .htaccess (just below my hotlink protection) I have this:

    ## BEGIN EXPIRES ##
    
        ExpiresActive On
        ExpiresByType image/jpg "access 1 year"
        ExpiresByType image/jpeg "access 1 year"
        ExpiresByType image/gif "access 1 year"
        ExpiresByType image/png "access 1 year"
        ExpiresByType image/x-icon "access 1 year"
    
        ExpiresByType text/css "access 1 month"
        ExpiresByType text/html "access 1 hour"
    
        ExpiresByType application/pdf "access 1 month"
        ExpiresByType application/x-javascript "access 1 month"
        ExpiresByType application/javascript "access 1 month"
        ExpiresByType text/javascript "access 1 month"
        ExpiresByType text/x-js "access 1 month"
    
        ExpiresByType application/x-shockwave-flash "access 1 month"
        
        ExpiresByType video/quicktime "access 1 month"
        ExpiresByType audio/mpeg "access 1 month"
        ExpiresByType video/mp4 "access 1 month"
        ExpiresByType video/mpeg "access 1 month"
        ExpiresByType audio/ogg  "access 1 month"
        ExpiresByType video/ogg  "access 1 month"
    
        ExpiresDefault "access 2 days"
    
    ## END EXPIRES ##
    

    I’ve added in only the types used by my site. I used to use Pragma caching headers as well, but I noticed that Google PageSpeed Insights and YSlow ignore them. Turns out that Pragma headers aren’t honored all the time, in fact, they aren’t honored often, so I just removed them. I don’t think it slowed my site down to have them, but the less to maintain, the better. This had an immediate positive impact, so it was time to look at the server.

    ShapesOver the years, I’ve tuned httpd.conf so it doesn’t crash, I’ve got CSF locked down to prevent people from DoS’ing me over TimThumb, and I of course have APC turned on. Recently I broke down and installed mod_pagespeed when I upgraded to PHP 5.4. Just those things have done a lot to make my site run faster. I intentionally skipped things like Varnish or TrafficServer, as well as a CND or Google’s PageSpeed Service. I (still) don’t need them.

    Since I’m new to Page Speed, I decided to look deep into the filters and enabled the following for the whole server: rewrite_javascript, rewrite_css, collapse_whitespace, elide_attributes. This had a right-away impact of what I jokingly called ‘Effective Minification.’ These filters are new to me, so I spent a lot of time reading up on all the filters, and I find them highly interesting. By having PageSpeed handle things like offloading jQuery, I take the load off of WordPress and other CMS tools, and don’t have to use a plugin.(Don’t get the wrong idea. There are uses for plugins! But I’m all about using the right tool for the right job. I don’t have plugins handle my WordPress database, because I feel it’s like using a screwdriver to hammer in a nail. You can….)

    I added in a couple more to my standard: remove_comments and rewrite_images. Then I went back to my site’s .htaccess and started turning on the things I wanted per-site.

    The ones I picked are:

    Putting those in my .htaccess looks like this (note: no spaces between the filter names, or it all blows an error 500):

    
        ModPagespeedEnableFilters move_css_to_head,defer_javascript,insert_ga
        ModPagespeedAnalyticsID UA-MYCOOLID-1
    
    

    That also means I don’t have to use a plugin to use Google Analytics for my whole site! This may not mean a lot to you, but I have multiple ‘apps’ on my site (four now) and when I edit themes, if I don’t have to do anything, it’s easier. Google will tell you not to do this, but unless they have a way for me to set pagespeed.conf in the /home/user/ folder of my server, I don’t know another per-user way about this.

    Finally I went back on my word, and I installed a plugin. APC by Mark Jaquith. This isn’t a full reversal on my ‘No Plugins!’ stance before, though. All APC is, you see, is but one file that sites in wp-content and kicks things over to APC. Doing this alone moved my TTFB from an F to a B. Which is pretty impressive. Giving it a little time to bake, this worked out okay.

  • wp-cron it up

    wp-cron it up

    CronIf you’ve spent much time mastering *nix servers, you’ve run into cron. I love cron. Cron is a special command that lets you schedule jobs. I use it all the time for various commands I want to run regularly, like the hourly check for new posts in RSS on TinyRSS or RSS2Email, or the nightly backups, or any other thing I want to happen repeatedly. Cron is perfect for this, it runs in the background and it’s always running.

    My first thought, when I heard about wp-cron, was that it clearly tapped into cron! If I scheduled a post, it must write a one-time cron job for that. I was wrong. Among other reasons, not everyone has cron on their servers (Windows, I’m looking at you), but more to the point, cron is a bit overkill here. Instead WordPress has a file called wp-cron.php which it calls under special circumstances. Every time you load a page, WordPress checks if there’s anything for WP-Cron to run and, if so, calls wp-cron.php.

    Some hosts get a little snippy about that, claiming it overuses resources and ask that you disable cron. One might argue that checking on every pageload is overkill, but realistically, with all the other checks WordPress puts in for comments and changes, that seems a bit off. In the old WordPress days, this actually was a little true. If you have a server getting a lot of traffic, it was possible to accidentally loop multiple calls at the same time. This was fixed quite a bit in WordPress 3.3 with better locking (so things only run once). Multisite was a hassle for a lot of people, but seems to have been sorted out.

    StopwatchWe already know that WordPress only calls wp-cron if it needs to, so if you disable it, you have to run that manually (which ironically you could do via a cron job (Read How to Disable WordPress WP-Cron for directions on how to disable and then use real cron.)). To disable wp-cron, just toss this in your wp-config.php:

    define('DISABLE_WP_CRON', true);

    Now, remember, you still want to run a ‘cron’ job to fire off anything scheduled, so you have to add in your own cron-job for this, which I actually do! I have cron turned off, and a ‘real’ cron job runs at 5 and 35 past the hour to call wp-cron with a simple command:

    curl http://example.com/wp-cron.php
    

    Now since I have multiple domains on this install, I actually have that for every site on my Multisite. After all, wp-cron.php on Ipstenu.org doesn’t run for photos.ipstenu.org and so on. Doing this sped up my site, and put the strain back where I felt it should be. The server.

    By the way, wp-cron does more than schedule posts. That’s what checks for plugin, theme and core updates, and you can write code to hook into it to schedule things like backups. Remember before how I said that WP checks to see if there’s anything scheduled? This is a good thing, since if you have your server run a long job (like backing up a 100meg site), you don’t want to wait for that to be done before you page loaded, right?

    For most people, on most sites, this is all fine to leave alone and let it run as is. For the rest, if you chose to use cron instead, keep in mind how things are scheduled. Like I set my cron to run and 5 and 35, so I tend to schedule posts for 30 and the hour. That means my posts will go up no later that 5 minutes after. That’s good, but if I use my DreamObjects plugin, the ‘Backup ASAP’ button schedules a backup to run in 60 seconds (so as not to stop you from doing anything else, eh?), which means I’d have to manually go to example.com/wp-cron.php in order to kick it off. Clearly there are issues doing this for a client.