Lua web pros and cons

A case study for replacing PHP with Lua

Objectives

My customer has web applications written in PHP, accessing an M database. For various reasons they are committed to a dynamic language, and are considering Lua as a lightweight option. Here are their primary objectives:

  1. Cleaner access to the M database (drop the JSON intermediary needed for PHP).

  2. A general-purpose language, not web-centric (like PHP is).

  3. A popular ecosystem/language: access new developers quickly.

Secondary objectives:

  • Reduce the language count: if adding Lua as a language, it must replace another language (e.g. PHP). And, over time, to also write more Lua and less M.

  • Support the latest Lua: 5.4 (rather than LuaJIT, which is Lua 5.1)

Lua vs PHP

Let's look at pros/cons of using Lua instead of PHP:

Pros for Lua:

  1. Native M database access library, so faster/tidier than PHP (which must access via a JSON intermediary)

  2. Lua is a general-purpose language, not web-specific

  3. Lua has a reasonably sized user base and is quick to learn

  4. The fastest web servers available use Lua: Redbean, OpenResty, Nginx-lws

  5. If OpenResty is also used, an opportunity to switch to standardized mechanisms (e.g. standard session manager -- see below)

Cons of Lua:

  1. Lua's tools are disparate, split between LuaJIT and Lua 5.4.

Only one con, but it's a big one.

Although PHP is infamous for changing its language every release causing web software compatibility issues, Lua's problem is similar. Its disparate web offerings are partly a result of language changes between Lua 5.1 and 5.4.

The largest APIs & developer community are restricted to OpenResty, which is stuck on LuaJIT's 5.1 interface, with 5.4 not even on its roadmap (it's at least a year before it is even possible, using the LuaJIT remake).

The best Lua 5.4 options are Redbean and Nginx-lws, depending on your requirements. These will be covered in more detail below.

The options

1. OpenResty does rank highly, with (of course) some rave reviews. Advantages are:

But, for now, it only supports LuaJIT (which is Lua 5.1 -- albeit, with extras from 5.2 and 5.3)

2. Nginx-lws advantages:

  • Lua 5.4 support

  • Great performance, akin to OpenResty

  • A well-designed API and runs on Nginx, a general-purpose web server

  • A nice monitor and profiler

  • Its author is planning on long-term support

However, Nginx-lws has no web framework, preferring to let the developer select their own independent Lua modules.

3. Redbean advantages:

  • Lua 5.4 support

  • Impressively fast

  • A substantial API

  • The fullmoon web framework

However, Redbean specialises in Lua and standalone apps, so it is not a general-purpose web server. For example, it does not serve Python apps with a built-in module, so these would have to use, say, a slower CGI mechanism.

4. Python instead of Lua could achieve all the stated objectives:

  • Huge community of web developers

  • Requires speed/syntax improvements for M access in YDBPthon

However, Python is not a built-in module for NGINX, so will incur protocol overheads compared to OpenResty's built-in Lua. However, I do not have benchmarks at this point.

5. PHP for all web apps. This would require PHP to have better access to M than the current JSON interface. The two primary options for better PHP access to M are:

  • Use mg_php. Challenges are its slow speed and overly verbose API

  • Port lua-yottadb to become php-yottadb, which would be fast and clean

The second option would take more initial work but provide a better long-term solution. All of this still fails to achieve objective 3 (providing a general-purpose language), but at least it refrains from introducing another new Language.

Summary

The initial objectives may be reached as follows:

Option Hurdle
OpenResty + LuaJIT
-- achieves all objectives
- add support for LuaJIT into lua-yottadb
- stuck with Lua 5.1
Nginx-lws
-- achieves all objectives
- no web framework
Redbean - non-standard
-- achieves all objectives
- not a general-purpose web server
- no built-in python module
Drop Lua for Python
-- achieves all objectives
- port speed/syntax improvements to YDBPython
- bigger/slower than Lua
PHP only
-- fails objective 2
- port lua-yottadb to php-yottadb (better)

The first four options achieve all objectives. OpenResty is a very good option if Lua 5.1 can be tolerated. Nginx-lws is a good option with less web framework. Redbean is great if you are willing to serve non-Lua apps more slowly. Failing that, a complete switch from Lua to Python would also achieve all objectives, at a slight speed penalty.