Lwan: an experimental, high-performance HTTP server in C
Experimental, scalable, high performance HTTP server
At a glance
- What is it?
- Lwan is a high-performance HTTP server written in C, distributed as source, container images and distribution packages. It is aimed at engineers who want to embed an HTTP server in a C program or study a small server's internals, not at teams replacing nginx tomorrow.
- Who is it for?
- Adopt Lwan if you are writing a C service that needs an embedded HTTP layer, or if you want to read and modify a small server's request path. Do not adopt it if you need a mature, stable release line, since the project describes itself as experimental and has tagged three releases since 2022.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- lpereira/lwan6,043 ★ · +6
| Repository | 2026-09-23 | 2026-11-13 |
|---|---|---|
| lpereira/lwan | 6k | 6k |
6 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What Lwan is for, and what it is not
Lwan is described in its README as a high-performance and scalable web server, and the repository tags it as experimental. The primary language is C, the licence is GPL-2.0, and the project lives at lwan.ws. That combination tells you the intended audience: people who are comfortable reading C, running CMake, and linking a server library into their own binary rather than configuring a packaged daemon.
The build produces more than one executable. Alongside src/bin/lwan/lwan, the main binary, the build generates a testrunner, several sample servers under src/samples (freegeoip, techempower, clock, forthsalon), and a set of build-time tools under src/bin/tools. The presence of a TechEmpower benchmark suite and a bundled weighttp rewrite signals that performance measurement is part of the project's own workflow, not an afterthought. The README is explicit that -DCMAKE_BUILD_TYPE=Release should be used when benchmarking, and warns that the default Debug build logs every request to standard output while holding a lock.
There is a lwan.conf at the repository root and a wwwroot directory.
How the build and runtime are put together
The dependency list is small and mostly standard. CMake 2.8 or later is required, together with one compression library: libdeflate, zlib-ng or ZLib. Everything else is optional and detected at configure time. Lua 5.4, Valgrind, Brotli, ZSTD and mbedTLS are linked only if present, and Brotli and ZSTD can be forced off with -DENABLE_BROTLI=NO and -DENABLE_ZSTD=NO. On Linux, TLS support via mbedTLS is on by default through -DENABLE_TLS=ON.
The allocator is a configure-time choice rather than a runtime one. Passing -DUSE_ALTERNATIVE_MALLOC to CMake accepts mimalloc, jemalloc, tcmalloc, or auto, which autodetects among them and falls back to libc malloc when none is found. That is a build-time decision baked into the binary, so switching allocators means rebuilding.
The repository also carries a Dockerfile and a Containerfile, and the README lists container images as one of its install routes.
Building Lwan and serving a first request
The README gives a clone, a build directory, a build type and make. The clone command uses the git protocol, which some networks block; the https form of the same URL is the usual workaround, but the README does not mention it.
git clone git://github.com/lpereira/lwan
cd lwan
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
makeThe result is a set of binaries under the build tree. The main one is src/bin/lwan/lwan, and the README says it can be run with --help for guidance. The first real step after a successful build is to run it and read the output.
./src/bin/lwan/lwan --helpThe README also lists container images as an install route.
Where Lwan gets in your way
The README's build section covers dependencies, package names per distribution, build commands and the list of produced binaries; for configuration, handlers and TLS setup, check the rest of the README and the project web site before planning around them.
Operating it in production has a similar shape. The release list shows v0.7 in June 2025 and v0.6 in September 2024, so releases are infrequent; the README does not promise a cadence.
The debug build is a trap worth naming. The README warns in a callout that the default build type is Debug, that it logs all requests to standard output, and that it does so while holding a lock. A server left on the default build type will behave very differently from the release build under load, and the README's instruction to use Release when benchmarking exists precisely because of that. Anyone who builds with plain cmake .. and then wonders why throughput looks wrong has hit a documented, avoidable problem.
Finally, platform support is narrower than the dependency list suggests. CI covers Linux x86_64, FreeBSD 15 x86_64 and OpenBSD 7.9 x86_64, with static analysis and tests on Linux. Nothing in the README indicates Windows support.
Lwan against a general-purpose web server
The natural comparison is with a mature, configuration-driven server such as nginx. The difference is architectural intent rather than feature count. nginx is a standalone daemon you configure with files, extend with modules compiled against a stable interface, and operate through a documented set of directives and signals. Lwan's README instead leads with building the server yourself and lists sample binaries that embed it, including a FreeGeoIP implementation and a TechEmpower benchmark entry.
That has consequences. With nginx you get a separate process, a reload signal and a documented module ABI. With Lwan the HTTP layer is part of your binary, so the build flags you choose for the server (allocator, TLS, Brotli, ZSTD) are the flags of your application. The trade is control and footprint against operational familiarity. If your team already runs nginx and has runbooks for it, Lwan replaces that knowledge with C build tooling.
The bundled weighttp is a second, smaller point of contrast. Rather than depending on an external benchmarking client, the project builds a rewrite of weighttp alongside the server. That keeps the measurement loop inside the repository, which is convenient for contributors and irrelevant for operators.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-11-01. Releases are tagged v0.5 (2022-05-28), v0.6 (2024-09-21) and v0.7 (2025-06-17), with the v0.5 tag described as the fifth experimental release. The gap between v0.5 and v0.6 is roughly two years and four months, and between v0.6 and v0.7 roughly nine months.
Upgrade cost is also a function of the build flags. Because the allocator, TLS, Brotli and ZSTD choices are all configure-time, an upgrade means re-running CMake with the same arguments and confirming that the optional libraries are still detected.
The licence is GPL-2.0. That is a copyleft licence, and the practical question for anyone embedding Lwan in a larger program is how the combined work would be distributed. This article cannot give legal advice; the point is that GPL-2.0 is a materially different starting position from a permissive licence, and it should be reviewed before Lwan is linked into a product rather than after.
Editorial conclusion
Adopt Lwan if you are writing a C service that needs an embedded HTTP layer, or if you want to read and modify a small server's request path. Do not adopt it if you need a mature, stable release line, since the project describes itself as experimental and has tagged three releases since 2022. Before committing, verify three things yourself: that your platform is one of the CI targets listed (Linux x86_64, FreeBSD 15, OpenBSD 7.9), that the optional TLS path with mbedTLS builds on your toolchain, and that the GPL-2.0 terms fit how you intend to link and distribute the result.
Frequently asked questions
How do I build Lwan from source?
Clone the repository, create a build directory, run cmake with -DCMAKE_BUILD_TYPE=Release, then make. The README lists CMake 2.8 or later and libdeflate, zlib-ng or ZLib as the only required dependencies.
Does Lwan need Lua, Brotli or ZSTD to build?
No. Lua 5.4, Brotli, ZSTD, Valgrind and mbedTLS are optional and enabled only if the build system finds them. Brotli and ZSTD can be turned off explicitly with -DENABLE_BROTLI=NO and -DENABLE_ZSTD=NO.
Does Lwan offer a container image?
The README lists container images as one of three ways to install Lwan, alongside building it yourself and grabbing a package from a distribution, and the repository carries a Dockerfile and a Containerfile.
Which platforms does Lwan support?
The README's build status table covers Linux x86_64, FreeBSD 15 x86_64 and OpenBSD 7.9 x86_64. Static analysis and the test suite run on Linux, and no Windows target appears in the README.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lpereira-lwan)Star history chart for your README
[](https://hysenlabs.com/projects/lpereira-lwan)Was this useful?