A Serverless text-to-speech player for jokes and quotes

Using AWS components, Cloudflare, and public APIs.

James Montgomery

2 minute read


I decided to dust off my text-to-speech list, implementing a serverless solution delivering random jokes and quotes. You may visit it at this address:


You can get a preview of the joke quality here:

Note: I can’t affect the humour quality 🤣.

Solution overview

Upon visiting the page, an event triggers calls to the API routes for their relative jokes and quotes. Contained in the API response is the source audio for the HTML5 audio controls.

An overview of AWS component use from my front-end.

The audio can be refreshed via page reload or pressing the update button.

Solution detail

I elected for an AWS solution, proxied via Cloudflare. Here is a logical diagram of the API solution used via fetch:

An overview of how my AWS gateway, lambda, and other components interact.

The Cloudflare component provides:

  • Rate limiting for my API; and
  • Edge caching for static JSON responses;

The motivation for rate-limiting was one of cost/resource control. Cloudflare offers rate-limiting to all plan types, including the free plan as a billable addition.

Similarly, the edge caching option allows me to serve static JSON responses without always required a function invocation. Benefits include:

  • Lower latency to response times; and
  • Fewer concurrent Lambda invocations when a cache hit occurs.

Edge caching is available via the page rules functionality and is available in the free plan. I have tested this, and it works as described. However, I need to change my implementation to take advantage of it. If I use it with the existing API, then the response is cached for 2 hours.

It was Troy Hunt’s post on Cloudflare and HIBP which first seeded this for consideration. Please do read his blog post; it’s all kinds of awesome.


I originally began this as a part of re-working my local Elite Dangerous projects (TTS player, timeline) to a serverless solution. Before doing so, I elected to work on the core concepts with similar requirements but a more straightforward problem to solve. And to laugh at some terrible jokes 😀.

What I’ve deployed works but it contains synchronous inter-service communication at the backend. It’s on the list to remove and improve. If you’d like to read about the options in this space, I recommend this blog post from Paul Swail.