DEV Community

IronSoftware
IronSoftware

Posted on

SelectPdf Slow Build Times: Why Your Compilation Takes Forever

Adding SelectPdf to a .NET project introduces a noticeable drag on build times. Developers report that builds which previously completed in 12 seconds now take 45 seconds or longer after adding the SelectPdf NuGet package. CI/CD pipelines that once ran quickly now stall waiting for package restoration and file copying. The culprit is the sheer size of the SelectPdf assemblies: packages ranging from 65 MB to over 105 MB that must be downloaded, extracted, and deployed with every build.

The Problem

SelectPdf distributes its PDF generation capabilities through NuGet packages that dwarf typical .NET library sizes. The primary Select.Pdf package weighs 75.61 MB, while the .NET Core variant Select.Pdf.NetCore reaches 105.33 MB. These figures represent the compressed NuGet package size; extracted assembly sizes are even larger.

For comparison, most .NET libraries on NuGet fall between 100 KB and 5 MB. SelectPdf packages are 15 to 100 times larger than the average NuGet dependency. Every clean build must download, extract, and copy these massive assemblies to the output directory.

The problem compounds when using the Blink rendering engine. SelectPdf.NetCore.Blink includes an entire Chromium browser folder (Chromium-124.0.6367.201) that must be deployed alongside the application. This folder contains hundreds of files totaling hundreds of megabytes, all of which must be processed during build and deployment.

Symptoms During Build

Developers observe several performance impacts:

Restoring packages for MyProject.csproj...
  GET https://api.nuget.org/v3-flatcontainer/select.pdf.netcore/25.2.0/select.pdf.netcore.25.2.0.nupkg
  OK https://api.nuget.org/v3-flatcontainer/select.pdf.netcore/25.2.0/select.pdf.netcore.25.2.0.nupkg 47231ms

Build started...
Copying files to output directory...
  Select.Pdf.dll
  Select.Html.dep
  Select.Tools.dep
  Chromium-124.0.6367.201/ (423 files)
Build completed in 67.4 seconds (previously 15.2 seconds)
Enter fullscreen mode Exit fullscreen mode

CI/CD pipeline logs reveal the impact more clearly:

# Azure DevOps Pipeline Output
- task: NuGetCommand@2
  displayName: 'Restore NuGet packages'
  # Duration: 3m 42s (with SelectPdf)
  # Duration: 0m 28s (without SelectPdf)

- task: DotNetCoreCLI@2
  displayName: 'Build'
  # Duration: 2m 15s (with SelectPdf)
  # Duration: 0m 45s (without SelectPdf)
Enter fullscreen mode Exit fullscreen mode

The total build time increase of 4-5 minutes per pipeline run multiplies across daily builds, pull request checks, and deployment cycles.

Who Is Affected

The selectpdf slow build issue impacts several categories of development workflows.

CI/CD Pipeline Impact:

  • GitHub Actions workflows exceed free tier minutes faster
  • Azure DevOps build minutes consumption increases significantly
  • Jenkins agents spend more time per job, reducing throughput
  • Docker image builds take longer due to larger layer sizes
  • Artifact storage costs increase with 100+ MB deployment packages

Development Machine Impact:

  • Clean builds require re-downloading large packages
  • Visual Studio Solution Load times increase
  • NuGet package cache consumes substantial disk space
  • Developers on slower internet connections face extended waits
  • Teams with metered connections incur additional data costs

Deployment Impact:

  • Azure App Service deployment slots take longer to swap
  • Container registry push/pull times increase
  • Serverless cold starts carry larger payload overhead
  • Kubernetes pod scheduling delays from image pull times

Evidence from the Developer Community

SelectPdf's package size has been noted in multiple technical discussions and comparisons.

Package Size Comparison

Package Version Compressed Size Notes
Select.Pdf 25.2.0 75.61 MB .NET Framework version
Select.Pdf.NetCore 25.2.0 105.33 MB .NET Core/.NET 5+ version
Select.HtmlToPdf 25.2.0 65.97 MB HTML conversion focused
Select.Pdf.x64 25.2.0 83.99 MB 64-bit optimized
Select.Pdf.NetCore.Blink 25.2.0 Package + Chromium folder Blink engine version

Community Observations

Technical comparison articles have noted the build impact:

"SelectPdf can have a big hit on your build time and deploy package size."
-- Technical comparison citing Stack Overflow discussions

The SelectPdf documentation itself acknowledges the file requirements:

"When SelectPdf is installed into your project, a reference to Select.Pdf.dll is created. Besides this assembly, several additional files are needed by SelectPdf: Select.Html.dep, Select.Tools.dep, and Chromium-124.0.6367.201 folder."
-- SelectPdf Installation Documentation

These additional files do not have project references, meaning build systems may not automatically optimize their handling.

Licensing Adds Deployment Concerns

SelectPdf's licensing model ties license tiers to deployment machine counts:

License Tier Developers Deployment Machines Price (1 Year)
Single Developer 1 1 $499
5-Developers Up to 5 Up to 10 $799
Enterprise Unlimited Up to 100 $1,199
Enterprise OEM Unlimited Unlimited $1,599

For teams scaling across multiple servers, the per-machine licensing creates cost uncertainty. Only OEM licenses allow unlimited deployment, and cloud deployments specifically require OEM licenses according to SelectPdf documentation. This means a team with 20 production servers, 10 staging servers, and 30 developer machines would need the Enterprise OEM tier regardless of actual usage patterns.

Root Cause Analysis

SelectPdf's assembly size stems from its architectural approach to PDF generation.

Multiple Rendering Engines:
SelectPdf bundles both WebKit and Blink (Chromium) rendering engines. The WebKit engine powers the Select.Html.dep file, while Blink requires a full Chromium installation. Supporting both engines in a single package means carrying the weight of both, even when only one is used.

Native Binary Dependencies:
The Select.Html.dep and Select.Tools.dep files are not .NET assemblies but native executables. These files contain the rendering logic that SelectPdf invokes through inter-process communication. Native binaries cannot be trimmed or optimized by .NET build tools.

Architecture Variants:
SelectPdf provides both x86 and x64 binaries in several packages, doubling the file size for broad compatibility. The x64-specific packages (Select.Pdf.x64) exist to reduce this overhead, but require teams to commit to a single architecture.

No Lazy Loading Architecture:
All SelectPdf binaries must be present at build time and deployed together. There is no option to download rendering components on-demand at runtime, which would allow smaller initial packages.

Attempted Workarounds

Developers have tried several approaches to mitigate selectpdf compilation time impact.

Workaround 1: Use Architecture-Specific Packages

Approach: Install Select.Pdf.x64 instead of the general Select.Pdf package to avoid including 32-bit binaries.

<!-- Instead of -->
<PackageReference Include="Select.Pdf" Version="25.2.0" />

<!-- Use -->
<PackageReference Include="Select.Pdf.x64" Version="25.2.0" />
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Still 83.99 MB package size
  • Only works for x64 deployment targets
  • Does not reduce Select.Html.dep or Select.Tools.dep sizes
  • Breaks builds on x86 systems

Workaround 2: Exclude from Clean Builds

Approach: Configure build to preserve SelectPdf files in output directory between builds.

<PropertyGroup>
  <PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>

<ItemGroup>
  <None Update="Select.Html.dep">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Does not help CI/CD pipelines that start fresh each run
  • Can cause stale binary issues after SelectPdf updates
  • Requires manual configuration per project
  • Does not reduce package download time

Workaround 3: NuGet Package Caching

Approach: Configure persistent NuGet cache in CI/CD pipelines.

# GitHub Actions example
- name: Cache NuGet packages
  uses: actions/cache@v3
  with:
    path: ~/.nuget/packages
    key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Cache invalidates on any package version change
  • First build in a cache miss scenario still slow
  • Cache storage counts against repository limits
  • Does not address local development clean builds

Workaround 4: Move PDF Generation to Separate Service

Approach: Isolate SelectPdf into a microservice that builds independently from the main application.

Limitations:

  • Significant architectural change
  • Introduces network latency for PDF operations
  • Adds operational complexity
  • Does not eliminate SelectPdf build time, only moves it

A Different Approach: IronPDF

IronPDF provides an alternative architecture that addresses package size concerns differently. While IronPDF also includes Chromium-based rendering, it offers deployment options that reduce build-time impact.

Why IronPDF Addresses Build Time Differently

IronPDF provides the IronPdf.Slim package specifically designed for environments where package size matters. This package contains only the core IronPdf.dll, with native rendering binaries downloaded at runtime when first needed.

Package Size Comparison:

Package Size Native Binaries
IronPdf (full) Contains platform binaries Included in package
IronPdf.Slim Core DLL only Downloaded at runtime
IronPdf.Linux Linux-optimized Linux binaries only

The Slim package approach means:

  • CI/CD builds download only the small core package
  • Platform-specific binaries download once per deployment target
  • Build artifacts remain small for faster artifact transfer
  • Different deployment targets can use different binary packages

Code Example

using IronPdf;

/// <summary>
/// Demonstrates IronPDF configuration for minimal build impact.
/// The Slim package approach separates compile-time dependencies
/// from runtime rendering binaries.
/// </summary>
public class BuildOptimizedPdfGenerator
{
    public BuildOptimizedPdfGenerator()
    {
        // When using IronPdf.Slim, enable automatic binary download
        // Binaries download once on first use, not during build
        Installation.AutomaticallyDownloadNativeBinaries = true;

        // Optionally specify a persistent location for binaries
        // This prevents re-download across application restarts
        Installation.CustomChromiumPath = "/var/lib/ironpdf/chromium";
    }

    public byte[] GeneratePdf(string htmlContent)
    {
        // Renderer uses pre-downloaded or just-in-time downloaded binaries
        var renderer = new ChromePdfRenderer();

        // Configure rendering options
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

        // Generate PDF
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
}
Enter fullscreen mode Exit fullscreen mode

Key points about this code:

  • The IronPdf.Slim package keeps build artifacts small
  • Native binaries download once at runtime, not during every build
  • Binary path configuration allows sharing across deployments
  • No architectural changes required compared to SelectPdf migration

CI/CD Pipeline Example

# GitHub Actions workflow demonstrating build optimization
name: Build with IronPdf.Slim

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'

      # Small package restore - IronPdf.Slim is minimal
      - name: Restore dependencies
        run: dotnet restore
        # Duration: ~30 seconds (vs 3+ minutes with full SelectPdf)

      - name: Build
        run: dotnet build --no-restore
        # Duration: ~45 seconds (consistent with pre-PDF-library times)

      # IronPDF binaries download during first test execution
      # Subsequent runs use cached binaries
      - name: Test
        run: dotnet test --no-build
Enter fullscreen mode Exit fullscreen mode

API Reference

For deployment optimization documentation:

Migration Considerations

Licensing

IronPDF uses a different licensing model:

  • Lite license: $749 (1 developer, 1 project, perpetual)
  • Plus license: $1,499 (3 developers, 3 projects, perpetual)
  • Professional license: $2,999 (10 developers, 10 projects, perpetual)
  • Unlimited license: $5,999 (unlimited developers and projects, perpetual)

Unlike SelectPdf, IronPDF licenses are not tied to deployment machine counts. A single license covers unlimited servers, containers, and cloud instances for the licensed project count. This simplifies cost planning for scaling deployments.

API Differences

The migration from SelectPdf to IronPDF requires updating class names and method signatures:

SelectPdf:

var converter = new HtmlToPdf();
converter.Options.PdfPageSize = PdfPageSize.A4;
var doc = converter.ConvertHtmlString(html);
doc.Save("output.pdf");
Enter fullscreen mode Exit fullscreen mode

IronPDF:

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Enter fullscreen mode Exit fullscreen mode

The conceptual mapping is straightforward:

SelectPdf IronPDF
HtmlToPdf ChromePdfRenderer
ConvertHtmlString() RenderHtmlAsPdf()
ConvertUrl() RenderUrlAsPdf()
Options.PdfPageSize RenderingOptions.PaperSize
doc.Save() pdf.SaveAs()

What You Gain

  • Significantly smaller build artifacts with IronPdf.Slim
  • Deployment-count-independent licensing
  • Cross-platform support (Windows, Linux, macOS) from single package
  • Runtime binary download option for CI/CD optimization
  • Docker and Azure compatibility without elevated tier requirements

What to Consider

  • Full IronPDF packages are also large when including all binaries
  • Runtime binary download requires internet access on first execution
  • Memory usage patterns differ from SelectPdf
  • Some SelectPdf-specific features may have different implementations

Conclusion

SelectPdf's 65-105 MB NuGet packages add substantial overhead to build times and CI/CD pipelines. The per-deployment-machine licensing model compounds concerns for scaling applications. While workarounds exist, they address symptoms rather than the fundamental selectpdf assembly size issue. IronPDF's Slim package architecture offers an alternative that keeps build artifacts small while providing runtime binary download, addressing both the compilation time impact and the licensing complexity that teams face when deploying across multiple servers.


Jacob Mellor is CTO at Iron Software, where he leads the technical development of IronPDF and other developer tools.


References

  1. NuGet Gallery - Select.Pdf{:rel="nofollow"} - Package size and version information
  2. NuGet Gallery - Select.Pdf.NetCore{:rel="nofollow"} - .NET Core package information
  3. SelectPdf Installation Documentation{:rel="nofollow"} - Official file deployment requirements
  4. SelectPdf Pricing{:rel="nofollow"} - License tiers and deployment machine limits
  5. SelectPdf Deployment Documentation{:rel="nofollow"} - Deployment file requirements
  6. SelectPdf EULA{:rel="nofollow"} - License terms including deployment restrictions
  7. IronPdf.Slim Package - Minimal package size option
  8. IronPDF Package Size Documentation - Package size considerations and options

For the latest IronPDF documentation and tutorials, visit ironpdf.com.

Top comments (0)