---
name: azion-enforce-hls-cache-for-live-streaming
description: >-
  Give the segments and the playlist of an HLS stream their own cache settings and rules, from Azion Console or the Azion API.
---

# Enforce HLS cache for live streaming

An HLS stream is delivered as two kinds of file, and they do not want the same cache. You give each one a cache setting of its own and apply it with a [Rules Engine](/en/documentation/platform/applications/rules-engine/) rule that matches the file extension, from Azion Console or the Azion API v4.

A segment file is written once and never changes, so it takes the longer cache TTL. The playlist is rewritten as the stream advances, so it takes a TTL of a few seconds. The playlist TTL this guide uses is below 60 seconds, which requires [Application Accelerator](/en/documentation/platform/applications/#application-accelerator) on the application.

---

## Prerequisites

- An application that delivers the playlist and the segments of your stream. To create one, refer to [Applications quickstart](/en/documentation/platform/applications/quickstart/).
- A domain on the workload that serves the application. For more information, refer to [Workloads](/en/documentation/platform/workloads/).
- Application Accelerator turned on for the application. For the steps, refer to [Configure cache policies for an application](/en/documentation/guides/application-performance/cache-and-purge/cache-settings/), whose first task turns the module on.
- Access to Azion Console, for the Console procedures. Refer to [Access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).
- A [personal token](/en/documentation/guides/platform/account-and-billing/personal-tokens/), for the API procedures.

Video files stored in [Object Storage](/en/documentation/platform/object-storage/) can serve as the origin of the stream: upload the video files, then point the encoder that produces the HLS output at the bucket.

---

## Create the cache setting for the segments

The segments keep a cache TTL of 60 seconds and a browser TTL of 0 seconds. To create the setting:

1. **Open the application**

   Access [Azion Console](https://console.azion.com/) > **Applications**, then select the application that delivers the stream.

2. **Go to the Cache Settings tab**

3. **Select + Cache**

4. **Name the cache setting**

   In **Name**, enter `hls-segments`.

5. **Set the browser cache**

   Under **Browser Cache**, select *Override cache settings* and set the TTL to `0`.

6. **Set Max Age**

   Under **Cache**, keep *Override cache behavior* selected and in **Max Age** enter `60`.

7. **Turn on Tiered Cache**

   The toggle is in the same section. It adds a second cache layer between Azion's cache and your origin.

8. **Select Save**

The setting appears in the **Cache Settings** list.

---

## Create the cache setting for the playlist

The playlist keeps a cache TTL of 5 seconds, so a client reading it receives the segments the encoder has already written. To create the setting:

1. **Select + Cache**

2. **Name the cache setting**

   In **Name**, enter `hls-playlist`.

3. **Set the browser cache**

   Under **Browser Cache**, select *Override cache settings* and set the TTL to `0`.

4. **Set Max Age**

   Under **Cache**, keep *Override cache behavior* selected and in **Max Age** enter `5`.

5. **Turn on Tiered Cache**

6. **Select Save**

Both settings now appear in the list, and neither applies to a request yet.

> **Note**
>
> A **Max Age** below 60 seconds requires Application Accelerator on the application. Without the module, the API rejects the setting with error `21021`. For the floor, refer to [Applications limits](/en/documentation/platform/applications/limits/#cache).

---

## Apply the settings with rules

Each setting needs a rule that matches its file extension. To create the rule for the segments:

1. **Go to the Rules Engine tab**

2. **Select + Rule**

3. **Name the rule**

   Enter `cache-hls-segments`.

4. **Select Request Phase**

5. **Set the criteria**

   Under **Criteria**, select `${uri}`, the *matches* operator, and enter `.*.ts` as the argument.

6. **Add the Set Cache Policy behavior**

   Under **Behaviors**, select **Set Cache Policy**, then select `hls-segments`.

7. **Select Save**

Repeat the procedure for the playlist: name the rule `cache-hls-playlist`, enter `.*.m3u8` as the criteria argument, and select `hls-playlist` as the cache policy.

Both rules now appear in the list, and each applies its setting to the files its pattern matches.

> **Note**
>
> A new rule can take a few minutes to propagate.

---

## Configure through the API

The same two settings and two rules are created with four requests. To create the cache settings:

1. **Create the segments setting**

   ```bash
   curl --location --request POST 'https://api.azion.com/v4/workspace/applications/{application_id}/cache_settings' \
   --header 'Accept: application/json' \
   --header 'Content-Type: application/json' \
   --header 'Authorization: Token [TOKEN VALUE]' \
   --data '{
     "name": "hls-segments",
     "browser_cache": { "behavior": "override", "max_age": 0 },
     "modules": {
       "cache": {
         "behavior": "override",
         "max_age": 60,
         "tiered_cache": { "enabled": true, "topology": "nearest-region" }
       }
     }
   }'
   ```

2. **Read the id in the response**

   The API answers with HTTP `201` and the new setting under `data`:

   ```json
   {"state":"executed","data":{"id":123456,"name":"hls-segments","browser_cache":{"behavior":"override","max_age":0},"modules":{"cache":{"behavior":"override","max_age":60,"tiered_cache":{"topology":"nearest-region","enabled":true}}}}}
   ```

3. **Create the playlist setting**

   Send the same request with `"name": "hls-playlist"` and `"max_age": 5` under `modules.cache`. The response carries its own `id`.

To apply each setting with a rule:

1. **Create the rule for the segments**

   Replace `[CACHE SETTING ID]` with the `id` of the `hls-segments` setting:

   ```bash
   curl --location --request POST 'https://api.azion.com/v4/workspace/applications/{application_id}/request_rules' \
   --header 'Accept: application/json' \
   --header 'Content-Type: application/json' \
   --header 'Authorization: Token [TOKEN VALUE]' \
   --data '{
     "name": "cache-hls-segments",
     "criteria": [[{ "variable": "${uri}", "operator": "matches", "conditional": "if", "argument": ".*.ts" }]],
     "behaviors": [{ "type": "set_cache_policy", "attributes": { "value": "[CACHE SETTING ID]" } }]
   }'
   ```

2. **Read the response**

   The API answers with HTTP `202` and the rule with `state` set to `pending`:

   ```json
   {"state":"pending","data":{"id":123457,"name":"cache-hls-segments","active":true,"order":0}}
   ```

3. **Create the rule for the playlist**

   Send the same request with `"name": "cache-hls-playlist"`, the argument `.*.m3u8`, and the `id` of the `hls-playlist` setting.

The stream is now cached by kind of file: each segment for 60 seconds, the playlist for 5 seconds.

---

## Next steps

- [Cache settings](/en/documentation/platform/applications/cache/cache-settings.md): Every field of a cache setting, with its type, its default, and its bounds.
- [Expiration and freshness](/en/documentation/platform/applications/cache/expiration-and-freshness.md): What the TTL does to a request, and what the second cache layer changes.
- [Purge cached content](/en/documentation/guides/application-performance/cache-and-purge/purge-cached-content.md): Remove a segment or a playlist from the cache before its TTL ends.
- [Check the cache status of a response](/en/documentation/guides/application-performance/cache-and-purge/check-page-cache-time.md): Confirm that a segment request is answered from the cache.
