reliability guide
How to Make Large Markdown-to-PDF Exports Reliable
Learn how failure isolation, page-aware layout, renderer state isolation, timeouts, and stress testing keep long technical PDFs from failing.
Convert Markdown to PDFLarge Markdown-to-PDF exports become reliable when the renderer isolates block-level failures, resets document state, waits for asynchronous assets, applies page-aware layout rules, validates the final PDF, and is tested with adversarial multi-page fixtures.
A 150-page document should not fail because one equation has a typo or one image URL is unavailable.
For the complete architecture, read the Markdown-to-PDF guide.
Why do long Markdown exports fail more often?
Every additional block increases the chance of encountering:
- malformed Markdown;
- invalid TeX;
- unsupported math commands;
- a broken Mermaid diagram;
- an unreachable image;
- missing font glyphs;
- a table wider than the page;
- a code block taller than a page;
- state leakage from a previous job;
- a browser timeout;
- an invalid final artifact.
A renderer that succeeds on five examples may still fail on a realistic document where all these features interact.
What is localized failure?
Localized failure means a recoverable error is contained at the smallest useful block.
Examples:
| Error | Local fallback | Document result |
|---|---|---|
| Malformed equation | Show source in a neutral math-error block | Continue |
| Invalid Mermaid diagram | Show message and diagram source | Continue |
| Missing image | Show placeholder and alt text | Continue |
| Unknown code language | Render plain code | Continue |
| Unbalanced fence | Preserve local source where possible | Continue |
Job-level failure should be reserved for conditions such as unreadable input, browser crash, hard timeout, invalid final PDF, storage failure, or exceeded hard limits.
Why does parser recovery matter?
A malformed code fence or delimiter can cause a naïve parser to consume the rest of the document as one block.
Recovery rules should prefer local preservation over aggressive guessing.
SolConverter currently:
- keeps malformed fence or delimiter content local where possible;
- removes an extra closing brace only under a narrow balanced-expression rule;
- does not invent a missing closing brace;
- preserves source fallback for malformed math.
These rules protect content while avoiding silent semantic changes.
How should renderer state be isolated?
Persistent browser reuse improves performance, but it creates a state-leak risk.
Reset between documents:
- MathJax macros;
- equation labels and counters;
- Mermaid configuration;
- DOM and global variables;
- local/session storage;
- fonts or style overrides;
- request handlers;
- timeouts and cancellation state.
SolConverter’s internal stress tests repeat the same fixture and check that labels and macros do not leak between documents.
Why do fonts and images need explicit waiting?
A browser can report that HTML is loaded before:
- a web font is ready;
- an image has decoded;
- Mermaid has generated SVG;
- MathJax has finished typesetting.
Printing too early creates intermittent failures that are difficult to reproduce.
A reliable worker waits for explicit readiness signals and has a deadline for resources that never complete.
Which pagination controls help long documents?
Browser print layout can be improved with rules that:
- keep headings with following content where possible;
- apply orphan and widow control to text;
- avoid splitting table rows;
- repeat table headers;
- keep figures and captions together;
- avoid splitting code blocks, images, diagrams, and display math when they fit;
- constrain oversized SVG and images;
- support landscape orientation for wide content.
These are best-effort rules. A block taller than one page cannot always remain unbroken.
How should a long equation be handled?
Do not only shrink it.
A better process is:
- parse the equation structure;
- find top-level additive operators;
- split into readable lines;
- keep nested groups intact;
- render vector output;
- check page width.
SolConverter’s current fixture includes an 84-term additive expression that wraps without clipping or losing terms.
Read the dedicated guide: How to convert Markdown with LaTeX equations.
What should a stress-test fixture include?
A strong fixture combines features instead of testing them only in isolation.
Markdown structure
- headings at several levels;
- nested lists and task lists;
- blockquotes;
- GFM tables;
- safe raw HTML tables;
- fenced code;
- malformed fences;
- front matter.
Math
- hundreds of inline and display equations;
- matrices and arrays;
- AMS environments;
- macros;
- labels;
- chemistry;
- MathML;
- an intentionally malformed equation;
- a very long equation.
Diagrams
- multiple Mermaid families;
- ZenUML;
- one invalid diagram before a valid diagram;
- wide SVG.
Languages
- Vietnamese;
- CJK;
- Arabic and Hebrew;
- mixed RTL/LTR;
- emoji;
- combining marks.
Assets
- public images;
- data images;
- broken images;
- blocked local/private targets;
- large images;
- captions.
PDF options
- A4, A3, and Letter;
- portrait and landscape;
- narrow and wide margins;
- page numbers on and off;
- long tables and code blocks.
Current SolConverter stress-test evidence
A SolConverter stress test run on 2026-08-04 used:
- a synthetic fixture containing 92 super-pages;
- a latest checked PDF of 156 pages;
- 333 MathJax expressions in one document;
- repeated runs without macro or label leakage;
- two deliberately malformed MathML blocks isolated at their locations;
- an 84-term expression wrapped across lines;
- 21 renderer unit tests passing;
- 16 API tests passing;
- a generated PDF passing
qpdf --check.
These are valuable product proof points, but they are not a comparative industry benchmark. Publish the test input, environment, renderer version, and date so readers can evaluate the evidence.
How should output be validated?
Use several levels.
Per job
%PDF-signature;- file-size bounds;
- expected page-generation result;
- no HTML error page;
- storage success.
Automated test suite
- PDF parser opens the file;
- text or markers expected after malformed blocks are present;
- page count is plausible;
- no cross-document state leakage;
- diagram and equation fallbacks are present when expected.
Release or nightly validation
qpdf --checkor equivalent syntax validation;- visual regression screenshots;
- fixture comparison;
- memory and browser-process monitoring;
- repeated sequential and concurrent runs.
How should timeouts work?
Use a hard job deadline and, where useful, stage-specific deadlines.
A timeout should:
- mark the current step;
- cancel pending work;
- close or recycle the page/context;
- avoid leaving a poisoned worker;
- return a stable error code;
- indicate whether retry may succeed.
Do not allow one hung image or diagram to occupy a worker indefinitely.
How can browser reuse remain safe?
Reuse the expensive browser process, not uncontrolled document state.
A practical model is:
Persistent browser process
├── isolated context/page for job A
├── isolated context/page for job B
└── health checks and restart policy
Restart when:
- the browser crashes;
- memory exceeds a threshold;
- renderer source changes;
- repeated jobs fail health checks;
- the worker reaches a deliberate lifecycle limit.
Frequently asked questions
How many pages can Markdown-to-PDF support?
There is no universal page limit. The practical limit depends on source complexity, browser memory, images, diagrams, fonts, timeout, and output-size policy.
Should one malformed equation fail the PDF?
Usually not. A document service can preserve the source and continue while reporting the local error.
Can browsers repeat table headers across pages?
They can when table headers and print CSS are structured correctly, but behavior should be tested in the target browser version.
Is passing qpdf --check enough?
No. It verifies PDF structure, not visual fidelity or content completeness.
Should every block avoid page breaks?
No. Use best-effort avoidance for blocks that fit. Oversized blocks require splitting, scaling, or a different layout.
Next step
Publish the stress fixture as a reproducible artifact. It will support technical claims more effectively than generic statements about reliability.
Try the Markdown-to-PDF tool, review math handling, or learn how the backend API manages jobs.