Does the memory usage of the Racket web server balloon if you don’t use continuations?

Racket allows you to build web applications using continuations. The web-server language encourages that. Continuations are a powerful feature, but they can be confusing and awkward to work with. From a web server performance standpoint, they are also a bit suspicious because they require memory. They are storing, after all, unfinished computations. But we want our servers to be nimble and crud-free!

If you do use continuations, your web server will almost certainly require memory to store them. And if you make a lot of requests for resources that use continuations, the memory footprint will grow and grow. Thankfully, there’s code that handles this situation. When faced with memory pressure, continuations will be killed and their memory reclaimed.

But what if you don’t explicitly use continuations?

If you build a web server with Racket, it’s not unreasonable to wonder whether continuations are, nonetheless, still being stored somewhere in the Racket process. If that were so, it could present a kind of memory leak: your Racket web server process’ memory footprint would grow and grow, and you’d be powerless to do anything about it.

The answer, thankfully, is that unless you explicitly use continuations, they aren’t being used behind your back. (And, to be clear, you don’t need to use continuations.) You can leverage the power of Racket to build web apps using a traditional request-response style.) You can go forward in confidence with your Racket web programming knowing that your web server’s memory footprint won’t balloon on you without your knowledge.

If you know that your Racket web server code does not use any continuations, you can slightly improve the memory performance of your application by using the none-manager. Using the #:manager keyword argument in the servlet/serve function, you can influence the way continuations get managed. Here, for instance, is how I invoke some of my servlets:

1
2
3
4

;; define a dispatcher, then:

(serve/servlet dispatcher #:manager (create-none-manager #f))

(If your code does use continuations, don’t use the none-manager!)