on Software

WMS Seeding

15 Aug 2015

For a good user experience, performance is one of the implicit requirements. It is never an issue, as long as everything is fast. Well, you may have had the conversion about this particular WMS service, that we all use, being not perfectly sufficient in term of responselyness.

The options to make things faster are numerous: more licenses, less visible geometry, faster hardware, removing custom draws, to name a few. And then there is caching. Caching is often one of the first actions taken because it does not seem to be expensive at first, and does not require big changes to the architecture.


Caching is often applied lightheartedly and sometimes inadvertently, even though we all know since our lecture of TAOCP that premature optimization is the root of all evil. When it comes to a WMS it introduces the problem of when to do cache invalidation. And cached tiles need disk space too.

Nonetheless, having a good WMS cache is pretty much all you can do when you do not have good control of a slow backend WMS. It is also a good choice when content does not change much, and likewise when you pay for bandwith or for requests or when company policy does not allow using an external WMS - there are, you see, many reasons for using a WMS cache.


I made good experience with GeoWebCache as it is deployed in many environments. It is Java based, LGPL, super configurable and controllable from scripts through a REST interface. It runs in Jetty and has a web administration interface.

For the purpose of showing my seeder, below, in action I configured GWC with a backend from CartoCiudad. The layer configuration looks like that:

  <!-- -->

That’s a WMS Layer to look at. Please notice that I did not put in cache expiry rules, so tiles never expire, and I configure GeoWebCache to tell Browsers never to cache tiles, as this would be yet another cache. They are everywhere.

Now lets go for the seeding part.

GWC Seeder

The Skeleton for my GeoWebCache Seeder is on GitHub. The readme has all you need to get started. It is written in JavaScript to run on node.js. I went for that solution because node.js is installed with our architecture stack anyways, doing HTTP requests from JavaScript is easy and everybody can program JavaScript. With configuration in JSON the config file parser is already implemented too.

In contrast to the administration interface