FormaTeX

\begin{article}

draft — not published

LaTeX Compilation Timeouts in CI/CD: Causes, Fixes, and Plan Selection

LaTeX can take minutes to compile complex documents. Here is why, how to diagnose slow compilations, and how to configure timeouts correctly in your CI pipeline.

·6 min read·
LaTeX Compilation Timeouts in CI/CD: Causes, Fixes, and Plan Selection

Nothing breaks a CI pipeline quite like a LaTeX job that runs for five minutes and then times out. Unlike most compilation steps that finish in seconds, LaTeX can legitimately take several minutes for complex documents — and the reasons are often surprising. This guide covers the causes, the fixes, and how to configure your pipeline accordingly.

Why LaTeX Is Slow

LaTeX is not a single-pass compiler. Complex documents require multiple passes, each of which reads the entire source file.

Multi-Pass Compilation

A document with cross-references, a table of contents, and a bibliography typically requires:

  1. Pass 1: Compile document, write .aux file with label positions
  2. Pass 2: Compile again, read .aux to resolve \ref{} and \pageref{}
  3. Run BibTeX/Biber: Generate bibliography from .bib file and .aux
  4. Pass 3: Compile again to incorporate bibliography
  5. Pass 4: Compile one more time to resolve bibliography references in text

That is four full passes through your entire document. A 100-page document with heavy math and bibliography can take 60–120 seconds even on fast hardware.

Font Loading

XeLaTeX and LuaLaTeX load OpenType fonts on startup. For documents with multiple custom fonts, this loading phase can add 10–30 seconds before the first page is rendered.

Package Initialization

Some packages do significant work on first use — tikz with complex diagrams, pgfplots with large datasets, and listings with syntax-highlighted code blocks all add compilation time.

The microtype Penalty

\usepackage{microtype} is excellent for output quality but adds 20–40% to pdflatex compilation time. For large documents on a free plan with a 30-second timeout, this can be the difference between success and timeout.

For CI pipelines where speed matters more than perfect typography, omit microtype or use \usepackage[draft]{microtype} to disable its processing without changing your source.

Common CI Timeout Causes

CauseSymptomSolution
Bibliography not resolved[?] in output, multiple biber runsUse latexmk engine
Cross-references not resolved?? in outputUse latexmk engine
Complex tikz diagramsSlow on every compileExternalize with tikz externalize
Large embedded imagesSlow image encodingPre-compress images to PDF or PNG
microtype on large docsConsistently slow pdflatexUse draft mode in CI
Font loading (XeLaTeX)Slow startupCache font database with fc-cache

Diagnosing Slow Compilations

Add timing to your LaTeX jobs:

bash
time curl -X POST https://api.formatex.io/api/v1/compile \
  -H "X-API-Key: $FORMATEX_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"content\": $(cat document.tex | jq -Rs .), \"engine\": \"pdflatex\"}" \
  --output document.pdf

# real    0m47.312s  ← this tells you actual API round-trip time

If compilation consistently exceeds 30 seconds on pdflatex, you need either:

  • A plan upgrade for a longer timeout, or
  • Document optimizations to reduce compilation time

Fixes for Self-Hosted Setups

If you are running pdflatex locally or on your own server, these fixes reduce compilation time. Keep in mind that self-hosting LaTeX vs. using a compilation API involves significant infrastructure overhead beyond just timeouts.

Use latexmk for Multi-Pass Documents

latexmk detects when re-runs are needed and stops as soon as the document is stable:

bash
latexmk -pdf -interaction=nonstopmode document.tex

Externalize TikZ Diagrams

latex
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize[prefix=tikz/]

TikZ diagrams are compiled once and cached. On subsequent runs, cached diagrams are reused.

Draft Mode for Development

latex
\documentclass[draft]{article}

Draft mode skips image rendering and some expensive operations. Use it during development, disable for final output.

FormaTeX Timeout Tiers

FormaTeX enforces plan-specific timeouts. Choosing the right LaTeX compilation engine also affects how long each pass takes:

PlanTimeoutBest for
Free30sSimple documents, short reports
Pro120sStandard documents with bibliography
Max300sLong-form, complex documents
Enterprise300sHigh-volume, complex documents

Choose your plan based on your typical document complexity.

Error Handling for Timeouts

When a compilation exceeds the timeout, the API returns:

json
{
  "error": "compilation timeout",
  "engine": "pdflatex",
  "timeout_ms": 30000
}

Handle this in your pipeline. For a full reference of all status codes your pipeline may encounter, see the LaTeX API error codes guide:

typescript
const response = await fetch("https://api.formatex.io/api/v1/compile", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.FORMATEX_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ content: latex, engine: "pdflatex" }),
});

if (!response.ok) {
  const error = await response.json();

  if (error.error === "compilation timeout") {
    // Retry with latexmk or upgrade your plan
    console.error(`Timeout after ${error.timeout_ms}ms. Consider upgrading your plan.`);
  } else {
    // Compilation error — check the log
    console.error("LaTeX error:", error.log);
  }

  throw new Error(error.error);
}

In shell-based pipelines, check the HTTP status code. Pairing this with API rate limiting and retry logic ensures your pipeline handles transient failures gracefully:

bash
HTTP_STATUS=$(curl -s -o response.bin -w "%{http_code}" \
  -X POST https://api.formatex.io/api/v1/compile \
  -H "X-API-Key: $FORMATEX_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"content\": $(cat document.tex | jq -Rs .), \"engine\": \"pdflatex\"}")

case "$HTTP_STATUS" in
  200) mv response.bin document.pdf && echo "Success" ;;
  408) echo "Compilation timeout — consider upgrading plan" && exit 1 ;;
  400) echo "LaTeX error:" && cat response.bin | jq -r '.log' && exit 1 ;;
  *) echo "API error: HTTP $HTTP_STATUS" && exit 1 ;;
esac

The Pro plan's 120-second timeout covers virtually all real-world documents including those with bibliography, TikZ diagrams, and complex math. Only extremely long theses and books typically require the Max plan's 300-second timeout.

Get Started

\end{article}

Back to blog

\related{posts}

One quick thing

We track anonymous usage — page views, feature usage, compilation events — to understand what works and what doesn't. No ads, no personal data, no third-party sharing.

Cookie policy