.htaccess is 30 years old and it is still in my critical path.


The annoying thing about .htaccess was never the syntax. It is that it is a config file with near-root power, scattered across the document tree, parsed on every request, and it is where every PHP application puts its security rules. You inherit a site and there are two hundred lines of rewrite and access rules that you did not write, cannot confidently delete, and are about to lose the moment you change web server.

The migration trap

Move a WordPress, Laravel or Drupal site off Apache onto something faster and those rules either come with you or they do not. Usually they do not.

OpenLiteSpeed is fast, free and light, and it does not process .htaccess the way Apache does. Applications that depend on it either break outright or — worse — keep working while the security rules quietly do nothing. A Require all denied that was protecting an admin path is simply not there any more, and nothing in the logs tells you that.

So the options were: stay on Apache, hand-translate every rule into OLS configuration, or find a shim.

What LiteHTTPD does

LiteHTTPD is that shim. It is an Apache .htaccess compatibility layer for OpenLiteSpeed, built from an LSIAPI module (litehttpd_htaccess.so) plus, in the Full edition, a patched OLS binary.

The numbers from its own documentation: 80 supported directives — 83 if you believe the README, the first of several places where the project disagrees with itself. On a compatibility test against a WordPress install with 19 plugins it scores 18 out of 18 and calls that 90%+, against 100% for LSWS Enterprise and 8 out of 18 for stock OpenLiteSpeed. That last figure is the one to sit with: stock OLS passed 44% of the tests, which means the majority of what you had written in .htaccess was being ignored.

It hooks into OLS at two phases: URI_MAP for access control, authentication, redirects, rewrite rules, PHP config and environment variables, and SEND_RESP_HEADER for response headers, Expires and Cache-Control, content type and conditionals. It reads .htaccess from the document root down to the requested path, merges with AllowOverride filtering, and executes in Apache’s order.

On performance their benchmark — AlmaLinux 9.5, WordPress with 19 plugins — puts it at 22,104 requests per second on static files against Apache’s 11,082, with .htaccess parsing overhead of minus 0.7% against minus 18.8% for stock OLS. Their numbers on their hardware, and they contradict each other elsewhere on the same site, so read them as directional.

Two editions, both GPLv3. Thin is the module alone on an unmodified OLS and covers 70+ directives, for the cases where you cannot replace the server binary. Full adds the patched binary and gives you actual RewriteRule execution.

The honest trade-offs

Start with the one that can take your site down. Rules that were inert become live. Stock OLS was ignoring most of your .htaccess, so Require all denied, FilesMatch denies and Header set were doing nothing at all. Switch LiteHTTPD on and they start working. That is the entire point, but it also means an .htaccess nobody has read since 2019 can now return 403 on your own site. The documentation says to review your rules before deploying to production, and that is not boilerplate.

Who should care, and who should not

If you inherit PHP sites with .htaccess files you cannot safely rewrite, and you want OpenLiteSpeed’s throughput, this removes the blocker that usually decides the argument in favour of staying on Apache. A specific situation, but a common one.

If you are greenfield on nginx or Caddy with no .htaccess anywhere, you do not need it. Compatibility layers are debt with a purpose, and there is no purpose when there is nothing to be compatible with.

It is a sub-project of the Web.Casa panel, which is a useful signal about who maintains it and where the effort comes from.

.htaccess is technical debt you cannot delete, because it is load-bearing for applications you did not write. The realistic goal is to keep paying the interest without rewriting the principal.