> For the complete documentation index, see [llms.txt](https://captivatehelp.newbluelive.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://captivatehelp.newbluelive.com/design-and-customize-graphics/chapter-index-3/tune-a-graphic-for-performance.md).

# Tune a graphic for performance

A complex graphic that animates smoothly in the Designer can still struggle live. The Designer renders one frame at a time on demand; Captivate’s cache renders ahead and re-renders every time something changes. The difference matters: design choices that are invisible in the Designer can multiply the work the cache has to do every frame. This article is a checklist of the choices that most often slow a graphic down, with the alternative that ships without the cost.

Use [Optimize the timing of a graphic](/design-and-customize-graphics/chapter-index-3/optimize-timing.md) as the first step — it shortens the timeline by removing dead space and is the single biggest free improvement. The items below are the next layer.

## Run Optimize Performance for the quick wins

Captivate can find and apply the most common of these optimizations for you. In the Designer, choose **Title** > **Optimize Performance…** to open the **Optimize Performance** dialog.

The dialog lists the graphic’s layers as a tree, with a gutter on the right that groups them into the cache’s combine blocks and a ⚠ on each layer the analyzer recommends changing. For each layer you can:

* **Disable Live Update** — make a variable static when it doesn’t actually change live, so the cache can fold the layer into a combined static block.
* **Simplify Blend** — composite the layer with **Normal** instead of an expensive blend mode so it can be combined. (This changes the look — review it.)
* **Move** — reorder a layer within its group or conductor (also **Ctrl+Up** / **Ctrl+Down**) so static layers sit together and combine.

Changes preview live in the work view as you toggle them. The **Preview at:** timeline strip at the bottom scrubs the preview to any moment in the title — drag it to check a change mid-animation, or use **Pause Point** to jump to the title’s pause point and **Layer** to jump to the middle of the selected layer’s settled window. Click **OK** to apply, or **Cancel** to revert everything — the tool changes nothing until you accept.

Optimize Performance automates the three highest-impact items below: static-ifying variables that aren’t truly live, simplifying costly blend modes, and reordering for cache combining. The rest of this article explains when each change is safe, and covers the optimizations the tool doesn’t touch — pattern variables, video encoding, effect stacks, and loops.

## Mark variables as live only when they actually change live

Every variable in a graphic carries an **Update Live** flag. The flag’s real cost isn’t that values trigger re-renders — it’s that the cache’s layer-combining optimizer cannot include any **Update Live** element in the combined static composite.

Here’s why that matters. When you finish a graphic and play it on air, Captivate builds a cache for it. The cache walks every layer and groups together everything that doesn’t change at runtime into a **single combined static element** — one texture, one composite, fast to play. A static background, a static team-color rectangle, a static logo, and a static border can all become one frame.

The moment any one of those elements is marked **Update Live**, the optimizer can’t include it in the combined element. It gets:

* its own render pass during cache build,
* its own memory footprint at runtime,
* its own per-frame decompress and composite during playback.

A graphic with five **Update Live** variables that don’t actually change live is a graphic doing five times the per-frame work it needs to.

Most variables in most graphics never change while the graphic is on air. A lower-third with a fixed speaker name, a fixed subtitle, a fixed accent color, and a fixed headshot doesn’t need any of those values flagged as live — they’re set when you stage the graphic and then they hold. A scoreboard’s **Team Name** and **Team Logo** almost never change mid-game; only the score and the clock do.

Audit the **Properties > Variables** tab for each layer and turn **Update Live** OFF on every variable that isn’t genuinely live during playback. Leave it ON for the variables that genuinely change live: scores, clocks, ticker text, anything bound to a Data Controller that pushes new values during the show.

### Other things that force a layer to render alone

**Update Live** is the most common trigger, but it isn’t the only one. A layer is forced to render on its own (and skips combining) when any of these is true:

* The layer has any variable marked **Update Live**.
* The layer is set to loop, or to play through (not stop at the Pause marker).
* The layer is a Data Graph layer.
* The layer follows another layer, or is followed by another layer.
* The layer is part of a **Leaderboard** or **Grid** Conductor. (Crawls and Rolls do combine — see the section on conductors below.)

A second cost worth knowing: making one layer dynamic can make its neighbors dynamic too. A static layer that follows a dynamic layer (or is followed by one) inherits the dynamic cost — the cache can’t combine it either. When you turn **Update Live** on, you’re often touching more than the one layer.

## Use blend modes deliberately

**Normal**, **Additive**, and **Mask** (the **Stencil** blend mode in its single-layer variant) are inexpensive in playback.

Other blend modes — **Multiply**, **Screen**, **Overlay**, **Soft Light**, **Hard Light**, and the rest — render fine in the Designer. The Designer uses a single-pass GPU render, and the GPU handles these modes without breaking a sweat. The problem appears during live playback. Captivate’s playout cache composites layers on the **CPU** per frame, and the expensive blend modes are exactly the kinds of pixel math the CPU is slow at. They become costly live, especially when:

* the layer the blend touches has a dynamic variable (a live-updated text, image, or color), so the composite has to redo from scratch on each update, and
* the affected pixel area is large.

The fact that a graphic looks and performs fine in the Designer is not a guarantee it will play smoothly live. Check the result in Captivate’s Program Monitor before committing. If a graphic with one of these blend modes drops frames, see whether you can move the blend onto a static layer above or below — the cache will combine static layers and the blend cost disappears.

## Use Pattern Variables for clock and scoreboard text from data files

Text variables that update many times per second — a clock ticking from a Tables data file, a score counting from a JSON feed — re-rasterize the whole text string each update by default. For values that only change in part (one or two digits at a time), the **Pattern Variable** type does the work incrementally and is dramatically cheaper.

Set up a Pattern Variable for any clock-style or scoreboard-style text driven from a data file. The [Create variables in graphics](/design-and-customize-graphics/chapter-index-4/create-variables-in-graphics.md) article covers the setup (it’s the **Pattern Variable** row of the variable-types table).

The savings are substantial. A clock that ticks once per second through `HH:MM:SS` cycles through 86,400 distinct text values across a day. Without a pattern, the cache builds 86,400 distinct text-rendered sprites. With a 6-position pattern (`H`, `H`, `M`, `M`, `S`, `S`, each rendered for 10 possible digits), it builds about 11 reusable glyph sprites and composes them on the fly. The cache becomes tiny, the rebuild is fast, and the playback is smooth.

Dedicated Data Controllers — System Time, Sportzcast, StatCrew, hardware scoreboards — set this up automatically. You only need to do it manually for custom clock-style displays driven from generic data sources via the Tables controller.

## Pre-render video clips to project size

A 4K video file dropped into a 1080p project is decoded at 4K every frame and then scaled to 1080p. The pixel-shading cost is wasted; the disk and memory bandwidth is wasted; the decode time is wasted.

Before adding a video clip to a media sequence, re-encode it to match your project’s working resolution and frame rate. Free tools like FFmpeg and HandBrake do this cleanly; Adobe Media Encoder and DaVinci Resolve do it with a UI.

Codec choice matters too. Pick codecs designed for playback, not for editing:

* **H.264** is the safe default. It’s hardware-accelerated on virtually every modern Windows and macOS machine, the files are small, and the decode quality is fine for graphics work.
* **H.265 (HEVC)** gives smaller files than H.264 at the same quality, but only newer hardware (roughly 2017 and later) accelerates the decode. On older machines, H.265 is software-decoded and slower than H.264.

Avoid these for playback files in Captivate:

* **ProRes 4444**, **ProRes HQ**, and similar editing-intermediate codecs. They’re designed to decode and re-encode many times during a non-linear edit, not to play back efficiently. They’re software-decoded on most consumer machines.
* **GoPro CineForm**, **DNxHR HQX**, and other editing-intermediates. Same story.
* **Animation**, **MJPEG**, and **uncompressed** formats. Designed for very old workflows. Software-only decode; large files.
* **Apple ProRes RAW**, **Blackmagic RAW**, **REDCODE**, and other camera RAW formats. These are capture-side formats. Convert to H.264 before using as playout material.

When in doubt, re-encode to H.264 with a high bitrate (15-30 Mbps for 1080p; 30-60 Mbps for 4K) before adding the file to a media sequence.

One more thing to watch: pixel formats. Captivate reads video through the OS’s native decoder path — Windows Media Foundation on Windows, AVFoundation on macOS. Files in common pixel formats (NV12, YUV420, BGRA) pass straight through. Files in uncommon pixel formats trigger a software color conversion on every frame, which is a significant per-frame cost on top of the decode. If you’ve encoded a file outside the typical broadcast pipeline (e.g., 10-bit YUV422 from a camera) and it’s playing poorly, re-encode to 8-bit H.264 with a standard YUV420 pixel format.

Also worth knowing: during a stinger or other transition between two media clips, both decoders run concurrently for the length of the cross-fade. A long fade between two heavy clips doubles the decode cost briefly. Keep cross-fade durations modest when the clips themselves are taxing.

## Audit effect stacks

Each GPU effect (blur, glow, drop shadow, displacement) adds a render pass. Two or three is fine; eight or ten on the same layer compounds. If a graphic feels slow, open **Properties > Effects** on each layer and check whether any effect is redundant or could be baked into the source asset instead.

This is especially worth doing on the layers that update most often live — every effect re-runs each time the underlying content changes.

## Be deliberate about loops

A looping layer keeps the cache re-rendering even when nothing visible is changing. Loops are appropriate for genuinely-looping content (a spinning logo, a pulsing highlight) but they bypass the Optimize Timing tool and they don’t free CPU when the rest of the graphic settles.

If a loop exists because you want a layer to "stay visible" after its animation finishes, that’s not what a loop is for — extend the layer’s duration instead, or use a Pause marker.

## A practical workflow

The cheapest changes are the ones that don’t compromise the design. Apply them in this order:

1. Run [Optimize Timing](/design-and-customize-graphics/chapter-index-3/optimize-timing.md) on the finished graphic.
2. Run **Title** > **Optimize Performance** for an automated pass at the next three items, and accept the changes you agree with.
3. Audit **Update Live** flags. Turn off everything that isn’t actually changing during playback.
4. Find any non-Normal / Additive / Mask blend modes on dynamic layers. Move them, replace them, or accept the cost knowingly.
5. For text driven from data files, switch the relevant variables to **Pattern Variable**.
6. For video assets, confirm they’re encoded at project resolution and frame rate in H.264.
7. Audit effects per layer. Cut anything redundant.
8. Audit loops. Replace "keep-visible" loops with longer durations.

Test in Captivate’s Program Monitor — not just the Designer preview. The Designer renders on demand; the cache renders ahead. The two costs are different.

## Related

* [Optimize the timing of a graphic](/design-and-customize-graphics/chapter-index-3/optimize-timing.md)
* [Create variables in graphics](/design-and-customize-graphics/chapter-index-4/create-variables-in-graphics.md)
* [Loop videos and animations in a graphic](/design-and-customize-graphics/chapter-index-3/loop-videos-and-animations-in-a-graphic.md)
* [Add effects to design layers](/design-and-customize-graphics/chapter-index-3/add-effects-to-design-layers.md)
* [Troubleshooting branch](/troubleshooting/branch-index.md) for runtime playback issues.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://captivatehelp.newbluelive.com/design-and-customize-graphics/chapter-index-3/tune-a-graphic-for-performance.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
