TeX auxiliary file corruption during concurrent compilation
0 reputation · 26 Feb 2026, 10:07 UTC
0 reputation · 26 Feb 2026, 10:07 UTC
The TeX engine operates as a single-threaded process. When multiple independent instances are launched to compile the same document simultaneously, they compete for access to shared auxiliary files, such as .aux&code, .toc&code, and .out&code.
Because the TeX core lacks native file-locking mechanisms, simultaneous write operations can lead to race conditions. Depending on the interaction mode—such as nonstopmode&code or batchmode&code;—these collisions may result in corrupted output or silent failures without a standardized atomic update mechanism to ensure data integrity.
The TeX engine does not prioritize file access through a queuing or locking system; it relies on the underlying operating system's file handling. Because TeX lacks native file-locking mechanisms, it does not synchronize access when multiple processes attempt to write to the same auxiliary file (such as .aux, .toc, or .out). Consequently, there is no documented method within the engine core to implement atomic updates for these files.
When two or more TeX processes execute simultaneously on the same document, they enter a race condition. Since the engine typically overwrites or appends to auxiliary files without checking for external locks, the resulting file often contains interleaved data or truncated commands. This corruption usually manifests in subsequent runs as Undefined control sequence or Missing item errors, as the engine can no longer parse the malformed auxiliary data.
To prevent corruption during parallel execution, you must isolate the working environment for each process. The most reliable method is to assign a unique output directory to every concurrent build instance.
build_1/, build_2/).-output-directory flag to ensure auxiliary files are written to these isolated paths.# Example for Process A
pdflatex -output-directory=build_a main.tex
# Example for Process B
pdflatex -output-directory=build_b main.tex
To verify that isolation is working, check the contents of the specified output directories. Each should contain its own independent set of .aux and .log files. If you see these files appearing in the root source directory during a parallel run, the isolation is failing.
Diagnostic Detail Required: Are you using a build automation tool (like latexmk) or a custom CI/CD script to launch these processes? This determines if the output directory needs to be managed via a configuration file or a shell environment variable.
Use comments to ask for clarification. Post a solution as an answer.
31,275 reputation · 26 Feb 2026, 13:04 UTC
One point worth adding: if you can't give each process its own -output-directory (for example, a shared build script expects auxiliaries in the source tree), you can serialize access externally, since the engine itself never will. On Unix-like systems a simple advisory lock around the invocation works:
flock /tmp/main.tex.lock pdflatex -interaction=nonstopmode main.tex
Build tools already do this implicitly: latexmk serializes all passes for a given document, which is why corruption typically only appears with hand-rolled parallel scripts or CI jobs sharing a working directory.
Also note the failure mode is often silent. Under nonstopmode or batchmode, a truncated .aux read on the next pass usually surfaces only as LaTeX Warning: There were undefined references or stale TOC/page numbers — the run completes and the PDF looks fine. Before adding locking, confirm concurrency is the actual cause: undefined-reference warnings also appear when you simply haven't run enough passes. A quick check is to diff the .aux from a suspected collision against a single-run baseline.