Is Apache 2.4 Worth the Upgrade?
Apache httpd 2.4.1 came out on February 21, and it’s the first GA release of the 2.4 branch. That makes it the first major httpd release since 2.2 back in 2005, and the announcement lists a lot: loadable MPMs, mod_lua, dynamic reverse proxy configuration, improved authentication and authorization, a FastCGI proxy, a new expression parser and a small object caching API. After a month and a half of it being out, the question I keep seeing is whether it’s worth moving a working 2.2 server. My short answer is yes for new builds, and carefully for existing ones, because your old config probably won’t start without some edits.
The event MPM is finally supported
The new features page says the event MPM is no longer experimental and is now fully supported. It goes after what the docs call the keep alive problem. With prefork or worker, a client holding a keep-alive connection open ties up a whole process or thread even while it’s just sitting there. The event MPM hands those idle connections, along with the listening sockets and connections that only have data left to send, to a dedicated thread, so worker threads are free for requests that actually need processing.
There are caveats in the 2.4.1 docs. The improved connection handling doesn’t work yet for certain connection filters, SSL in particular, so HTTPS connections fall back to worker behavior with one thread per connection. The docs also say it’s currently only compatible with epoll and kqueue.
MPMs can now be built as loadable modules too (configure with --enable-mpms-shared), which means switching MPMs is a LoadModule change instead of a rebuild.
The catch for a lot of us is PHP. PHP’s own install docs still recommend against a threaded MPM in production with mod_php and point you to prefork. If you want event, the cleaner route is running PHP out of process with PHP-FPM, which has shipped with PHP since 5.3.3, and 2.4 now includes mod_proxy_fcgi, a FastCGI backend for mod_proxy. That’s a bigger change than an httpd upgrade, so plan it as its own project.
Require replaces Order, Allow and Deny
This is the change most likely to break things. The upgrading guide says any configuration file that uses authorization will likely need changes. In 2.2, host and IP based access control used Order, Allow, Deny and Satisfy. In 2.4 it goes through the same authorization system as everything else, via mod_authz_host and the Require directive. The before and after is refreshingly short:
# 2.2
Order deny,allow
Deny from all
Allow from example.org
# 2.4
Require host example.org
Require all granted replaces the usual Order allow,deny plus Allow from all, Require all denied blocks everything, and Require ip 10.1.0.0/16 handles address ranges. If you need more complicated logic, <RequireAll> and <RequireAny> let you combine rules.
If you can’t rewrite everything on day one, the old directives still exist in mod_access_compat. The docs call them deprecated, so treat that module as a bridge, not a destination. Watch your .htaccess files as well, since that’s where old Allow and Deny lines tend to hide.
Other things that break on upgrade
The upgrading guide has a section of common startup errors, and two are worth memorizing. If httpd complains that Order is an invalid command, load mod_access_compat or convert to Require. If it says User is invalid, you need to load mod_unixd, which is where User and Group live in 2.4. Neither module existed in 2.2, so an old config never loads them. It’s also worth knowing that a fresh 2.4 build loads only a basic set of modules by default and leaves the other LoadModule lines commented out, so check that everything your config uses is actually loaded.
A few renames and changed defaults are also easy to miss. MaxClients is now MaxRequestWorkers and MaxRequestsPerChild is now MaxConnectionsPerChild, though the old names still work. NameVirtualHost and DefaultType no longer do anything except emit a warning. EnableSendfile now defaults to Off, FileETag defaults to MTime Size without the inode, and KeepAlive only accepts On or Off. The old LockFile, AcceptMutex and friends are replaced by a single Mutex directive. APR and APR-Util are no longer bundled with the httpd source, and every third party module has to be recompiled for 2.4.
The 2.4.1 announcement also warns that there’s no Windows binary yet and that 2.4.1 may not be suitable for all Windows servers.
So, is it worth it?
For a new server where you control the whole stack, I think 2.4 is the better starting point, especially if you pair the event MPM with PHP-FPM. For an existing 2.2 box, the gains are real but so is the config churn. I’d copy the config to a test machine, run apachectl configtest against 2.4, and work through the errors one by one. Convert access rules to Require as you go instead of leaning on mod_access_compat forever, and check that every third party module you depend on has a 2.4 build before you commit.