Skip to main content
Version: Stable 3.x


This document explains the design details and goals for the architecture of LibreTime. It describes the result of a discussion that happened on Github.

Previous architecture

The previous architecture of LibreTime (based on AirTime) was missing a proper separation of concerns. It was build around a legacy MVC app written in PHP, and services in Python to accomplish specific tasks.

New architecture

Below is the new architecture goal of LibreTime, with a proper separation of concerns.

flowchart TD users([Users]) public([Public]) subgraph create_schedule[Create the schedule] webapp[Web app] subgraph core[Backend] message_api[Message API] api[Web API] worker[Worker] end end subgraph play_schedule[Play the schedule] playout[Playout] liquidsoap[[Liquidsoap]] icecast[[Icecast]] hls[[HLS]] end message_queue[[Message Queue]] database[[Database]] storage[[Storage]] users --> |Edit| webapp webapp --> api api --> database api --> storage api --> message_queue message_queue <--> worker worker --> database worker --> storage message_queue <--> message_api message_api --> database message_queue <--> playout playout <-. via message queue .-> message_api playout --> |e.g. download file| api playout <--> liquidsoap liquidsoap --> icecast liquidsoap --> hls public --> webapp public --> |Listen| icecast public --> |Listen| hls

The LibreTime architecture is split into 2 main monolithic blocks Create the schedule and Play the schedule. Both blocks must be able to scale horizontally.


A microservice architecture was rejected as it won't fix or improve any aspect of LibreTime.


This document tries to focus on creating and playing a schedule, it doesn't consider features such as monitoring, logging or archiving.

Create the schedule

This block contains the following components:

  • a web API,
  • a worker to run background tasks,
  • a message API to communicate with the Play the schedule block, and other services,
  • a web app to interface with the users.

The web API, the worker and the message API rely on the Django framework to handle database, message queue and storage access.

Play the schedule

Since the Play the schedule has its own requirements in terms of logic and uptime, it's handled separately from the Create the schedule block. This block needs to be able to be duplicated in a high availability context.

This block contains the following components:

  • a Playout app that communicates with the Play the schedule block to gather the schedule,
  • a Liquisoap app that plays and mixes the scheduled items, and dispatch them to the delivery services,
  • an Icecast server that delivers a legacy audio stream to the public,
  • a HLS stream that delivers a modern audio stream to the public.

One setup per radio station

LibreTime isn't meant to be used in a multi-tenant architecture, and an entire LibreTime installation should be dedicated to a single radio station. Previous SAAS or multi-tenant features from Airtime should be deprecated or removed.

Separation of concerns

The Create the schedule block must only prepare a schedule, and the Play the schedule must only play that schedule. A strong separation of concerns is required between the 2 blocks to allow the Play the schedule block to meet its uptime requirements while not depending on the Create the schedule in case of a failure. Development will be simplified if both blocks share a single and properly defined protocol.