volution / kawipiko

kawipiko -- blazingly fast static HTTP server -- focused on low latency and high concurrency, by leveraging Go, `fasthttp` and the CDB embedded database
396 stars 10 forks source link
cdb fasthttp go golang http http-server http2 http2-server http3 http3-server quic quic-server static-server static-site web-server

.. image:: ./documentation/assets/github-banner.png


############################################# kawipiko -- blazingly fast static HTTP server #############################################

.. highlights::

Table of contents:

* `Manual <#manual>`__ and `Examples <#examples>`__
* `Installation <#installation>`__ and `FAQ <#faq>`__
* `Features <#features>`__ and `Benchmarks <#benchmarks>`__
* `About <#about>`__, `Copyright and licensing <#notice-copyright-and-licensing>`__, `SBOM <#sbom-software-bill-of-materials>`__, and `References <#references>`__
* `chat on Discord <https://discord.gg/NH7V7NKjNu>`__, `discuss on GitHub <https://github.com/volution/kawipiko/discussions/categories/discussions>`__, or `email author <mailto:ciprian.craciun@gmail.com>`__

About

kawipiko is a lightweight static HTTP server written in Go; focused on serving static content as fast and efficient as possible, with the lowest latency, and with the lowest resource consumption (either CPU, RAM, IO); supporting both HTTP/1 (with or without TLS), HTTP/2 and HTTP/3 (over QUIC); available as a single statically linked executable without any other dependencies.

Want to see kawipiko in action?

However, simple doesn't imply dumb or limited, instead it implies efficient through the removal of superfluous features, thus being inline with UNIX's old philosophy of "do one thing and do it well <https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well>__". Therefore, it supports only GET requests, and does not provide features like dynamic content generation, authentication, reverse proxying, etc.; meanwhile still providing compression (gzip, zopfli, or brotli), plus HTML-CSS-JS minifying (TODO), without affecting its performance (due to its unique architecture as described below).

What kawipiko does provide is something very unique, that no other HTTP server offers: the static content is served from a CDB file <#why-cdb>__ with almost no latency (as compared to classical static servers that still have to pass through the OS via the open-read-close syscalls). Moreover, as noted earlier, the static content can still be compressed or minified ahead of time, thus reducing not only CPU but also bandwidth and latency.

CDB files <#why-cdb>__ are binary database files that provide efficient read-only key-value lookup tables, initially used in some DNS and SMTP servers, mainly for their low overhead lookup operations, zero locking in multi-threaded / multi-process scenarios, and "atomic" multi-record updates. This also makes them suitable for low-latency static content serving over HTTP, which is what this project provides.

For those familiar with Netlify (or competitors like CloudFlare Pages, GitHub Pages, etc.), kawipiko is a host-it-yourself alternative featuring:

For a complete list of features please consult the features section <#features>. Unfortunately, there are also some tradeoffs as described in the limitations section <#limitations> (although none are critical).

With regard to performance, as described in the benchmarks section <#benchmarks>__, kawipiko is at least on-par with NGinx, sustaining over 100K requests / second with 0.25ms latency for 99% of the requests even on my 6 years old laptop. However the main advantage over NGinx is not raw performance, but deployment and configuration simplicity, plus efficient management and storage of large collections of many small files.

In relation to kawipiko I've also published a few articles on my own site:


Manual

.. contents:: :local: :backlinks: none

Workflow

The project provides the following executables (statically linked, without any other dependencies):

Unlike most (if not all) other servers out-there, in which you just point your web server to the folder holding the static website content root, kawipiko takes a radically different approach: in order to serve the static content, one has to first archive the content into the CDB archive through kawipiko-archiver, and then one can serve it from the CDB archive through kawipiko-server.

This two step phase also presents a few opportunities:

kawipiko-server

See the dedicated manual <./documentation/manuals/server.rst>__.

This document is also available in plain text <./documentation/manuals/server.txt>, or as a man page <./documentation/manuals/server.1.man>.

kawipiko-archiver

See the dedicated manual <./documentation/manuals/archiver.rst>__.

This document is also available in plain text <./documentation/manuals/archiver.txt>, or as a man page <./documentation/manuals/archiver.1.man>.


Examples


Installation

See the dedicated installation document <./documentation/readme/installation.rst>__.


Features

.. contents:: :local: :backlinks: none

Implemented

The following is a list of the most important features:

Pending

The following is a list of the most important features that are currently missing and are planed to be implemented:

Limitations

As stated in the about section <#about>__, nothing comes for free, and in order to provide all these features, some corners had to be cut:


Benchmarks

See the dedicated benchmarks document <./documentation/readme/benchmarks.rst>__.


FAQ

How to ask for help?

If you have encountered a bug, just use the GitHub issues <https://github.com/volution/kawipiko/issues>__.

If you are not sure about something, want to give feedback, or request new features, just use the GitHub discussions <https://github.com/volution/kawipiko/discussions/categories/discussions>__.

If you want to ask a quick question, or just have a quick chat, just head over to the Discord channel <https://discord.gg/NH7V7NKjNu>__.

Is it production ready?

Yes, it currently is serving ~600K HTML pages.

Although, being open source, you are responsible for making sure it works within your requirements!

However, I am available for consulting on its deployment and usage. :)

Why CDB?

CDB is the venerable key-value embedded database implemented by D.J. Bernstein, <https://cr.yp.to/cdb.html>, and was used in many software solutions implemented by him, most notably qmail <https://cr.yp.to/qmail.html> and tinydns <https://cr.yp.to/djbdns/tinydns.html>__. From there it was picked up by many other network services that required mostly-static low-overhead lookup tables, like for example Postfix as an alternative for its user database.

Until I expand upon why I have chosen to use CDB for service static website content, you can read about the sparkey <https://github.com/spotify/sparkey>__ from Spotify.

The CDB implementation being used is a custom fork of the following:

Why Go?

Because Go is highly portable, highly stable, and especially because it can easily support cross-compiling statically linked binaries to any platform it supports.

Why not Rust?

Because Rust fails to easily support cross-compiling (statically or dynamically linked) executables to any platform it supports.

Because Rust is less portable than Go; for example Rust doesn't consider OpenBSD as a "tier-1" platform.


Notice (copyright and licensing)

.. contents:: :local: :backlinks: none

Authors

Ciprian Dorin Craciun

Please also see the SBOM (Software Bill of Materials) <./documentation/sbom/sbom.md>__ for links this project's dependencies and their authors.

Notice -- short version

The code is licensed under AGPL 3 or later.

If you change the code within this repository and use it for non-personal purposes, you'll have to release it as per AGPL.

Notice -- long version

For details about the copyright and licensing, please consult the notice <./documentation/licensing/notice.txt> file in the documentation/licensing <./documentation/licensing> folder.

If someone requires the sources and/or documentation to be released under a different license, please send an email to the authors, stating the licensing requirements, accompanied with the reasons and other details; then, depending on the situation, the authors might release the sources and/or documentation under a different license.


SBOM (Software Bill of Materials)

This project, like many other open-source projects, incorporates code from other open-source projects (besides other tools used to develop, build and test).

Strictly related to the project's dependencies (direct and transitive), please see the SBOM (Software Bill of Materials) <./documentation/sbom/sbom.md>__ for links to these dependencies and their licenses.


References

See the dedicated references document <./documentation/readme/references.rst>__.