OpenResty vs Lua 5.4: a benchmark

OpenResty vs Lua 5.4: a benchmark

The problem

One of my customers, the University of Antwerp, wants to switch from PHP to Lua 5.4 for their web apps that access their library catalogue product. OpenResty is the obvious choice of web stack ... but it doesn't support Lua 5.4.

Everyone knows that OpenResty is the fastest web engine out there, but if they want Lua 5.4 ... well, they want it. And if they use Lua 5.4 everywhere else, it's going to be hard for them to restrict their web code to OpenResty's Lua 5.1 language features, because they'll need to call the rest of their Lua 5.4 code to access the catalogue database.

[Update: it turns out that Redbean is actually the fastest, and there are more good Lua 5.4 alternatives. See my update here.]

The Benchmark

But perhaps they can handle the speed hit. If they insist on Lua 5.4 and forfeit OpenResty, how much speed will they really lose? I made a benchmark to test 50,000 web requests as follows:

ab -k -c1000 -n50000 -S "http://localhost:8081/multiply?a=2&b=3"

All of these run on NGINX except for the mod_lua option, which requires Apache. OpenResty is clearly the fastest, and Apache takes 2× as long.

Since my Lua program is so small and simple, you can see that it makes no difference whether we use Lua 5.1, Lua 5.4 or LuaJIT. The real thing we're testing is the server stack overhead to call Lua.

All the rest of the NGINX solutions take a very slow 6-7× as long. I guess this is because they all convert to an intermediate protocol: either uWSGI or FastCGI.

However: It's possible that there is a way to halve the duration of my FastCGI and uWSGI benchmarks. I guess this because my CPU load is only about 50% on each core (according to htop) when I run those tests, whereas OpenResty and Apache tests use 100% of every core. I don't know why NGINX doesn't parallel those up sufficiently to use 100% CPU. There may be a better server config, but I've tried various ones and I can't find it.

If you're an NGINX guru, please help me tweak my server config if this can be fixed. You can examine my configs in the benchmark repository here, or clone/run the benchmarks on your own machine with a make summary command.

Which web stack?

All of this raises the question, which web stack is best for a user that wants both speed and Lua 5.4? Well, you can't (yet) have both. You could have Lua 5.4 at half speed, but here are some other disincentives that I discovered along the way. Please add your own:

  • Most independent tools such as Lapis (URL routing, sessions, CSRF protection) are either for OpenResty or else require Lua5.1/LuaJIT

  • Most other lua-enabled web servers (lwan-lua, sailor) are also stuck on Lua5.1/LuaJIT and are up to a decade old and not maintained. Even Apache's mod_lua has not been touched in 11 years (though I expect it works with Lua 5.4)

  • NGINX + uWSGI does actually work with Lua 5.4 as shown in the tests above, even though it only documents support up to Lua 5.2. However, uWSGI generates deprecation warnings when you build it, and it will fail if built on Python >= 3.12.

By contrast, OpenResty has clear advantages besides speed:

  • It allows Lua scripts to provide not just content, but also control Nginx in various other ways: access to the NGINX environment, init phase, rewrite phase, access phase, and logging.

  • OpenResty's cosocket library allows async-style code development, without the programmer having to specifically yield all the time (see this presentation and why co-routines are better). Writing web request code without this looks uglier.

In short, the modern Lua-web ecosystem, in every facet, is very much based on Lua 5.1. I grudgingly recommend that Lua 5.4 is not the right way to go for now.

Hope for OpenResty with Lua 5.4?

OpenResty has stayed with LuaJIT (5.1 language features) for reasons. Simplistically, this is partly because the author of LuaJIT does not agree with all the 5.4 changes, and also partly because a 5.4 update is a lot of work.

Yet, IMHO, there's a new source of hope for a reconciled Lua community around a 5.4 JIT.

Haoran Xu is halfway through his LuaJIT Remake (although he's initially targeting 5.1 for benchmark comparisons, he has 5.4 in his eventual sights). He's doing GREAT work, and his benchmarks to date suggest that it's angling to be the fastest Lua around by a long shot.

I am hopeful that once a blindingly fast JIT for 5.4 is available, OpenResty will be in a position to switch to a 5.4 world. If you're influential at OpenResty, please comment.

I know that LuaJIT vs Lua 5.4 is a flamewar issue. If you comment, please try to keep it thoughtful and brief!