Xojo and load balancing with Haproxy

Xojo and load balancing with Haproxy

I have previously written a post on load balancing for Xojo web app developers using Nginx. You can see the post here. This is an update to that post focusing on Haproxy instead of Nginx.

You can learn more about and download Haproxy here.

Why choose Haproxy over Nginx?

There are pros and cons to each of these solutions – but Haproxy offers better options for sticky sessions than the standard free Nginx package. If you get the Nginx “plus package” ($1350) then Nginx would be the better overall solution. But for free, Haproxy beats it for pure load balancing capability. Specifically, Haproxy includes cookie injection and routing which allows you to tag each user with a cookie indicating what back-end Xojo process to route them too – which maintains the session. Without the “Plus package” the best Nginx can do is IP hashing which will route an entire office of users (if behind one NAT IP) to the same single instance of your app. If you have multiple users in the same location (ex. employees of the same business) then the load balancing is defeated. If that is not your circumstance, then check out the Nginx post – it may be a better choice for you. Nginx can also offer the power of serving non Xojo web pages and static content such as images.


Haproxy Configuration

        log local0
        maxconn 4096

        log global
        mode http
        option httplog
        option dontlognull
        retries 3
        option redispatch
        maxconn 2000
        contimeout 5000
        clitimeout 50000
        srvtimeout 50000

frontend http-in
        bind *:80
        acl is_myapp1 hdr_end(host) -i myapp1.mydomain.com
        acl is_myapp2 hdr_end(host) -i myapp2.mydomain.com

        use_backend myapp1pool if is_myapp1
        use_backend myapp2pool if is_myapp2
        default_backend myapp1pool

backend myapp1pool
        option httpchk OPTIONS /
        option forwardfor
        option http-server-close
        cookie serverid insert indirect nocache
        server node1 check cookie node1
        server node2 check cookie node2
        server node3 check cookie node3

backend myapp2pool
        option httpchk OPTIONS /
        option forwardfor
        option http-server-close
        cookie serverid insert indirect nocache
        server node1 check cookie node1
        server node2 check cookie node2
        server node3 check cookie node3


The above configuration shows how to set up basic Xojo compatible load balancing (for standalone apps) and also how to set up different apps under different sub-hosts on the same server. Here are some things to notice:


The timeouts here are values that are working well for me. Feel free to play with them. If they are too low you will run into “Application went offline” messages.


This uses ACLs (Access Control List) to change backends depending on the hostname being requested. This allows you to set up multiple apps on the same server under different hostnames (e.g. app.hostname.com and otherapp.hostname.com). This feature is really powerful and flexible, just scratching the surface here. But this works great. You can have an unlimited number of ACLs/hosts/apps being routed here. The ACL rule names, host names and backend names can be whatever you want – these are just placeholders.


Set up a separate backend for every app you want to serve. This injects a cookie called “serverid” and assigns it a value of “node1”, “node2”, or “node3” depending on which backend app-instance it routes to. Once the cookie is set, haproxy routes subsequent requests from that user to the same app-instance, maintaining the session. Xojo also includes a “sessionid” cookie which it uses to maintain session.


Because Xojo web apps only utilize a single processor core per instance the total processing power of the server is underused. There is no multi-processor capability within the Xojo web app itself automatically. It requires either load balancing multiple app-instances or an app that uses helper processes. For me, this is the simpler solution. Once set up it is fairly trivial to multiply out an app’s capacity to take advantage of processors. This does not accelerate the app for any single user, but can make a substantial difference across multiple users.

In the previous post I covered a nice, easy way to handle startup and shutdown of multiple instances of an app across different server ports. Be sure to check that out as well.

Feel free to leave a comment here or on the Xojo Forum.


What do you think?