When wkhtmltopdf hangs indefinitely or times out during PDF generation, developers lose hours debugging a process that never completes. The tool offers no built-in timeout mechanism, and when it freezes at "Loading Pages 90%," the only option is to kill the process manually. This article documents the most common causes of wkhtmltopdf timeouts and hangs, examines evidence from the developer community, and presents a migration path to avoid these issues entirely.
The Problem
wkhtmltopdf is a command-line tool that converts HTML to PDF using Qt WebKit. While it served developers well for many years, it has a fundamental architectural problem: the process can hang indefinitely with no way to set a global timeout. When remote resources fail to load, when JavaScript enters an infinite loop, or when the document is simply too large, wkhtmltopdf provides no mechanism to abort gracefully.
The project was archived on January 2, 2023, meaning these issues will never receive official fixes. The repository is now read-only, and the wkhtmltopdf organization was marked as archived on July 10, 2024.
Common Error Patterns
Developers report these symptoms when wkhtmltopdf hangs:
Loading pages (1/6) [> ] 0%
Loading pages (1/6) [======> ] 10%
[Process hangs indefinitely at this point]
Or the process runs for extended periods consuming resources:
wkhtmltopdf process running for 28 minutes eating 99% CPU
Server effectively killed by runaway PDF generation
When using PHP frameworks like Symfony or Laravel with wkhtmltopdf wrappers:
ProcessTimedOutException: The process exceeded the timeout of 60 seconds.
Who Is Affected
This issue affects developers using wkhtmltopdf in these scenarios:
- Server-side PDF generation in web applications (PHP, Python, Ruby, .NET)
- Linux deployments, particularly in Docker containers
- Large document generation (40+ pages)
- Documents with remote resources (images, fonts, stylesheets from external URLs)
- High-volume batch processing where reliability is critical
- Applications using wkhtmltopdf wrappers (DinkToPdf, Rotativa, laravel-snappy, wicked_pdf, pdfkit)
The hanging behavior is intermittent, making it particularly frustrating to debug. Reports indicate it occurs in approximately 1 out of 10 runs for large documents.
Evidence from the Developer Community
Timeline
| Date | Event | Source |
|---|---|---|
| 2014-03-27 | Error running wkhtmltopdf when generating PDF reports | Axway Support |
| 2015-11-15 | Request for timeout parameter implementation | GitHub Issue #2671 |
| 2016-06-15 | wkhtmltopdf intermittently hanging reported | GitHub Issue #2113 |
| 2016-09-02 | Hang at 90% reported | GitHub Issue #3191 |
| 2016-09-14 | wkhtmltopdf hangs on network errors | GitHub Issue #2254 |
| 2017-08-17 | Hangs on 10% and does not generate PDF | GitHub Issue #2628 |
| 2018-02-22 | Freeze when converting HTML to PDF | GitHub Issue #4013 |
| 2019-01-11 | Timeout expired to exiting call to wkhtmltopdf.exe | Laserfiche Answers |
| 2019-01-17 | Electron/wkhtmltopdf Timeout | jsreport forum |
| 2021-06-07 | exceeded the timeout of n seconds | GitHub Issue #5019 |
| 2021-11-04 | wkhtmltopdf hangs on long-running webpage (anything over 5min 40sec) | GitHub Issue #5177 |
| 2023-01-02 | wkhtmltopdf repository archived | GitHub |
Community Reports
"About 1 of every 10 runs the process hangs while 'Loading Pages' around 88-90%. This could only be reproduced when generating large PDFs. When generating 10-20 page PDFs, the hanging never happened. When generating 40+ page PDFs it happened about 1 out of 10 runs."
— Developer, GitHub Issue #2113"We have found wkhtmltopdf running for extended periods (28 minutes) eating 99% of CPU and effectively killing the server. It would be great to have a timeout set so that if the process can't create a PDF within X seconds (e.g., 30 seconds) it dies."
— Developer, GitHub Issue #2671"When calling a webpage that takes longer than 340 seconds, wkhtmltopdf hangs indefinitely. It works fine for anything 340s or less but some timeout causes it to fail at 350 seconds+."
— Developer, GitHub Issue #5177"Sometimes wkhtmltopdf hangs on network errors - the process freezes after socket operations are in progress."
— Developer, GitHub Issue #2254"The default timeout setting to generate a PDF from HTML is 1 minute. When the form is long or IIS is slow, it is possible to hit this timeout."
— Laserfiche documentation
Root Cause Analysis
1. No Built-in Timeout Mechanism
The most fundamental issue is that wkhtmltopdf has no global timeout parameter. A feature request was opened in 2015 (Issue #2671) but was never implemented before the project was archived.
# There is no --timeout flag
wkhtmltopdf --timeout 30 input.html output.pdf # Does not exist
Developers must implement external timeout mechanisms using operating system tools:
# Linux workaround using timeout command
timeout 30s wkhtmltopdf input.html output.pdf
2. Remote Resource Loading Hangs
When wkhtmltopdf fetches remote resources (images, fonts, CSS, JavaScript), network issues cause indefinite hangs. The tool waits forever for resources that may never load.
<!-- Remote resources that can cause hangs -->
<link rel="stylesheet" href="https://external-cdn.com/styles.css">
<img src="https://slow-server.com/image.jpg">
<script src="https://analytics.example.com/tracker.js"></script>
The --load-error-handling ignore flag is supposed to help, but developers report it does not prevent hangs in all cases:
# Often ineffective for timeout issues
wkhtmltopdf --load-error-handling ignore --load-media-error-handling ignore input.html output.pdf
3. No Media Loading Timeout
There is no way to control how long wkhtmltopdf waits for media resources to load. This was requested in Issue #1888 but never implemented.
# Requested feature that was never added
wkhtmltopdf --media-timeout 10 input.html output.pdf # Does not exist
4. JavaScript Execution Issues
When using the --window-status flag to wait for JavaScript to signal completion, if the page never emits the expected status, wkhtmltopdf waits forever:
# If the page never sets window.status = "ready", this hangs forever
wkhtmltopdf --window-status ready input.html output.pdf
5. PHP Session Blocking
A particularly insidious cause of hangs affects PHP applications. When passing session cookies to wkhtmltopdf, PHP's session file locking causes deadlocks:
// This can cause wkhtmltopdf to hang indefinitely
$options = ['cookie' => ['PHPSESSID' => session_id()]];
// wkhtmltopdf makes a request that needs the session
// But PHP has the session file locked
// Deadlock occurs
6. Memory Exhaustion Leading to Hangs
Large documents cause memory usage to spike dramatically. A 168-page PDF was reported to consume 8GB of memory. When memory is exhausted, the process can hang rather than fail cleanly.
# Memory usage can exceed 5GB for large documents
# 400,000 row tables cause memory to grow at ~20MB per second until exhaustion
7. File Handle Exhaustion
When generating large PDFs with headers and footers, wkhtmltopdf opens file handles for each page. Reports indicate that around page 505, the "Too many open files" error occurs, causing hangs:
# Error after ~505 pages with headers/footers
wkhtmltopdf: Error: Too many open files
Attempted Workarounds
Workaround 1: External Timeout Wrapper
Approach: Use operating system timeout commands to kill wkhtmltopdf if it exceeds a time limit.
# Linux/macOS
timeout 60s wkhtmltopdf input.html output.pdf
# Windows (PowerShell)
$process = Start-Process wkhtmltopdf -ArgumentList "input.html output.pdf" -PassThru
if (!$process.WaitForExit(60000)) {
$process.Kill()
}
Limitations:
- No graceful error handling when timeout occurs
- PDF generation simply fails without explanation
- Does not address the root cause
Workaround 2: Pre-download Remote Resources
Approach: Download all remote resources locally before calling wkhtmltopdf.
# Download resources first
wget -P ./local/ https://cdn.example.com/styles.css
wget -P ./local/ https://cdn.example.com/image.jpg
# Modify HTML to reference local files
# Then run wkhtmltopdf
Limitations:
- Significant implementation complexity
- Requires parsing and modifying HTML
- Does not help with JavaScript-generated content
Workaround 3: Close PHP Sessions Before Conversion
Approach: Release the PHP session lock before calling wkhtmltopdf.
// Release session lock before PDF generation
session_write_close();
// Now wkhtmltopdf can access the session without deadlock
$pdf = $snappy->getOutputFromHtml($html);
Limitations:
- Only addresses session-related hangs
- May not be possible if session data is needed during the request
- Does not help with other causes of hangs
Workaround 4: Use a Proxy with Timeout
Approach: Route wkhtmltopdf requests through a proxy (like Squid) that enforces timeouts.
Limitations:
- Complex infrastructure requirement
- Additional point of failure
- Earlier wkhtmltopdf versions had issues with proxies and HTTPS
Workaround 5: Increase System Limits
Approach: Adjust ulimits and kernel parameters to prevent resource exhaustion.
# Increase file descriptor limits
ulimit -n 65535
# Modify /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
Limitations:
- Does not prevent hangs, only delays them
- May cause buffer overflow issues with very large documents
- Requires system-level configuration
Workaround 6: Split Large Documents
Approach: Generate smaller PDFs and merge them afterward.
# Generate individual PDFs
wkhtmltopdf page1.html page1.pdf
wkhtmltopdf page2.html page2.pdf
# Merge with pdftk or ghostscript
pdftk page1.pdf page2.pdf cat output combined.pdf
Limitations:
- Significant implementation complexity
- May lose cross-page features (page numbers, table of contents)
- Headers and footers may not work correctly across merged documents
A Different Approach: IronPDF
For developers who need reliable PDF generation without the timeout and hanging issues that plague wkhtmltopdf, IronPDF provides an alternative architecture. Rather than wrapping an external command-line process that can hang indefinitely, IronPDF embeds a Chromium rendering engine directly into the .NET application.
Why IronPDF Does Not Have This Issue
IronPDF's architecture eliminates the fundamental causes of wkhtmltopdf hangs:
- Embedded engine: No external process to hang or timeout. The rendering happens within the .NET runtime.
- Modern networking: Chromium's network stack handles timeouts, retries, and failures gracefully.
- Configurable timeouts: Built-in timeout options for page loading and JavaScript execution.
- Async/await support: Non-blocking PDF generation that integrates with .NET's cancellation tokens.
- Active development: Issues are fixed in regular releases rather than accumulating in an archived repository.
Code Example
using IronPdf;
using System;
using System.Threading;
using System.Threading.Tasks;
public class ReliablePdfGenerator
{
public async Task<byte[]> GeneratePdfWithTimeout(string htmlContent, int timeoutSeconds = 60)
{
var renderer = new ChromePdfRenderer();
// Configure rendering timeouts
renderer.RenderingOptions.Timeout = timeoutSeconds;
// Set reasonable wait time for JavaScript execution
renderer.RenderingOptions.WaitFor.RenderDelay = 2000;
// Handle remote resources with timeout rather than hanging
renderer.RenderingOptions.WaitFor.NetworkIdle0Timeout = 10000;
// Configure page settings
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
// Use cancellation token for application-level timeout control
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds + 10));
try
{
// RenderHtmlAsPdfAsync provides async control
using var pdf = await renderer.RenderHtmlAsPdfAsync(htmlContent);
return pdf.BinaryData;
}
catch (OperationCanceledException)
{
throw new TimeoutException($"PDF generation exceeded {timeoutSeconds} seconds");
}
}
public byte[] GenerateLargeDocument(string htmlContent)
{
var renderer = new ChromePdfRenderer();
// Configure for large documents
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
// Enable headers and footers without file handle exhaustion
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
HtmlFragment = "<span style='font-size:10px'>Page {page} of {total-pages}</span>",
DrawDividerLine = true
};
// Chromium handles memory efficiently for large documents
using var pdf = renderer.RenderHtmlAsPdf(htmlContent);
return pdf.BinaryData;
}
}
Key points about this code:
- The
Timeoutproperty sets a maximum rendering time, preventing indefinite hangs -
NetworkIdle0Timeoutcontrols how long to wait for network requests to complete - Cancellation tokens provide application-level timeout control
- No external process management is required
- Headers and footers work correctly on documents of any size without file handle issues
Code Example: URL to PDF with Timeout Control
For converting web pages to PDF, where network timeouts are most problematic:
using IronPdf;
public class WebPageToPdfConverter
{
public byte[] ConvertUrlToPdf(string url, int timeoutSeconds = 30)
{
var renderer = new ChromePdfRenderer();
// Configure network timeout
renderer.RenderingOptions.Timeout = timeoutSeconds;
// Wait for network activity to settle
renderer.RenderingOptions.WaitFor.NetworkIdle0Timeout = 5000;
// Allow JavaScript execution with timeout
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.JavaScript = "document.readyState === 'complete'";
renderer.RenderingOptions.WaitFor.Timeout = 10000;
using var pdf = renderer.RenderUrlAsPdf(url);
return pdf.BinaryData;
}
}
API Reference
For more details on the methods used:
- ChromePdfRenderer - Main rendering class
- RenderingOptions - Timeout and configuration options
- HTML to PDF Tutorial - Getting started guide
- URL to PDF Tutorial - Web page conversion
Migration Considerations
Licensing
IronPDF is commercial software with per-developer licensing. A free trial allows evaluation before purchase. For teams with budget constraints, the cost must be weighed against the hours spent debugging wkhtmltopdf hangs and implementing workarounds.
API Differences
| wkhtmltopdf | IronPDF |
|---|---|
| External process execution | Embedded Chromium engine |
| No built-in timeout | Configurable timeout options |
--javascript-delay 5000 |
RenderingOptions.WaitFor.RenderDelay = 5000 |
--load-error-handling ignore |
Graceful error handling built-in |
| Hangs on network errors | Timeout and retry behavior |
| File handle exhaustion | Managed memory and resources |
What You Gain
- Reliable PDF generation without indefinite hangs
- Configurable timeout behavior at multiple levels
- Modern CSS rendering (Flexbox, Grid, CSS variables)
- JavaScript framework support (React, Vue, Angular)
- Regular security updates and bug fixes
- No external binary dependencies
What to Consider
- Commercial licensing cost
- Larger deployment size due to embedded Chromium
- Different rendering output (Chromium vs WebKit)
- Learning curve for new API patterns
Conclusion
wkhtmltopdf's timeout and hanging issues stem from fundamental architectural decisions that cannot be fixed: no global timeout mechanism, no media loading timeout, and external process execution that can hang indefinitely. With the project archived since January 2023, these issues will never receive official fixes. For production applications that require reliable PDF generation, migrating to a library with embedded rendering and configurable timeout behavior eliminates the root cause of these problems rather than patching around them with workarounds.
Jacob Mellor has spent 25+ years building developer tools, including IronPDF.
References
- How to set timeout? - Issue #2671{:rel="nofollow"} - Original timeout feature request
- wkhtmltopdf intermittently hanging - Issue #2113{:rel="nofollow"} - Intermittent hanging reports
- wkhtmltopdf hangs on network errors - Issue #2254{:rel="nofollow"} - Network-related hangs
- exceeded the timeout of n seconds - Issue #5019{:rel="nofollow"} - Timeout exceeded reports
- wkhtmltopdf hangs on long-running webpage - Issue #5177{:rel="nofollow"} - 340+ second hangs
- Hang at 90% - Issue #3191{:rel="nofollow"} - Loading percentage hang
- Hangs on 10% and does not generate PDF - Issue #2628{:rel="nofollow"} - Early loading hang
- Freeze when converting HTML to PDF - Issue #4013{:rel="nofollow"} - Conversion freeze
- add timeout for loading of media resources - Issue #1888{:rel="nofollow"} - Media timeout feature request
- It is getting stuck on Loading page 100% - Issue #3451{:rel="nofollow"} - 100% loading hang
- cpu 100% - Issue #3774{:rel="nofollow"} - High CPU usage
- High Memory Usage - Issue #2090{:rel="nofollow"} - Memory consumption
- consuming too much memory - Issue #1562{:rel="nofollow"} - Memory exhaustion
- Buffer Overflow with large PDF - Issue #2093{:rel="nofollow"} - Large document issues
- Crash with html footers and headers on huge pdfs - Issue #4296{:rel="nofollow"} - File handle exhaustion
- Timeout expired to exiting call to wkhtmltopdf.exe - Laserfiche Answers{:rel="nofollow"} - Enterprise software timeout issues
- PDF Generation exceeded the timeout of 60 seconds - KnpLabs/snappy Issue #399{:rel="nofollow"} - PHP wrapper timeout
- Stuck at Loading pages - phpwkhtmltopdf Issue #120{:rel="nofollow"} - PHP wrapper hanging
- Solve wkhtmltopdf Memory Problem - Full Guide{:rel="nofollow"} - Memory optimization guide
- wkhtmltopdf is now abandonware - Doppio Documentation{:rel="nofollow"} - Project status
For IronPDF documentation and tutorials, visit ironpdf.com.
Top comments (0)