Frequently Asked Questions

Never memorize something that you can look up. Albert Einstein

Why use G-WAN on a VPS (or "Cloud Server")?


Virtualized servers can easily run out of memory during traffic spikes. For example, the Apache default setting for MaxClients allows 150 users to connect simultaneously. VPS servers can quickly go belly-up:

As a typical Apache process requires around 25MB of RAM, a moderate traffic spike of 150 users, will trigger 150 processes consuming 3,7GB of RAM. Since the VPS doesn't have that much memory, the system will swap memory to disk to make room for the new processes – and then swap them back into memory to run them.

This is how VPS or Cloud servers can be stuck for hours (or even days), and they will stay unresponsive long after the traffic spike is gone. During this time, very few users will receive a reply to their requests – and the more they will try, the less the server will be able to recover.

Apache is not an isolated example. DNS or Email server applications, runtimes like PHP or database servers like MySQL can quickly consume huge amounts of RAM. Configuring these applications to avoid memory swapping is not always easy – nor even possible: if Apache is using "MaxClients = 30" then a single script kiddie will be able to saturate your server from his DSL home connection.

For example, with 6 workers for Nginx and worker_connections 4096; while G-WAN is unlimited:

 > Server 'nginx' process topology:       > Server 'gwan' process topology:
 -------------------------------------    -------------------------------------
   6] pid:21228 Process RAM: 0.77 MB       6] pid:6054 Thread
   5] pid:21229 Process RAM: 2.44 MB       5] pid:6053 Thread
   4] pid:21230 Process RAM: 2.44 MB       4] pid:6052 Thread
   3] pid:21231 Process RAM: 2.44 MB       3] pid:6051 Thread
   2] pid:21232 Process RAM: 2.44 MB       2] pid:6050 Thread
   1] pid:21233 Process RAM: 2.44 MB       1] pid:6049 Thread
   0] pid:21234 Process RAM: 2.44 MB       0] pid:5839 Process RAM: 2.19 MB
 -------------------------------------    -------------------------------------
 'nginx' server footprint: 15.39 MB      'gwan' server footprint: 2.19 MB

G-WAN can serve many more simultaneous clients with much less RAM than Apache or Nginx (and it does so without any configuration nor huge amounts of pre-allocated memory). This translates into peace of mind for system administrators and delight for website visitors as G-WAN's latency is also much lower.

And as G-WAN natively embeds an elastic load-balancing reverse-proxy and supports protocol handlers G-WAN can be used to implement DNS, Email or Database servers (benefiting from the G-WAN architecture, scalable on multicore and CPU/RAM low-consumption). Eventually, G-WAN can be made the only server process running on a data-center and greatly reduce the burden of maintenance and configuration – as well as the surface of vulnerability.

How to configure G-WAN's number of concurrent clients?


Unlike other Web servers like Apache2 or Nginx (and Application servers like GlassFish or Tomcat), G-WAN does not use configuration files: the values are adjusted on-the-fly depending on the current context (server load, fetched resource, etc.).

In Apache2 or Nginx, the number of concurrent clients must be hard-coded in configuration files because they reserve the corresponding amount of memory at startup, before listening and accepting connections.

If you configure it with worker_connections 1000000; then Nginx consumes 2.25 GB RAM at startup:

 > Server 'nginx' process topology:       > Server 'gwan' process topology:
 -------------------------------------    -------------------------------------
   6] pid:6053 Process RAM:   0.77 MB       6] pid:4604 Thread
   5] pid:6054 Process RAM: 374.72 MB       5] pid:4603 Thread
   4] pid:6055 Process RAM: 374.72 MB       4] pid:4602 Thread
   3] pid:6056 Process RAM: 374.72 MB       3] pid:4601 Thread
   2] pid:6057 Process RAM: 374.72 MB       2] pid:4600 Thread
   1] pid:6058 Process RAM: 374.72 MB       1] pid:4599 Thread
   0] pid:6059 Process RAM: 374.72 MB       0] pid:4477 Process RAM: 2.19 MB
 -------------------------------------    -------------------------------------
 'nginx' server footprint: 2249.08 MB     'gwan' server footprint: 2.19 MB

In contrast, G-WAN will start with a 2.2MB (1,000x lower) memory usage because it allocates memory on-demand rather than upfront. And load tests show that under heavy traffic loads G-WAN's memory consumption will grow far slower than for Nginx... while G-WAN is serving more requests per second!

This matters: while G-WAN will not be overwhelmed by a traffic spike, Apache2 and Nginx will stop responding because the fixed option has been setup at a low value to save RAM. With theese servers, you must occupy huge amounts of RAM upfront to merely be able to cope with a load peak.

But configuration files and fixed values also raise problems for usability, performance and security:

  • fixed timeouts act like if it takes n seconds for all clients to load a file – whatever the file size or client connectivity!
  • the maximum POST entity size accepted by a server should be tunable on-the-fly as needed (rather than fixed)
  • the tcp_nopush or tcp_nodelay socket options must change depending on the resource type (fixed values are bad)

Failure to use dynamic options means that with Nginx or Apache2 you need different configuration files (and different server sections) to serve each resource sizes optimally! As this can't be done at the byte level, you have to accept compromises (which translate into perfectly unavoidable inefficiencies).

In the relevant cases, the G-WAN API allows you to decide on-the-fly and on a per-connection basis or globally what settings to apply. See the get_env() function and the related G-WAN environment variables.

But for the general case,by using adaptative variables instead of fixed values, G-WAN not only makes it easier for users to deploy server and applications (there's less room for errors and the learning curve is much smaller) but it also makes G-WAN both more efficient and safer (i.e.: dynamically adjusted timeouts defeat common DoS attacks).

G-WAN does not run (no error message)


Please use stable (well tested) Linux releases. Debian and CentOS work very well.

On Linux 64-bit, you have to use G-WAN 64-bit. On Linux 32-bit use G-WAN 32-bit. IP tables or SELinux can also block G-WAN.

On Linux Debian 64-bit, when using G-WAN 32-bit, you will need:

 sudo apt-get install ia32-libs libc6-dev-i386

"bash: ./gwan: cannot execute binary file"


Don't use G-WAN 64-bit on a 32-bit Linux distribution. Use G-WAN 64-bit on Linux 64-bit, and G-WAN 32-bit on Linux 32-bit.

Running servlets gives "permission denied"


This is a file permission issue, either on the /csp directory that contains the scripts, or on the /tmp directory which is used for temporary compilation files.

Make sure that the account used to run G-WAN has the necessary rights (read on /csp and read/execute /tmp) on these /csp directories.

 sudo apt-get install ia32-libs libc6-dev-i386

"loading > error 8246"


This error means that your system configuration won't let G-WAN compile scripts. Renaming the /csp scripts folder will let G-WAN run as a static Web server. If you want to use scripts, then you have to correct your configuration.

Look why your system cannot compile /csp scripts: is GCC installed? Even if GCC is installed, you might not have the required system libc headers. On Debian, use:

 sudo apt-get update
 sudo apt-get install libc-dev

That error may also happen if you are using a version of the gwan executable that does not match the /gwan/include files. To resolve this issue, dowload the latest G-WAN archive and decompress it in a new directory (or rename your old G-WAN directory) so all the files are matching the same version.

Another common reason is that you are using a very old version of LIBC. LIBC 2.18 is the current stable version. G-WAN requires at least LIBC 2.3.2 to support Linux epoll (I/O event notification).

To find the version of LIBC used on your system, type:

 ldd --version

To find the version of LIBC needed by a program (like gwan), type:

 ldd gwan

Another reason for this error to happen, can be that G-WAN could not use the /tmp directory to store temporary compilation files. The most likely reason is that the 'x' (execute) bit has been disabled for security reasons. The workaround is either to:

  • use a more relaxed policy for the /tmp directory (so G-WAN can use it)
  • or
  • define an alternate /tmp directory (usable for the account running G-WAN) with: export TMPDIR=/.../temp

Note: the "..." above is the placeholder for a directory that you must create.

No Listener


Rather than using configuration files, Listeners and Hosts are defined by using G-WAN sub-folder names:

 / gwan / / # / www       for HTML, CSS, JS, and images
    |         |               |   / logs      for log files
    |	listening on this     |   / handlers  for Handlers
    |	interface (any) and   |   / csp       for scripts (C, C++, C#, Java, PHP)
    |	port number 8080      |   / cert      for SSL certificates
    |                         |
    |             Host name (like
 where the gwan   or IP address (like
 executable is    (one "#"-prefixed root host and
 located          several "$"-prefixed virtual hosts)

For each Listener tied to an interface and port, you will define one single (#-prefixed) root Host and, optionally, one or several additional ($-prefixed) virtual Hosts – each of which serving a different website:

 listener 1: / gwan / / #    (root host)
                                     / $  (virtual host)

 listener 2: / gwan / / #    (root host)
                                     / $       (virtual host)

In contrast, an Alias lets you assign additional domain names to an existing (root or virtual) Host (the folder contents of an alias, if any, are ignored by G-WAN):

 / gwan / / #                (root host)
                            /        (alias)
                            /       (alias)
                            /   (alias)
                            /  (alias)

To recapitulate:

  • virtual hosts let you host different websites on one single IP address;
  • host aliases let you serve the same website from different domain names.


When using a terminal, you will have to quote directory names ('/user/my folder/blah') that contain characters like spaces, dots, or dollar signs to avoid breaking shell commands which use those characters as escape sequences or separators.

Also, make sure that the user account used to run ./gwan has enough privileges to access the directory where you have installed G-WAN. If that's not the case, then G-WAN cannot find a listener because you did not allow it to do so.

404 - Not Found (File Permissions)


You have installed and run G-WAN as expected but Internet Browsers can't access either static nor dynamic contents.

This is most probably a file permission issue. You have to make sure that the G-WAN directories are reachable from the account used to launch G-WAN.

Some directories, like gwan/.../www which contains static files, can be setup as READ-ONLY. Other directories, like logs which contains the log files, or the gzip cache, need to be able to CREATE and READ/WRITE files.

You also need to make sure that the account used in daemon mode (ie: # ./gwan -d:www-data) owns the files it needs to access. To find who owns a directory and with which rights, run this:

 $ ls -ld "/opt/gwan/"
 drwxrwxr-x 2 www-data www 4096 Feb 12 06:24 "/opt/gwan/"

The first expression "drwxrwxr-x" is the file permissions. "www-data" is the owner of the directory, and "www" is the group-owner of the directory. The permissions are divided in 3 groups (owner, group, other users):

 d rwx rwx r-x
 d: directory   ie: chmod 654      effect on directories (write:create/delete/modify)
 -: file        rwx = 111b = 7d    read/write/list files/sub-directories
 r: read        rw- = 110b = 6d    read/write      files/sub-directories
 w: write       r-x = 101b = 5d    read/      list files/sub-directories
 x: execute     r-- = 100b = 4d    read            files/sub-directories

Here is how to proceed from scratch, by creating a new 'www-data' group (if it does not already exist):

$ sudo groupadd www-data

Add to this group the users that will need to share this directory:

 $ sudo usermod -aG www-data user1
 $ sudo usermod -aG www-data user2

Assign the directory ownership to the 'www-data' account:

 $ sudo chgrp -hR www-data /opt/gwan/.../www

Change the file permissions of all files and directories:

 $ sudo sudo chmod -R 2770 /opt/gwan/.../logs

From now, all users can read files but only users that are part of the root and www-data groups can create and write files.

403 - Forbidden (File Owners - high CPU usage)


You have installed and run G-WAN as expected but Internet Browsers can't access either static nor dynamic contents.

This is most probably a file ownership issue. You have to make sure that the G-WAN directories belong to the account used to launch G-WAN.

G-WAN can be started on the command line under the current account, but it can also be started as root, in which case G-WAN will use the privileges to start listening on port 80, better allocate resources, or start in daemon mode (before changing for the lower 'www-data' account):

 $ ./gwan                              // running under the current account
 # ./gwan                              // running under user/group 'www-data'
 sudo ./gwan                           // running under user/group 'www-data'
 sudo ./gwan -d                        // running under user/group 'www-data'
 sudo ./gwan -d:paula                  // running under user/group 'paula'

If the root account is used to start G-WAN then, www-data will be imposed unless another account was explicitely specified (note that this other account must belong to the www-data group). For security reasons, G-WAN will not accept any connection until the root privileges have been dumped.

So, to make it possible for G-WAN to access the /www files, you have to let the 'www-data' group own this directory:

 $ sudo chown -hR www-data /.../gwan/a.b.c.d:80/#a.b.c.d/www

The same must be done for the /gzip cache directory to let G-WAN create and update compressed resources:

 $ sudo chown -hR www-data /.../gwan/a.b.c.d:80/#a.b.c.d/gzip

If these permissions are not set properly then G-WAN will be forced to compress the same files at each request, artificially creating a high CPU usage by defeating the disk /gzip cache.

Remember that you can force a different user and group by specifying ./gwan -d:user:group explicitly.

For more information about file permissions, read the previous question.

Missing Headers


You need to install missing library headers. Here is an example for libc:

Linux Debian 64-bit running G-WAN 32-bit:

 sudo apt-get -y install libc6-dev-i386

Linux Debian 32-bit or 64-bit:

 sudo apt-get -y install libc6-dev

To find which package contains a given header file, install apt-file (available on Debian-based systems):

 sudo apt-get -y install apt-file             // install the apt-file tool
 apt-file update                              // load apt-file's definitions

Then use apt-file as follows:

 apt-file search sqlite3.h                    // search the missing header
 libsqlite3-dev: /usr/include/sqlite3.h       // here is where it can be found
 sudo apt-get install libsqlite3-dev          // install the missing package

Undefined Symbol


If a library used by a C script with the #pragma link directive – or a system library – cannot be found by the linker, then.

On Debian, use apt-get to install the missing dependencies: on 64-bit systems it downloads and installs libraries needed for 64-bit programs (on 32-bit systems it downloads and installs libraries needed for 32-bit programs).

Here is how to install the mysql client library:

 sudo apt-get install libmysqlclient

You will also need to install the library headers for development:

 sudo apt-get install libmysqlclient-dev

Sometimes, a library is not properly installed. For example, SQLite3 may be stored on disk as /usr/lib/ and /usr/lib/ but not as /usr/lib/ which is the required form (usually a file system symbolic link or a hard link) to let applications find the library without knowing the[.major.minor] version name. The solution is then to create the missing link:

 sudo ln /usr/lib/ /usr/lib/

This happens with pre-installed libraries on several Linux distributions. As a result, a G-WAN script using this library won't compile – causing the Web server to fail after it correctly started in daemon mode. The gwan/logs/gwan.log file will tell you what's wrong, and you can check if the problem is fixed by running G-WAN in the terminal (without the -d switch).

Using Libraries from G-WAN scripts


On Linux, /usr/lib lists more than 1,000 pre-installed libraries. Millions of C libraries have been written in 40 years. G-WAN lets you use any of them by adding the #pragma link and #pragma include directives at the top of your C scripts:

#pragma link "sqlite3"                // link with the SQLite3 library
#pragma include "./libraries/sqlite3" // PATH to the SQLite3 headers (if not standard)

#include "sqlite3.h"                  // SQLite3 definitions
#include "gwan.h"                     // G-WAN definitions

int main(int argc, char *argv[]) 

If the library headers are properly installed in the system include PATH then you can use #include <sqlite3.h> instead of the #include "sqlite3.h" and #pragma include used above.

You must link 32-bit libraries to a 32-bit process and 64-bit libraries to a 64-bit process. To know how a given library was compiled, use the command below:

 file /usr/lib/
 /usr/lib/ ELF 64-bit LSB shared object...

C++ libraries can be used from C programs by using an extern "C" {} wrapper around the functions that they export. This is neded because C++ is adding a non-standard (different for each C++ compiler) prefix before every function name to distinguish overloaded functions using the same name with different types or number of arguments (Google "C++ mangling" for more details).

Using Libraries from gwan/libraries


There are times when you want your scripts to call your own libraries (stored under the gwan/libraries directory instead of in the system-wide /usr/lib), to avoid duplicating routines in several scripts, and/or to avoid disclosing their source code.

This is precisely what the R&D team at stack GmbH needed to do, and they have sent us this short how-to to help other users (thanks for sharing).

Say you have lib2 relying on lib1, both of which stored in sub-directories under gwan/libraries:

  gwan/libraries/src              // lib2 source code
  gwan/libraries/dir1/   // lib1 location
  gwan/libraries/dir2/   // lib2 location

Here is the GCC command line to build lib2 to make it resolve lib1 when dynamically linked:

 gwan/libraries/src$ gcc -shared -o ../dir2/ -Wl,-rpath=libraries/dir1 \
                               -L../dir1 -lone libtwo.c

Then the servlet will specify libtwo as usual:

#pragma link "./libraries/dir2/libtwo"
#include "libtwo.h"

Thanks to the -Wl,-rpath=libraries/dir1 linker switch used to build libtwo, libone (the dependency of libtwo), is resolved and dynamically linked at runtime.

Installing system-wide Libraries


If you have created a library called libmy.a (a static library) or (a shared library), then you will use it from G-WAN in the same manner with a simple #pragma include, see the question above.

For static libraries (linked at compilation time with each of your scripts):

 sudo install -m 644 libmy.a /usr/lib 

For shared libraries (loaded once instead of being linked to each script):

 sudo cp /lib                                // files repository
 cd /usr/lib                                                // links repository
 sudo ln -sf ../../                  // create a *.so link
 sudo ldconfig                                              // update the cache

Most of the time you will use shared libraries to save memory (saving memory helps a great deal for performance).

Static linking provides even better performance but may cause issues when mixed with shared libraries (ie: the LIBC runtime may not be the same, causing incompatibilities).

Further considerations:

As we have seen above, libraries may be installed under different directories, some under the system PATH like /usr/lib, /usr/local/lib, etc. (each Unix version and Linux distribution possibly using different conventions).

If you want to link against installed libraries in a given directory called MY_LIBDIR, then you must either use the libtool system command to specify the full pathname of the library, or use the -LMY_LIBDIR linker switch and do at least one of the following:

  • add MY_LIBDIR to the LD_LIBRARY_PATH environment variable at runtime
  • add MY_LIBDIR to the LD_RUN_PATH environment variable during linking
  • use the -Wl,-rpath -Wl,MY_LIBDIR linker switches
  • add MY_LIBDIR to /etc/ (or equivalent)

How can I trace a crash in a G-WAN Handler?


The first thing to do is to add the following directive at the beginning of all your C/C++ scripts (handlers and servlets):

   #pragma debug

Then, the crash's backtrace will make sense as it will show the place where the fault took place (script file name, line number, and function name) instead of something like:

   #0  0x00007fa3169698ad in ?? ()
   #1  0x0000000000000000 in ?? ()

Is G-WAN's source code portable?


Yes, G-WAN is written in ANSI C code, the most widely ported programming language in history. Sometimes people speculate that most of G-WAN is written in assembly language, and they (learnedly) conclude "hence its speed".

In reality, very little assembly was written: this was needed for for atomic operations which address CPU instructions directly. All modern programs have to do the same things, so G-WAN does not specifically benefit from doing this.

We have received reverse-engineering attempt reports from people who concluded that, as their tools did not manage to reverse G-WAN's machine code into meaningful C code, or as they did not understand how this machine code can be generated from C, G-WAN was necessarily using assembly language.

Many things in a server program can be done in efficient ways rather than in the usual academic (but sub-optimal) ways explained in books.

Two things make a program run faster: its design (architecture) and its implementation (coding). G-WAN v4.2.7's 110k lines of code contain 40% of comments. No other server provides so many features in so little code (56k lines, without blank lines). That's what makes G-WAN both faster/more scalable.

Proof? Nginx 1.3.11, which is twice older, requires 94k lines of code (twice more) to do much less things than G-WAN.

Supported CPUs (Illegal Instruction, Floating Point Error)


As G-WAN was written for multicore architectures, the minimum required to run it is either a Intel Core2 or an Intel Atom (both with 64-bit extensions, MMX, SSE, SSE2 SSE3 and SSSE3 instruction set support).

These two CPUs have 2 CPU Cores – the bare minimum to enter the multicore game. G-WAN shines even with the slowest of those 2-Core machines: (the Passmark score is a good indication of the overall CPU capabilities)

Running G-WAN on machines using older CPUs may give an "Illegal/Unsupported Instruction" or a "Floating Point" error message. This is the expected behavior.

Note that G-WAN 4.2.7 32-bit was used on CentOS 6.2 32-bit with an old 2006 SONY Vaio VGN-TX5MN laptop:

 G-WAN 4.2.7 32-bit (Feb 7 2013 15:31:43)
 RAM: (672.18 MiB free + 0 shared + 20.67 MiB buffers) / 997.22 MiB total
 DISK: 35.80 GiB free / 35.10 GiB total
 CPU: 1x Genuine Intel(R) CPU U1400 @ 1.20GHz
  L1d cache:   32K line:64     0
  L1i cache:   32K line:64     0
  L2  cache: 2048K line:64     0
 CPU(s):1, Core(s)/CPU:1, Thread(s)/Core:1
   using   1 workers 0[1]0
   among   1 threads 0[1]0
CentOS release 6.2 (Final) (2.6.32-220.) 32-bit
 memory footprint: 1.29 MiB
 Host /opt/gwan/
 memory footprint: 1.10 MiB
 server started

G-WAN is very fast, even on one single CPU Core – but it's no longer the CPU architecture in use since 2004 (whether on cellphones, laptops, workstations or servers). If you wish to see G-WAN running on an unsupported CPU or if you need a different G-WAN release to support more advanced CPU features then contact us.

Supported Operating Systems


Initially, G-WAN was written for Windows (where G-WAN, an user-mode process, was, depending on the kind of load, 2-5x faster than IIS 7, a server implemented as a kernel module).

After 2009's G-WAN v1 Linux port proved to be 3.5x faster than G-WAN/Windows, the Windows branch was discontinued: G-WAN's purpose is to extract the most of the available hardware.

Since then, G-WAN has greatly improved on speed and features, and is successfully used on many other Linux distributions. If you wish to see G-WAN running on a new platform (OS and/or CPUs) then contact us.

Recommended Operating Systems


Debian remains a decent (relatively well documented) choice but CentOS provides smaller distributions, which may be handy to travel light.

You must test an OS release before blindly assuming that 'newer' means 'better': Ubuntu 10.10 64-bit is faster and more scalable than Ubuntu 12.04 LTS, both of which use the new Linux kernel v3.

It's difficult to make definitive recommendations in a world where OSes change the way they work unpredictably (breaking backwards compatibility without notice) but common-sense should make one prefer server distributions that offer the smallest ISO images (having less code, they have less bugs, execute faster, and are also more stable).

Installing whatever is missing on a tiny core OS is much better than wasting days to figure how to identify and remove the mountains of things that you don't need at all and that should be uninstalled without breaking other things that are have been arbitrarily made mandatory for a given system.

If big players like Read Hat or ORACLE support their software only on their own Linux distribution, this might be for a reason.



This is even more difficult to address than mere Linux distribution and/or version incompatibilities: hypervisors (Xen, VMWare, VirtualBox, etc.) alter the CPU instruction sets in violation of the specifications (like for the CPUID opcode) in addition to altering the OS behavior (in a no more sane manner: "free RAM > total RAM", "0 CPU", "0 Core", broken kernel structures, etc.).

It can be frustrating to see other Web servers run fine on hypervisors while G-WAN may have problems. This comes from the fact that legacy Web servers are not designed to support multicore: users are supposed to run several instances of each single-threaded server, and to manually tie them on different CPU cores, with the inefficiencies (like shared memory) and redundancies (duplicate code and data structures) that G-WAN was designed to address... on deterministic machines.

To find and resolve these hypervisor issues, constant compatibility checks should take place, but this is well beyond our needs (remember that G-WAN was developed to fill a gap in our infrastructure) and we can't justify the effort from a financial point of view, as hypervisor vendors do not document these (ever changing) altered behaviors.

Again, if vendors like ORACLE or Red Hat only support their own "certified" (translate "stable" or "well-known") version of Linux, that may be for a reason.



Benchmarks are the only way to know if your application works – and how well it works. Here is how to install Weighttp (a good multi-threaded ApacheBench replacement).

PLEASE read this page before making benchmarks – many things can explain why you don't get the same results than us (system configuraton, Linux release, type of CPU, type of client test tool, size of tested file, virtualization, etc.) and this document tries to address all the possibilities to let your machines go as fast as possible.

Here is a couple of benchmark examples.

The ApacheBench (AB) client is using one worker thread. Therefore, AB cannot saturate a server using several threads like G-WAN. To really test G-WAN you must use a multi-threaded client like Weighttp (in this case, on a single 6-Core CPU, G-WAN is 16x faster than Nginx used with one worker per CPU Core – the server architecture since 2004.

Many single-threaded servers 'prefer' AB tests for this sole reason: its total irrelevance on multicore systems.

I wrote a wrapper for AB and Weighttp which you can see exercised here to test the scalability, performance and resource utilization (CPU and memory) of Web servers.

See AB compared to Weighttp to measure how important the difference is.

Remember, what you ignore will bite you at the worse time: that is, when you will really need to rely on second-hand assumptions that you took for safe to blindly adopt.

Finally, some have modified the original Weighttp client test tool written by Lighttpd's Team in order to dynamically reschedule connections if the server does not handle them evently.

They claim that this is right since then their server is passing their test faster. This modification just hides the defects of the server scheduler (its inability to handle client traffic as it comes, how contrarian to the server's expectations and design this might be).

It should be obvious (even intuitively) that a server should NEVER be in a position to dictate to clients how they are supposed to schedule their requests to please it (clients are rarely here to please), and even less dynamically.

A closer look at what these creative guys are doing will also teach you how far some are not shy to publish cooked numbers, close connections before serving the whole contents, etc. to merely shine in benchmarks.

If it sounds like a repetition, that may be because it is one: double check, tripple check, everything, everytime. And trust only those who give you access to the means necessary to make yourself an opinion.

Open-Source (License)


G-WAN is a freeware. It means that it is free for all (commercial users included). We can often read that "a product without its source code cannot be used because it can't be trusted".

Hmm... surely they don't use a car, a TV, a cellular phone, a voice answering-machine, a fax, or even a washing-machine, right? These devices are not open-source, nor their online updates and add-ons tunnelled by service providers.

How can they use a computer? Even Linux relies on closed-source software: proprietary drivers, codecs and firmware (keyboards, BIOS, hard-disks, disk controllers, video boards, network adapters, printers, Wifi stations, etc. some of which are notoriously used to hack remote computers).

But this 22-year-old X Window critical security hole will surely convince the most reluctants about how heavily scrutinized the most widely used open-source software (here all Unix flavors) is – and how serious the security auditors are about providing a relevant service... in the real world.

Like their closed-source peers, open-source "trusted security" champions, such as OpenSSL Foundation (among many others), are paid by governments to backdoor both the whole ecosystem (Windows, Mac OS X, Linux, Solaris, BSD, OpenVMS, IBM OS/400, hypervisors, security appliances, smartcards, firewalls, VPNs, etc.).

So, claiming that the "many-eyes" open-source policy is a guaranty of security is mere propaganda: your secret keys (SSL certificates, SSH connections, OS updates, etc.) are happily processed by NSA-backdoored Operating systems and libraries... a fact that no open-source blogger or open-source company feels the urge to criticize.

Another argument is that "having the source code lets the community find hidden vulnerabilities".

  1. Most vulnerabilities are found by testing the binaries: executables are the end-result;
  2. Despite Microsoft products being closed-source, new security holes are inserted and found constantly;
  3. Despite being open-source, Apache or Nginx are exposing their users to new critical vulnerabilities – every single year.

G-WAN makes more efforts than others to be trustworthy: no vulnerability was found since its first release in 2009. This was so unacceptable for our "trusted" competitors that in 2011 they have felt the need to forge a fake advisory.

Another fallacious argument is that G-WAN would no longer be supported if its author disappeared.

  1. Big companies die (Compaq, DEC, SUN...) or discontinue product lines (Microsoft PDS-Basic, Visual Basic, etc.);
  2. To this effect, G-WAN provides a source code insurance to secure people's investment in case of support interruption;
  3. If Nginx modules are such a pain to create and use, fixing its uncommented and bulky source code is even harder:
serverbirthfilesindentationblank linescomment linessource code linestotal lines
Apache1995368K&R variant29,44048,55877,951155,949
Nginx2002256K&R variant35,1314,30894,369133,808

G-WAN, while using a more readable indentation and more comments, needs less source code lines to offer more features.

The open-source argument is clearly mis-used by some vested bloggers to spread F.U.D.:

  • G-WAN is free for all – and users can subscribe to support plansjust like for the less capable open-source servers;
  • G-WAN offers licensing options to those software vendors who want to benefit from G-WAN's so fruitful years of R&D.
  • G-WAN was written because other Web application servers are a pain. At TWD Industries AG we needed a better tool.

And, instead of keeping G-WAN for the company he founded in 1998 Pierre released it as a freeware for all to benefit from it.

  • End-users: just need to have the job done – at the best cost (cost-reduction is what makes a faster server appealing in the first place). And since G-WAN can be used gratis, there is no way to reduce costs any further;
  • Software vendors: using others' many years of R&D for free is appealing: they can 'fork' the code, put their name on it, and sell licenses (or Cloud subscriptions) without ever contributing to the project that fuels their business. Since the U.S. Dept. of Justice fails to punish the big companies that violate US and international laws, startups and smaller firms don't have a chance.

Next time someone feels the need to publicly call G-WAN's (1-page) license "weird" or "insane", look at what they sell and who they get their revenues from. And, guess what, on the top of forcing you to burn cash at wasted hardware resources or to expose your network infrastructure and your data to spies and crooks, unlike G-WAN, what they offer is not free at all.



If a G-WAN script crashes, then the server does not go down, a detailled crash report is issued either interactively in the terminal or in the gwan/trace log file.

If the G-WAN process crashes/freezes itself (since 2009 we haven't seen this happening consecutively to receiving client data), then the parent process (kills a frozen child if any and then) restarts a new clean child process.

In any case, a G-WAN server crash and restart is stamped and logged in the gwan/trace log file, and a crash report is also issued here, with a backtrace when available (ie: when the thread stack was not corrupted).

The break-down of threads in a child G-WAN process is explained here. By default, G-WAN starts as many worker threads as your server has physical CPU Cores.



Despite its small footprint, G-WAN is an all-in-one solution because communicating with other servers (FastCGI, SCGI, etc.) takes time (enlarging latency), and wastes CPU and RAM resources when the network can be avoided. Also, supporting many programming languages lets G-WAN serve most needs instead of having to use slower backend servers and fontend caches. Remember that our goal here is to use the ultimate low-latency and resource-saving solution. This is why G-WAN is a:

  1. Web server
  2. App. server
  3. Cache server
  4. Key-Value store server
  5. Reverse-proxy and elastic load-balancer server

To cache a file or a page generated dynamically, you can use the G-WAN Caching API with cacheadd(), cacheaded() and cacheget() implemented via the G-WAN 'wait-free' KV store.

But this feature does not replace dedicated cache servers (also called "Web accelaration servers") like Nginx (which has a cache activated by default, see its --without-http-cache compilation option used by proxy_cache and fastcgi_cache) Varnish or Apache Traffic server (ATS) which are used to transparently cache the data served by backend servers.

To reduce the need for a frontend cache server (and to let G-WAN be used as a caching reverse-proxy) You can enable G-WAN micro-caching, a RESTful feature disabled by default (see the gwan/init.c file).

When a given URI is invoked at high concurrencies and when generating the payload take a lot of time, then G-WAN will automatically cache a page for 200 milliseconds (the average latency on the Internet) to make sure that the cache is up-to-date: within 200 ms, consecutive requests provide the expected result.

Requests using cookies are not cached as they are intended to be unique for each user. To use caching on a per-request basis, enable the caching feature and disable caching by using a changing query parameter (per user session id, random, counter, etc.) or use the RC_NOCACHE return value for servlets. Obviously, the cache is also disabled if a servlet returns RC_STREAMING.

But G-WAN is very fast even without micro-caching because:

  • G-WAN allows dynamic contents to be generated faster than the same LIBC-based program (either stand-alone or Apache/Nginx pre-compiled modules). See this example comparing G-WAN to Windows and Linux system calls.

    A clear illustration of this capability is the time needed to generate (here without concurrency) a loan(100 years) page:

    ›   G-WAN + C script ............ 0.4 ms    GCC -O3 loan.c ... 5.67 ms   G-WAN is 15x faster than standalone C code
    ›   Apache + PHP ............... 12.6 ms
    ›   GlassFish + Java ............42.3 ms
    ›   IIS + ASP.Net C# ......... 171.8 ms

  • G-WAN is a faster server even when micro-caching not triggered: caching hello world would actually slow-down things by involving a cache lookup where a simple static string copy is faster. Because G-WAN is a faster server it serves small payloads faster than the fastest servers (see G-WAN hello world benchmarks).

When a G-WAN script has to make slow calculations (loan) or to fetch a value from a (database) backend server, the network is slow and a database is even slower so they will both produce high latencies. In this case, caching is the only way to serve hundreds of thousands of concurrent requests with a single server.

At the ORACLE Open World, G-WAN has accelerated ORACLE noSQL to reach 1.2 billion TPS on a 6-Core machine. That was done by working as a cache between the 45,000 live users (and 100 millions of bots) stored by ORACLE noSQL.

For more common applications, the point of micro-caching is to avoid the need for yet another server process burning cash on another dedicated machine because G-WAN works fine as a cache (see Varnish compared to G-WAN).

Caching is so important that the Internet is heavily relying on distributed proxy servers (CDNs or gateways at ISPs and enterprises) and local caches (in Internet browsers like Firefox, Chrome, Opera or IE) to speedup requests and spare resources (it is pointless to fetch a valid answer already made available in the past).

Caching is also used in CPUs (that's one of the rare ways that make it possible to run non-parallelized code faster on multicore), disk controllers as well as file systems for the very same reason: saving time and resources that can be better allocated elsewhere. We as human beings call it "short-term memory" and we could hardly work without it.

Changing the PATH


You have to change the PATH variable if you want to call programs without specifying their location.

The PATH is defined in the file /etc/profile. It applies to all users. This is a colon-separated list of directories that you can list as follows:


Edit the PATH as follows:

 sudo gedit /etc/profile

After modification, reload the PATH:

 . /etc/profile
 source /etc/profile

You can find the PATH of a program by typing:

 type apache2
 apache2 is /usr/sbin/apache2


 which apache2

Setting ENVIRONMENT variables


Many examples here explain how to use the export command to change session-wide environment variables for one user. But if you want those changes to be permanent and system-wide then do that:

 sudo gedit /etc/environment                        // add environment variables
 source /etc/environment                            // reload environment

Here you would have to add variable definitions like:


If you decide instead to use the ("less recommended") /etc/profile configuration file then do this:

 sudo gedit /etc/profile                            // add BASH commands
 source /etc/profile                                // reload profile

Here you would have to add BASH commands like:

 export JAVA_HOME="/usr/lib/jvm/java-6-sun"

We publish this information because we belive that it may be useful to those who do not know (yet) how to proceed. Reading the dedicated Ubuntu help page makes it clear that, oddly, this is not a trivial issue.

ENVIRONMENT variables are ignored


You have defined environment variable like above and they have no effect. Chances are that you are using sudo which does not load the system wide variables... unless this is explicitely requested:

 sudo -i                               // load environment variables
 cd /opt/gwan                          // go to the G-WAN directory
 ./gwan                                // start G-WAN with environment variables

This sudo problem does not exist with the regular root account most likely used on a production server.

Service Mode


To start G-WAN as a service (make it start automatically at boot time) use the script below:


# Provides:          G-WAN
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: G-WAN initscript
# Description:       This initscript starts and stops G-WAN

# Author: Thomas Meitz, gwan at jproxx dot com
# Modified by: Fnux, fnux.fl at gmail dot com (environment variables)
# Version: 1.3 as of 10.27.2013
# Note: (edit the GWAN_PATH variable if G-WAN isn't installed in /opt/gwan_linux64-bit)
# 1. copy under /etc/init.d 
# 2. chmod 775x /etc/init.d/gwan
# 3. update-rc.d gwan defaults 95 5

STARTMESG="\nStarting TrustLeap G-WAN Web Application Server in deamon mode."
UPMESG="\n$NAME is running."
DOWNMESG="\n$NAME is not running."
TESTMESG="\nStarting Trustleap G-WAN Web Application Server in client mode.\nHit Ctrl+C (or close the terminal) to stop G-WAN."
STATUS=`pidof $NAME`

# Exit if G-WAN is not installed
[ -x "$GWAN_PATH/$NAME" ] || exit 0

case "$1" in
        echo $STARTMESG
        cd $GWAN_PATH
        ./$NAME $START
    cd $GWAN_PATH
        ./$NAME $STOP
    if [ "$STATUS" > 0 ] ; then
        echo $UPMESG
        echo $DOWNMESG
    cd $GWAN_PATH
    ./$NAME $STOP
        echo $STARTMESG
    ./$NAME $START
    cd $GWAN_PATH
        ./$NAME $VERSION
    cd $GWAN_PATH
    echo $TESTMESG
        echo "Usage: $SCRIPTNAME {start|status|restart|stop|version|test}" >&2
        exit 3

To install the script above under /etc/init.d/gwan and run it (under Debian):

 gksudo gedit /etc/init.d/gwan        (paste the script above and save the file)
 sudo chmod 755 /etc/init.d/gwan      (change the file access rights) 
 sudo update-rc.d gwan defaults 95 5  (after this, reboot)
 sudo service gwan start              (start the gwan service)

Cron Jobs (maintenance)


cron is a system tol used to start periodic tasks at a given time (see man cron and man crontab for more details). It can be used to stop and restart G-WAN, run system integrity checks, make backups, transfer log files, etc. Here is an example for Ubuntu:

# this system configuration file is stored as /etc/cron.d/gwan

# modify as needed

# restart /opt/gwan/gwan daily (UTC time) every day
# Syntax: MIN(0-59) HOUR(0-23) DAY(1-31) MONTH(1-12) WEEKDAY(0-6) ACCOUNT COMMAND(S)
# (unlike '&&' which stops at the first error, the ';' command separator ignores errors)
00 16 * * * root /opt/gwan/gwan -k;/opt/gwan/gwan -d:www-data

Other Linux distributions may use another system PATH to store cron jobs (check your system's man pages).

Support of Programming Languages


As G-WAN supports scripts in many languages (C/C++, C#, PHP, Java, Javascript, Lua, Go, Perl, Python, Ruby, etc.), people invariably ask how their (currently unsupported) favorite language can be made working with G-WAN.

This is not always easy because of many factors, among which the most common problem is the lack of (correct and/or up-to-date) documentation from the language vendor.

If you want to use a new language with G-WAN then contact us. Having built more than a dozen of interfaces so far, there's chances that one more can be added if people provide the relevant information.

Setup of Programming Languages


Note that the support of those languages (without handler) depends on the G-WAN version:

  • asm ............... v1+
  • C ................. v1+
  • C++ ............... v3.1+
  • C# ................ v3.8+
  • D ................. v3.1+
  • Go ................ v3.10+
  • Java .............. v3.2+
  • Javascript ........ v3.10+
  • Lua ............... v3.10+
  • Objective-C ....... v3.1+
  • Objective-C++ ..... v3.1+
  • Perl .............. v3.10+
  • PHP ............... v3.10+
  • PH7 ............... v4.11+
  • Python ............ v3.10+
  • Ruby .............. v3.10+
  • Scala ............. v3.9+

As you can see, G-WAN v3 has worked hard to offer many more programming languages to let almost all developers benefit from multicore CPUs.

A G-WAN user has generously donated a bash script to install these 15 languages (and the ab.c/weighttp benchmark tool) on many Linux distributions (Debian, LinuxMint, CentOS, Fedora, RedHat, Manjaro, Arch Linux and Bridge). The installation menu is available in English, German, French and Spanish!

Version numbers are formatted as [Year.Month.Day]. Some of the version numbers listed above were non-published beta releases available for registered users (at the 'Enterprise' level or greater) or for partners who have helped with those technologies. The '+' following a version number means that any more recent version supports the specified language.

To develop in C you have to install GCC, the C compiler:

 sudo apt-get install gcc build-essential

To develop .NET C# applications you HAVE to download the source code and build the C# runtime:

 tar -xjf mono-3.0.2.tar.bz2; cd mono-3.0.2
 sudo ./configure --prefix=/usr; make; make install

On Ubuntu 10.x the Mono packages contained the necessary files but this is no longer the case.

GAC libraries can be linked to your G-WAN scripts by using the following comment at the top of your script:

 // pragma link mylib

Other C# libraries can be forced to be linked with all your G-WAN scripts by copying the *.dll files in the /.../gwan/libraries/cs/dll folder.

The D programming language requires you to write "extern (C)" before all (translated in D) gwan.h prototypes (see the hello.d example). The D import replacement for the C include directive could probably be used – if only its file-system mapping was documented). Any help in this matter is appreciated.

For Java, use the OpenJDK or the SUN/Oracle JVM. G-WAN + OpenJDK has a 20 MB footprint on Linux Debian 6 64-bit (the JVM is loaded only if a /csp folder contains *.java scripts).

 sudo apt-get install openjdk-7-jre
  • To specify which Java VM you want to use, define the $JAVA_HOME environment variable:
     export JAVA_HOME=/usr/lib/jvm/java-6-sun
     export PATH=$PATH:$JAVA_HOME/bin

    You can clear an environment variable with the command: unset JAVA_HOME

  • To load external classes with import, add their path to the $CLASSPATH environment variable:
     export CLASSPATH

  • To load JAR archives with import, add them to the $CLASSPATH environment variable:
     export CLASSPATH


In the past, G-WAN was using the javac compiler of its corresponding JVM, and both were loaded from the same jdk/bin directory branch. As recent versions of Linux have removed the javac compiler from its corresponding jdk/bin directory, G-WAN is using the JVM compiler found in the PATH when this is hapening. If you don't want that to happen then create a jdk/bin/javac link pointing to the right javac compiler (the one really matching the JVM that you have specified).

If Java Scripts Do Not Work

 1. delete all openjdk pakets
    a. sudo apt-get purge openjdk-\* icedtea-\* icedtea6-\*

 2. Download Java 7 from Oracle and uncompress into /opt directory
    b. move the download to /opt
    c. cd /opt
    d. gunzip jdk-7u10-linux-x64.tar.gz
    e. tar xvf jdk-7u10-linux-x64.tar

 3. edit /etc/profile (put these line to the end of the file)
    a. export JAVA_HOME="/opt/jdk1.7.0_10"
    b. export PATH=$PATH:$JAVA_HOME/bin

 4. relog

This Java troubleshooting procedure has been provided by Thomas Meitz, gwan at jproxx dot com

Scala relying on the JVM, it requires the same dependencies needed by Java, check the tips above to make sure that a JVM can be used for G-WAN scripts. When this is the case, you can install and configure the Scala runtime:

 sudo apt-get install scala

If scalac cannot be invoked from a prompt then create $SCALA_HOME and add it to the PATH:

 export SCALA_HOME=/usr/share/java
 export PATH=$PATH:$SCALA_HOME/bin

Then you MUST include the Scala runtime and libraries in the Java $CLASSPATH:


Oddly, this last step in not done by the Scala installation (which has added the SCALA_HOME to the PATH for me). When it is missing (like that was the case for me) then the first time you will run a scala servlet you will get the following error:

 Exception in thread "..." java.lang.NoClassDefFoundError: scala/ScalaObject

This error means that the Scala runtime was not found by the JVM.

To install the Javascript runtime on Debian, run the following command:

 sudo apt-get install nodejs

Your're done... that is, if you have the latest Debian/Ubuntu release. Else, many things are broken so you should rather install manually (install the latest source code archive by replacing the version number below):

 gunzip node-v0.6.12.tar.gz
 tar -xf node-v0.6.12.tar
 cd node
 sudo make install  

To install the Google Go runtime, download the latest Go binary package or source code.

To install the binary package do this (replace the version number by yours):

 sudo tar -C /usr/local -xzf go1.0.3.linux-amd64.tar.gz

Then, add Go to your PATH (you can do it permanently in the /etc/environment file):


Note that sudo ignores the /etc/environment file unless you run "sudo -i" to force sudo to load the /etc/environment file. Then, you will have to cd to the G-WAN directory and run the ./gwan program.

We initially made Go benchmarks by using the Ubuntu 10.10 package below but users reported that this is no longer working:

 sudo add-apt-repository ppa:gophers/go
 sudo apt-get update
 sudo apt-get install golang

If you have installed the golang package in the past then you will have to remove it before installing the latest version:

 sudo apt-get remove golang

To install the Lua runtime, run the following command:

 sudo apt-get install lua

Objective-C requires the following dependencies:

 sudo apt-get install gobjc gnustep gnustep-devel build-essential

If, when compiling, you get the kind of errors below:

 Foundation/NSObject.h: No such file or directory

Then, create the links below:

 sudo ln -s /usr/include/GNUstep/Foundation /usr/include/Foundation
 sudo ln -s /usr/include/GNUstep/GNUstepBase /usr/include/GNUstepBase
 sudo ln -s /usr/include/GNUstep/ObjectiveC2 /usr/include/ObjectiveC2

Run the following command to install the Perl runtime:

 sudo apt-get install perl

Run the following command to install the Python runtime:

 sudo apt-get install python

Run the following command to install the Ruby runtime:

 sudo apt-get install ruby

On Debian, run this command to install the PHP runtime:

 sudo apt-get install php5-cli

G-WAN supports many PHP-specific environment variables, including $_GET and $_POST, see the hello.php example.

G-WAN supports another PHP runtime called PH7 (from Symisc Systems SUARL) that you can install by doing this:

 1. download the PH7 'amalgamation' source code

 2. compile PH7 (-m32 is for 32-bit, -m64 for 64-bit):
     gcc -m32 -Os -o ph7.c -fPIC -shared -fstack-protector-all -D PH7_ENABLE_THREADS
     gcc -m64 -Os -o ph7.c -fPIC -shared -fstack-protector-all -D PH7_ENABLE_THREADS

 3. copy the shared library ( in the gwan/libraries/ph7 directory

Then, G-WAN will be able to run *.ph7 scripts (so you can run both *.php and *.ph7 scripts at the same time from G-WAN). Of course, you can define either PHP or PH7 as G-WAN's default language and omit the extension when invoking scripts.

What's the point? PH7 can be made thread-safe. Therefore, it can run directly from a multi-threaded process like G-WAN. This allows PH7 to be much faster and scalable than PHP (which crashes if more than one worker thread is running the Zend VM). This is why PHP has to be used as a (slower) CGI/SCGI/FastCGI process by G-WAN.

PH7 currently supports quite a large subset of PHP, but the PH7 authors said that they will add missing (core and library) calls if they are sponsored. At 500,000 requests/second on a 6-Core without caching(!), this is certainty an option worth exploring.

A suggestion to enhance these FAQs? Let us know.

Questions Not Answered Here


For those looking for it, the G-WAN Forum initially setup graciously by G-WAN users in 2010 has been put offline (by their maintainers) in Sept. 2012. This Forum was aimed at letting people search for replies to common questions, as well as ask your own questions about how to use G-WAN.

Stackoverflow is also a good place to get technical replies (don't forget to indicate the [g-wan] tag to let G-WAN users find your questions – and either benefit from them or participate to the answers).

For more specific questions, contact us.