COMPARISON

Gotenberg vs IronPDF: Technical Comparison Guide

When .NET developers assess PDF generation solutions, Gotenberg stands out as a Docker-based microservice that converts HTML to PDF through REST API calls. While adaptable for diverse architectures, Gotenberg introduces notable infrastructure overhead—Docker containers, network latency, and operational complexity. IronPDF offers an alternative: an in-process NuGet package providing the same Chromium-based rendering without containers, network calls, or infrastructure management.

This comparison looks at both solutions across technically relevant dimensions to assist professional developers and architects in making informed decisions for their .NET PDF needs.

Understanding Gotenberg

Gotenberg is a Docker-based microservice architecture for PDF generation. It runs as a separate container that exposes REST API endpoints for converting HTML, URLs, and other formats to PDF. Every PDF operation requires an HTTP call to the Gotenberg service.

Gotenberg uses endpoints like POST /forms/chromium/convert/html for HTML-to-PDF and POST /forms/chromium/convert/url for URL-to-PDF conversion. Configuration is passed via multipart/form-data with string-based parameters like paperWidth, paperHeight, marginTop, and marginBottom (in inches). The service requires Docker deployment, container orchestration (Kubernetes/Docker Compose), and network infrastructure.

The architecture requires:

  • Docker container deployment and management
  • Network communication for every PDF request (10-100ms+ latency)
  • Container cold start handling (2-5 seconds for first requests)
  • Health check endpoints and service monitoring
  • Multipart/form-data construction for every request

Understanding IronPDF

IronPDF is a native .NET library that runs in-process as a NuGet package. It provides Chromium-based HTML rendering without external services, network calls, or container infrastructure.

IronPDF uses ChromePdfRenderer as its primary rendering class with methods like RenderHtmlAsPdf() and RenderUrlAsPdf(). Configuration uses typed C# properties on RenderingOptions including PaperSize, MarginTop, MarginBottom (in millimeters). Documents are saved with SaveAs() or accessed as BinaryData.

The library requires only:

  • NuGet package installation (dotnet add package IronPdf)
  • License key configuration
  • Standard .NET project setup

Architecture and Infrastructure Comparison

The fundamental difference between these solutions lies in their deployment and runtime architecture.

FactorGotenbergIronPDF
DeploymentDocker container + orchestrationSingle NuGet package
ArchitectureMicroservice (REST API)In-process library
Latency per request10-100ms+ (network round-trip)< 1ms overhead
Cold start2-5 seconds (container init)1-2 seconds (first render only)
InfrastructureDocker, Kubernetes, load balancersNone required
Network dependencyRequiredNone
Failure modesNetwork, container, service failuresStandard .NET exceptions
API styleREST multipart/form-dataNative C# method calls
ScalingHorizontal (more containers)Vertical (in-process)
DebuggingDistributed tracingStandard debugger
Memory managementSeparate container (512MB-2GB)Shared application memory
Version controlContainer image tagsNuGet package versions
Health checksHTTP endpoints requiredNot needed (in-process)
CI/CD complexityContainer builds, registry pushesStandard .NET build

Gotenberg's Docker-based approach requires container deployment, health monitoring, and network infrastructure management. IronPDF eliminates this infrastructure layer entirely by running in-process.

Code Comparison: Common PDF Operations

Basic HTML to PDF Conversion

The most fundamental operation demonstrates the architectural difference clearly.

Gotenberg:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergExample
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("output.pdf", pdfBytes);
        Console.WriteLine("PDF generated successfully");
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergExample
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("output.pdf", pdfBytes);
        Console.WriteLine("PDF generated successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF:

// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class IronPdfExample
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var html = "<html><body><h1>Hello from IronPDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF generated successfully");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class IronPdfExample
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var html = "<html><body><h1>Hello from IronPDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF generated successfully");
    }
}
$vbLabelText   $csharpLabel

Gotenberg requires creating an HttpClient, constructing MultipartFormDataContent, adding the HTML as a file attachment with a specific filename (index.html), making an async HTTP POST to the Gotenberg service endpoint, reading the response bytes, and writing to disk. Every request goes over the network with associated latency and failure modes.

IronPDF creates a ChromePdfRenderer, calls RenderHtmlAsPdf() with the HTML string, and saves with SaveAs(). The operation is synchronous, in-process, and uses typed methods rather than string-based form data.

For advanced HTML rendering options, explore the HTML to PDF conversion guide.

URL to PDF Conversion

Converting live web pages to PDF shows similar architectural patterns.

Gotenberg:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergUrlToPdf
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        content.Add(new StringContent("https://example.com"), "url");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("webpage.pdf", pdfBytes);
        Console.WriteLine("PDF from URL generated successfully");
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergUrlToPdf
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        content.Add(new StringContent("https://example.com"), "url");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("webpage.pdf", pdfBytes);
        Console.WriteLine("PDF from URL generated successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF:

// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class IronPdfUrlToPdf
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://example.com");

        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("PDF from URL generated successfully");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class IronPdfUrlToPdf
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://example.com");

        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("PDF from URL generated successfully");
    }
}
$vbLabelText   $csharpLabel

Gotenberg uses the /forms/chromium/convert/url endpoint with the URL passed as form data. IronPDF calls RenderUrlAsPdf() directly with the URL string—a single method call replacing the HTTP infrastructure.

Custom Page Size and Margins

Configuration handling reveals the API design differences.

Gotenberg:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergCustomSize
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");
        content.Add(new StringContent("8.5"), "paperWidth");
        content.Add(new StringContent("11"), "paperHeight");
        content.Add(new StringContent("0.5"), "marginTop");
        content.Add(new StringContent("0.5"), "marginBottom");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes);
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergCustomSize
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");
        content.Add(new StringContent("8.5"), "paperWidth");
        content.Add(new StringContent("11"), "paperHeight");
        content.Add(new StringContent("0.5"), "marginTop");
        content.Add(new StringContent("0.5"), "marginBottom");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes);
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF:

// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;

class IronPdfCustomSize
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 50;
        renderer.RenderingOptions.MarginBottom = 50;

        var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom-size.pdf");
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;

class IronPdfCustomSize
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 50;
        renderer.RenderingOptions.MarginBottom = 50;

        var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom-size.pdf");
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
$vbLabelText   $csharpLabel

Gotenberg uses string-based parameters ("8.5", "11", "0.5") added to multipart form data. Paper dimensions are in inches. Each parameter is a separate Add() call with no type checking or IntelliSense support.

IronPDF uses typed properties on RenderingOptions. PaperSize accepts an enum (PdfPaperSize.Letter), and margins are numeric values in millimeters. The typed API provides compile-time checking and IDE support.

Learn more about rendering configuration in the IronPDF tutorials.

API Mapping Reference

For developers evaluating Gotenberg migration or comparing capabilities, this mapping shows equivalent operations:

Endpoint to Method Mapping

Gotenberg RouteIronPDF Equivalent
POST /forms/chromium/convert/htmlChromePdfRenderer.RenderHtmlAsPdf()
POST /forms/chromium/convert/urlChromePdfRenderer.RenderUrlAsPdf()
POST /forms/chromium/convert/markdownRender Markdown as HTML first
POST /forms/pdfengines/mergePdfDocument.Merge()
POST /forms/pdfengines/metadata/readpdf.MetaData
POST /forms/pdfengines/metadata/writepdf.MetaData.Author = "..."
GET /healthN/A

Form Parameter to RenderingOptions Mapping

Gotenberg ParameterIronPDF PropertyConversion Notes
paperWidth (inches)RenderingOptions.SetCustomPaperSizeInInches()Use method for custom
paperHeight (inches)RenderingOptions.SetCustomPaperSizeInInches()Use method for custom
marginTop (inches)RenderingOptions.MarginTopMultiply by 25.4 for mm
marginBottom (inches)RenderingOptions.MarginBottomMultiply by 25.4 for mm
marginLeft (inches)RenderingOptions.MarginLeftMultiply by 25.4 for mm
marginRight (inches)RenderingOptions.MarginRightMultiply by 25.4 for mm
printBackgroundRenderingOptions.PrintHtmlBackgroundsBoolean
landscapeRenderingOptions.PaperOrientationLandscape enum
scaleRenderingOptions.ZoomPercentage (100 = 1.0)
waitDelayRenderingOptions.RenderDelayConvert to milliseconds
emulatedMediaTypeRenderingOptions.CssMediaTypeScreen or Print

Note the unit conversion: Gotenberg uses inches for margins (e.g., "0.5" = 0.5 inches = 12.7mm), while IronPDF uses millimeters.

Infrastructure Comparison

Gotenberg Docker Compose

Gotenberg requires container infrastructure:

# Gotenberg requires container management
version: '3.8'
services:
  app:
    depends_on:
      - gotenberg
    environment:
      - GOTENBERG_URL=http://gotenberg:3000

  gotenberg:
    image: gotenberg/gotenberg:8
    ports:
      - "3000:3000"
    deploy:
      resources:
        limits:
          memory: 2G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
# Gotenberg requires container management
version: '3.8'
services:
  app:
    depends_on:
      - gotenberg
    environment:
      - GOTENBERG_URL=http://gotenberg:3000

  gotenberg:
    image: gotenberg/gotenberg:8
    ports:
      - "3000:3000"
    deploy:
      resources:
        limits:
          memory: 2G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
YAML

IronPDF Configuration

IronPDF requires no additional services:

# IronPDF - No additional services needed
version: '3.8'
services:
  app:
    environment:
      - IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No Gotenberg service. No health checks. No resource limits.
# IronPDF - No additional services needed
version: '3.8'
services:
  app:
    environment:
      - IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No Gotenberg service. No health checks. No resource limits.
YAML

The infrastructure difference is substantial: Gotenberg requires container deployment, health monitoring, resource allocation, and service dependencies. IronPDF runs in-process with the application.

Performance Characteristics

OperationGotenberg (Warm Container)Gotenberg (Cold Start)IronPDF (First Render)IronPDF (Subsequent)
Simple HTML150-300ms2-5 seconds1-2 seconds50-150ms
Complex HTML500-1500ms3-7 seconds1.5-3 seconds200-800ms
URL Render1-5 seconds3-10 seconds1-5 seconds500ms-3s
PDF Merge200-500ms2-5 seconds100-300ms100-300ms

Gotenberg's network round-trip adds 10-100ms+ per request. Container cold starts add 2-5 seconds. IronPDF's first render incurs Chromium initialization (1-2 seconds), but subsequent renders have minimal overhead.

When Teams Consider Moving from Gotenberg to IronPDF

Development teams evaluate transitioning from Gotenberg to IronPDF for several reasons:

Infrastructure Overhead: Gotenberg requires Docker, container orchestration (Kubernetes/Docker Compose), service discovery, and load balancing. Teams seeking simpler deployment find IronPDF's NuGet-only approach eliminates these infrastructure concerns.

Network Latency: Every Gotenberg PDF operation requires an HTTP call to a separate service—adding 10-100ms+ per request. For high-volume applications, this overhead accumulates. IronPDF's in-process approach has negligible overhead after initialization.

Cold Start Issues: Container startup can add 2-5 seconds to first requests. Even warm containers have network overhead. Every pod restart, scale-up event, or deployment triggers cold starts. IronPDF's cold start occurs once per application lifetime.

Operational Complexity: Gotenberg requires managing container health, scaling, logging, and monitoring as separate concerns. Network timeouts, service unavailability, and container crashes become application concerns. IronPDF uses standard .NET exception handling.

Multipart Form Data API: Every Gotenberg request requires constructing multipart/form-data payloads with string-based parameters—verbose and without compile-time type checking. IronPDF provides typed C# properties with IntelliSense support.

Version Management: Gotenberg images update separately from your application. API changes can break integrations. IronPDF versions are managed through NuGet with standard .NET dependency management.

Strengths and Considerations

Gotenberg Strengths

  • Polyglot Architecture: Works with any language that can make HTTP calls
  • Language Agnostic: Not tied to .NET ecosystem
  • MIT License: Free and open source
  • Microservices Pattern: Fits containerized architectures

Gotenberg Considerations

  • Infrastructure Overhead: Docker, Kubernetes, load balancers required
  • Network Latency: 10-100ms+ per request
  • Cold Starts: 2-5 seconds container initialization
  • String-Based API: No type safety or IntelliSense
  • Distributed Debugging: Requires distributed tracing
  • Health Monitoring: Additional endpoints to manage

IronPDF Strengths

  • Zero Infrastructure: NuGet package only
  • In-Process Performance: No network latency after initialization
  • Type-Safe API: Strongly-typed properties with IntelliSense
  • Standard Debugging: Normal .NET debugger works
  • Comprehensive Resources: Extensive tutorials and documentation
  • Professional Support: Commercial license includes support

IronPDF Considerations

  • .NET Specific: Designed for .NET ecosystem
  • Commercial License: Required for production use

Gotenberg and IronPDF represent fundamentally different approaches to PDF generation in .NET applications. Gotenberg's Docker-based microservice architecture introduces container management, network latency, and operational complexity. Every PDF operation requires HTTP communication with associated failure modes and cold start penalties.

IronPDF provides the same Chromium-based rendering as an in-process library. The NuGet package eliminates Docker containers, network calls, and infrastructure management. Typed C# APIs replace string-based multipart form data. Standard .NET exception handling replaces HTTP status codes and network failure modes.

As organizations plan for .NET 10, C# 14, and application development through 2026, the choice between microservice infrastructure overhead and in-process library simplicity significantly impacts deployment and operational complexity. Teams seeking to reduce infrastructure burden while maintaining HTML/CSS/JavaScript rendering fidelity will find IronPDF addresses these requirements effectively.

Start evaluating IronPDF with a free trial and explore the comprehensive documentation to assess fit for your specific requirements.