PDFg in ColdFusion 2025
PDF generation and document services configuration guide
Last updated: October 27, 202512 min read
ColdFusion's PDF Generation (PDFg) service enables server-side PDF creation and manipulation. Configure PDFg for stability, security, and performance in production environments.
PDFg Architecture
PDFg runs as a separate service that ColdFusion communicates with via HTTP:
- The PDFg service runs independently from the main ColdFusion process
- ColdFusion sends HTML content to PDFg for rendering into PDF format
- PDFg processes the content and returns the generated PDF back to ColdFusion
- Communication happens over a configurable port (default is 8989)
Installation and Configuration
Install PDFg using cfpm:
Install and Start PDFg Service
# Install PDFg package
cfpm install pdfg --acceptEULA
# Start PDFg service
# Linux
/opt/coldfusion/cfusion/jre/bin/java -jar pdfg.jar
# Windows
C:\ColdFusion2025\cfusion\jre\bin\java -jar pdfg.jarAfter installing PDFg, you need to configure the connection settings in the ColdFusion Administrator under Server Settings > Document.
Isolation for Stability
Best Practice: Run PDFg on separate nodes from your application servers for improved stability and resource isolation.
Running PDFg on separate nodes provides several important benefits:
- PDFg crashes or failures won't affect your main application servers
- Resource-intensive PDF generation is isolated from normal application processing
- You can scale PDFg capacity independently based on document generation workload
- Troubleshooting and monitoring become easier when services are separated
Security Considerations
- Input Validation: Limit and validate untrusted HTML input
- Resource Limits: Prevent resource exhaustion attacks
- Network Access: Restrict PDFg service to internal network only
- Authentication: Configure shared secret for CF-to-PDFg communication
Secure PDF Generation
<!--- Limit HTML input from untrusted sources --->
<cfif len(userHTML) GT 100000>
<cfthrow message="HTML input too large">
</cfif>
<!--- Sanitize or validate HTML --->
<cfset cleanHTML = htmlEditFormat(userHTML)>
<!--- Generate PDF with timeout --->
<cfdocument format="pdf" timeout="30">
<cfoutput>#cleanHTML#</cfoutput>
</cfdocument>// Limit HTML input from untrusted sources
if (len(userHTML) > 100000) {
throw(message="HTML input too large");
}
// Sanitize or validate HTML
cleanHTML = htmlEditFormat(userHTML);
// Generate PDF with timeout
cfdocument(format="pdf", timeout="30") {
writeOutput(cleanHTML);
}Performance Optimization
- Cache generated PDFs when the source content doesn't change frequently
- Use asynchronous generation for large documents to avoid blocking requests
- Optimize your HTML and CSS for faster rendering performance
- Avoid loading external resources like images and fonts when possible to reduce dependencies
- Configure an appropriate heap size for the PDFg JVM based on your workload
Cache PDF Output
<!--- Cache PDF for 1 hour --->
<cfset pdfCacheKey = "invoice_#invoiceID#">
<cfset cachedPDF = cacheGet(pdfCacheKey)>
<cfif isNull(cachedPDF)>
<cfdocument format="pdf" name="cachedPDF">
<!--- Document content --->
</cfdocument>
<cfset cachePut(pdfCacheKey, cachedPDF, createTimeSpan(0, 1, 0, 0))>
</cfif>
<cfcontent type="application/pdf" variable="#cachedPDF#">// Cache PDF for 1 hour
pdfCacheKey = "invoice_#invoiceID#";
cachedPDF = cacheGet(pdfCacheKey);
if (isNull(cachedPDF)) {
cfdocument(format="pdf", name="cachedPDF") {
// Document content
}
cachePut(pdfCacheKey, cachedPDF, createTimeSpan(0, 1, 0, 0));
}
cfcontent(type="application/pdf", variable=cachedPDF);Update and Regression Testing
PDFg updates may introduce rendering changes that affect your documents:
- Carefully review PDFg update notes for any known regressions or changes
- Test all critical PDF generation functionality after applying updates
- Maintain a comprehensive test suite with sample documents to catch rendering changes
- Monitor production output for rendering differences after updates are deployed
Common PDF Operations
PDF Generation
Generate PDF from HTML
<cfdocument format="pdf" filename="output.pdf" overwrite="true">
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #333; }
</style>
</head>
<body>
<h1>Invoice #12345</h1>
<p>Details here...</p>
</body>
</html>
</cfdocument>cfdocument(format="pdf", filename="output.pdf", overwrite=true) {
writeOutput("
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: ##333; }
</style>
</head>
<body>
<h1>Invoice ##12345</h1>
<p>Details here...</p>
</body>
</html>
");
}PDF Manipulation
PDF Operations
<!--- Merge PDFs --->
<cfpdf action="merge" destination="merged.pdf" overwrite="true">
<cfpdfparam source="file1.pdf">
<cfpdfparam source="file2.pdf">
</cfpdf>
<!--- Extract pages --->
<cfpdf action="extracttext" source="input.pdf" name="pdfText">
<!--- Add watermark --->
<cfpdf action="addwatermark"
source="input.pdf"
image="watermark.png"
destination="output.pdf">// Merge PDFs
cfpdf(
action="merge",
destination="merged.pdf",
overwrite=true,
source="file1.pdf,file2.pdf"
);
// Extract text
cfpdf(
action="extracttext",
source="input.pdf",
name="pdfText"
);
// Add watermark
cfpdf(
action="addwatermark",
source="input.pdf",
image="watermark.png",
destination="output.pdf"
);Monitoring and Troubleshooting
- Continuously monitor PDFg service health and uptime to catch issues early
- Track PDF generation times using the Performance Monitoring Toolset (PMT)
- Configure alerts to notify you of PDFg service crashes or high error rates
- Regularly review PDFg logs for rendering errors and performance issues
- Test your failover procedures if you're using multiple PDFg nodes
PDFg Checklist
- PDFg installed via cfpm
- PDFg service running and configured
- PDFg on separate nodes (recommended)
- Input validation for untrusted HTML
- Resource limits and timeouts configured
- PDF caching implemented for static content
- PDFg service health monitored
- Update regression tests in place
Gotchas
- Service Dependency: PDFg service must be running for PDF operations to work
- Rendering Differences: Complex HTML/CSS may render differently than in browsers
- External Resources: External resources (images, fonts) can cause timeouts or failures
- Update Regressions: PDFg updates can introduce rendering regressions
- Memory Usage: Large PDFs consume significant memory - size JVM appropriately
- Resource Exhaustion: Untrusted HTML input can cause resource exhaustion