From 04b9039aafabc913a0dc984ebf9243619e7a6778 Mon Sep 17 00:00:00 2001
From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
Date: Wed, 6 May 2026 18:11:54 +0100
Subject: [PATCH 1/7] unoserver-improvements
---
.../LibreOffice-Parallel-Processing.md | 132 +++++++++++++++++-
.../Configuration/Performance-Optimization.md | 2 +-
2 files changed, 130 insertions(+), 4 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index 653e282a..c37ef530 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -47,12 +47,20 @@ By default, Stirling PDF manages a local pool of UNO (Universal Network Objects)
-Each additional instance consumes approximately **50 MB of RAM when idle** and significantly more during active conversion. A reasonable starting point is one instance per 2 CPU cores, adjusted based on available RAM and expected workload.
+A reasonable starting point is one instance per 2 CPU cores; see [Host resource requirements](#host-resource-requirements) below for memory and storage sizing.
+
+If an instance becomes unresponsive it is automatically restarted in the background, so your conversions keep working without manual intervention.
:::info
The default `libreOfficeSessionLimit` is `1`, meaning only one conversion runs at a time. If you see conversions queuing up or running slowly, increasing this is the first thing to try.
:::
+### Throughput expectations
+
+Per-worker throughput varies enormously with document content and host hardware. Tiny plain DOCX inputs on a fast SSD-backed host can finish in well under a second, while large PPTX with embedded media or complex spreadsheets on a constrained host can take tens of seconds each. There's no single number worth quoting. What is reliable is that the pool's total throughput scales roughly linearly with instance count up to the host's available CPU; doubling workers on an under-saturated host roughly doubles concurrency.
+
+Measure your own baseline: run a representative document through a single worker, time the conversion, then size the pool around your expected concurrent users and acceptable queue wait. Plan for the worst-case documents your users actually upload, not the average.
+
---
## Remote UNO Server Endpoints
@@ -111,12 +119,12 @@ Set `autoUnoServer` to `false` and define your remote endpoints:
- "8080:8080"
unoserver1:
- image: docker.stirlingpdf.com/stirlingtools/stirling-pdf-unoserver:latest
+ image: ghcr.io/stirling-tools/stirling-unoserver:latest
ports:
- "2003:2003"
unoserver2:
- image: docker.stirlingpdf.com/stirlingtools/stirling-pdf-unoserver:latest
+ image: ghcr.io/stirling-tools/stirling-unoserver:latest
ports:
- "2004:2003"
```
@@ -143,6 +151,47 @@ Use `remote` when running UNO servers in separate Docker containers, even if the
---
+## The `stirling-unoserver` Image
+
+`ghcr.io/stirling-tools/stirling-unoserver` is the official image for the remote pool pattern, ready to run as a standalone conversion worker.
+
+Available tags:
+
+| Tag | Use it for |
+|---|---|
+| `:latest` | Production deployments |
+| `:alpha` | Pre-release testing |
+| `:1.0.0`, `:1.0.1`, etc. | Pin to a specific version |
+
+The image is versioned independently from Stirling PDF and only republished when the image itself changes, so under normal circumstances you can pin a specific image version and leave it alone while Stirling PDF itself updates. In the rare case Stirling PDF requires a newer compatible image, that will be called out in the release notes and migration docs. Full version independence is the goal but not a guarantee.
+
+### Configuration options
+
+| Variable | Default | Purpose |
+|---|---|---|
+| `UNOSERVER_PORT` | `2003` | Port the client connects to. Change if it conflicts with another service on the host. |
+| `UNOSERVER_INTERFACE` | `0.0.0.0` | Listen address. Use `127.0.0.1` to make the container reachable only from the same host. |
+| `UNOSERVER_CONVERSION_TIMEOUT` | `1800` (seconds) | Maximum time a single conversion is allowed to run. If exceeded, the container restarts itself automatically. Set this to be at least as long as Stirling PDF's `libreOfficeTimeoutMinutes`. |
+| `UNOSERVER_RECYCLE_INTERVAL_SECONDS` | `0` (disabled) | Periodically restart the container to keep memory usage steady over long uptimes. Set to e.g. `3600` for hourly recycling. Minimum value is 60 seconds. |
+
+### Periodic recycling
+
+LibreOffice can slowly grow its memory footprint over many conversions. Setting `UNOSERVER_RECYCLE_INTERVAL_SECONDS` makes each container restart itself on a schedule, keeping memory usage steady.
+
+The restart takes a few seconds. During that window any request routed to that container is automatically retried by Stirling PDF, so user-facing requests still complete normally. If you run several containers, their startups will drift apart naturally so they don't all recycle at the same moment.
+
+For steady production traffic, an hourly or once-a-day recycle is usually plenty. For lighter workloads or short-lived deployments you can leave it disabled.
+
+:::info Run multiple instances
+A single container is one worker. To run four workers, declare four services in your compose file (`unoserver1` through `unoserver4`) using the same image, and list all four endpoints in the Stirling PDF configuration.
+:::
+
+### Asian-language fonts
+
+The default image includes broad European-language coverage including hyphenation for English, French, German, Spanish, Italian, Portuguese, Dutch, Polish, and Russian. If you need Chinese, Japanese, or Korean conversion support you'll need a custom variant of the image with CJK fonts added. Contact us or open a GitHub issue and we can publish one.
+
+---
+
## Running UNO Servers Without Docker
If you are running Stirling PDF without Docker (bare metal or systemd), you can start additional UNO server instances manually using the `unoserver` Python package:
@@ -184,6 +233,83 @@ If conversions are consistently timing out, this usually indicates the system is
---
+## Host resource requirements
+
+When sizing a host for office conversion, plan for the following:
+
+**Memory.** Each LibreOffice worker uses around 70 MB of RAM when idle, climbing to 140 to 250 MB during active conversion depending on the document. Multiply by your worker count and add headroom for the operating system, the Stirling PDF application itself, and any other services on the host. If memory runs out, the OS will start killing processes and conversions will fail.
+
+**CPU.** Each conversion uses one CPU core at 100% for its duration, regardless of how many cores the host has. A reasonable starting point is one worker per two CPU cores; increase from there if you see queues building up.
+
+**Storage.** Uploaded files are written to temporary disk space at `/tmp/stirling-pdf` while they're being converted. Allow free space of roughly `2 × your maximum upload size × number of concurrent uploads`. On hosts with a small `/tmp` partition (some VPS providers default to 1 or 2 GB) mount a larger volume:
+
+```yaml
+services:
+ stirling-pdf:
+ volumes:
+ - stirling-tmp:/tmp/stirling-pdf
+volumes:
+ stirling-tmp: {}
+```
+
+---
+
+## Worked example: 4 remote workers
+
+A reasonable starting point for a small team or trial deployment is one Stirling PDF instance plus four `stirling-unoserver` containers on the same host, with the conversion pool capped at 4. This caps memory predictably and lets all four conversions run truly in parallel:
+
+```yaml
+services:
+ stirling-pdf:
+ image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
+ ports:
+ - "8080:8080"
+ environment:
+ PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
+ PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "4"
+ PROCESS_EXECUTOR_TIMEOUT_MINUTES_LIBRE_OFFICETIMEOUT_MINUTES: "5"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION: "remote"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST: "unoserver2"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION: "remote"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST: "unoserver3"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION: "remote"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST: "unoserver4"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST_LOCATION: "remote"
+ depends_on:
+ unoserver1: { condition: service_started }
+ unoserver2: { condition: service_started }
+ unoserver3: { condition: service_started }
+ unoserver4: { condition: service_started }
+
+ unoserver1: &uno
+ image: ghcr.io/stirling-tools/stirling-unoserver:latest
+ environment:
+ UNOSERVER_RECYCLE_INTERVAL_SECONDS: "3600"
+ deploy:
+ resources:
+ limits: { cpus: "1.0", memory: 1g }
+ restart: on-failure:5
+ unoserver2: { <<: *uno }
+ unoserver3: { <<: *uno }
+ unoserver4: { <<: *uno }
+```
+
+Stirling PDF distributes incoming conversions evenly across all configured workers. Extra requests above the worker count simply queue and wait for a free slot. The system stays stable under high concurrency. The practical limits you'll hit, in order, are:
+
+1. Per-conversion time on heavy documents (a complex PPTX or large spreadsheet can take tens of seconds, which lowers your effective throughput regardless of worker count)
+2. Host CPU saturation
+3. Free `/tmp` disk space if many large uploads queue at once
+4. Stirling PDF's `libreOfficeTimeoutMinutes` for any single request that waits too long
+
+If your workload is mostly heavy documents, run more workers with smaller per-worker memory limits rather than fewer larger ones. That gives you better parallelism per dollar of RAM.
+
+---
+
## Related
- [Process Limits](./Process-Limits.md) — Configure session limits and timeouts for all external tools
diff --git a/docs/Configuration/Performance-Optimization.md b/docs/Configuration/Performance-Optimization.md
index d3f5c473..2a7ef01d 100644
--- a/docs/Configuration/Performance-Optimization.md
+++ b/docs/Configuration/Performance-Optimization.md
@@ -146,7 +146,7 @@ Some operations require significantly more resources than others. If your organi
|---|---|---|---|
| Merge / Split | Low | Proportional to total file sizes | Lightweight file operations |
| OCR (Tesseract) | Very High | High | CPU-bound image analysis |
-| File Conversion (LibreOffice) | High | High | Single-threaded per instance |
+| File Conversion (LibreOffice) | High | High | Single-threaded per instance. Scales by running multiple instances. Per-conversion time varies widely with document complexity and host hardware. See [LibreOffice Parallel Processing](./LibreOffice-Parallel-Processing.md). |
| PDF-to-Image | Moderate | Very High | Page rendering expands memory significantly |
| PDF/A Conversion | Moderate | High | Font embedding and color profiles |
| Compression | Moderate | High | Rewriting internal PDF structures |
From abbbac4cb181a9ab807197db883df9b82322cfda Mon Sep 17 00:00:00 2001
From: a
Date: Tue, 12 May 2026 14:32:05 +0100
Subject: [PATCH 2/7] Trim verbosity in LibreOffice parallel processing docs
Compress throughput, recycling, host-sizing, and worked-example sections,
drop unverified claims, and surface the INSTALL_CJK_FONTS build arg.
---
.../LibreOffice-Parallel-Processing.md | 77 ++++++-------------
.../Configuration/Performance-Optimization.md | 2 +-
2 files changed, 24 insertions(+), 55 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index c37ef530..3919fc26 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -47,9 +47,7 @@ By default, Stirling PDF manages a local pool of UNO (Universal Network Objects)
-A reasonable starting point is one instance per 2 CPU cores; see [Host resource requirements](#host-resource-requirements) below for memory and storage sizing.
-
-If an instance becomes unresponsive it is automatically restarted in the background, so your conversions keep working without manual intervention.
+A reasonable starting point is one instance per 2 CPU cores. See [Host resource requirements](#host-resource-requirements) for memory and storage sizing.
:::info
The default `libreOfficeSessionLimit` is `1`, meaning only one conversion runs at a time. If you see conversions queuing up or running slowly, increasing this is the first thing to try.
@@ -57,9 +55,7 @@ The default `libreOfficeSessionLimit` is `1`, meaning only one conversion runs a
### Throughput expectations
-Per-worker throughput varies enormously with document content and host hardware. Tiny plain DOCX inputs on a fast SSD-backed host can finish in well under a second, while large PPTX with embedded media or complex spreadsheets on a constrained host can take tens of seconds each. There's no single number worth quoting. What is reliable is that the pool's total throughput scales roughly linearly with instance count up to the host's available CPU; doubling workers on an under-saturated host roughly doubles concurrency.
-
-Measure your own baseline: run a representative document through a single worker, time the conversion, then size the pool around your expected concurrent users and acceptable queue wait. Plan for the worst-case documents your users actually upload, not the average.
+Per-conversion time varies from sub-second (small DOCX) to tens of seconds (complex PPTX, large spreadsheets). Pool throughput scales roughly linearly with worker count up to host CPU saturation — benchmark a representative document before sizing.
---
@@ -153,42 +149,32 @@ Use `remote` when running UNO servers in separate Docker containers, even if the
## The `stirling-unoserver` Image
-`ghcr.io/stirling-tools/stirling-unoserver` is the official image for the remote pool pattern, ready to run as a standalone conversion worker.
-
-Available tags:
+`ghcr.io/stirling-tools/stirling-unoserver` is the official standalone worker image.
-| Tag | Use it for |
+| Tag | Use |
|---|---|
-| `:latest` | Production deployments |
+| `:latest` | Production |
| `:alpha` | Pre-release testing |
-| `:1.0.0`, `:1.0.1`, etc. | Pin to a specific version |
+| `:1.0.0`, `:1.0.1`, … | Pinned version |
-The image is versioned independently from Stirling PDF and only republished when the image itself changes, so under normal circumstances you can pin a specific image version and leave it alone while Stirling PDF itself updates. In the rare case Stirling PDF requires a newer compatible image, that will be called out in the release notes and migration docs. Full version independence is the goal but not a guarantee.
+The image is versioned independently from Stirling PDF — pin a version and update it on its own cadence. Compatibility breaks are called out in release notes.
-### Configuration options
+### Configuration
| Variable | Default | Purpose |
|---|---|---|
-| `UNOSERVER_PORT` | `2003` | Port the client connects to. Change if it conflicts with another service on the host. |
-| `UNOSERVER_INTERFACE` | `0.0.0.0` | Listen address. Use `127.0.0.1` to make the container reachable only from the same host. |
-| `UNOSERVER_CONVERSION_TIMEOUT` | `1800` (seconds) | Maximum time a single conversion is allowed to run. If exceeded, the container restarts itself automatically. Set this to be at least as long as Stirling PDF's `libreOfficeTimeoutMinutes`. |
-| `UNOSERVER_RECYCLE_INTERVAL_SECONDS` | `0` (disabled) | Periodically restart the container to keep memory usage steady over long uptimes. Set to e.g. `3600` for hourly recycling. Minimum value is 60 seconds. |
-
-### Periodic recycling
-
-LibreOffice can slowly grow its memory footprint over many conversions. Setting `UNOSERVER_RECYCLE_INTERVAL_SECONDS` makes each container restart itself on a schedule, keeping memory usage steady.
-
-The restart takes a few seconds. During that window any request routed to that container is automatically retried by Stirling PDF, so user-facing requests still complete normally. If you run several containers, their startups will drift apart naturally so they don't all recycle at the same moment.
+| `UNOSERVER_PORT` | `2003` | Listen port. |
+| `UNOSERVER_INTERFACE` | `0.0.0.0` | Listen address; use `127.0.0.1` to restrict to the same host. |
+| `UNOSERVER_CONVERSION_TIMEOUT` | `1800` (s) | Max time per conversion. Set ≥ `libreOfficeTimeoutMinutes`. |
+| `UNOSERVER_RECYCLE_INTERVAL_SECONDS` | `0` (off) | Periodic restart to bound LibreOffice memory growth. Minimum 60 s; e.g. `3600` for hourly. |
-For steady production traffic, an hourly or once-a-day recycle is usually plenty. For lighter workloads or short-lived deployments you can leave it disabled.
+### CJK fonts
-:::info Run multiple instances
-A single container is one worker. To run four workers, declare four services in your compose file (`unoserver1` through `unoserver4`) using the same image, and list all four endpoints in the Stirling PDF configuration.
-:::
+The default image covers European languages with hyphenation for EN/FR/DE/ES/IT/PT/NL/PL/RU. For Chinese/Japanese/Korean, rebuild with `--build-arg INSTALL_CJK_FONTS=true` (~120 MB extra).
-### Asian-language fonts
+### Multiple workers
-The default image includes broad European-language coverage including hyphenation for English, French, German, Spanish, Italian, Portuguese, Dutch, Polish, and Russian. If you need Chinese, Japanese, or Korean conversion support you'll need a custom variant of the image with CJK fonts added. Contact us or open a GitHub issue and we can publish one.
+One container is one worker. To run four, declare four services using the same image and list all four endpoints in Stirling PDF's configuration.
---
@@ -235,13 +221,9 @@ If conversions are consistently timing out, this usually indicates the system is
## Host resource requirements
-When sizing a host for office conversion, plan for the following:
-
-**Memory.** Each LibreOffice worker uses around 70 MB of RAM when idle, climbing to 140 to 250 MB during active conversion depending on the document. Multiply by your worker count and add headroom for the operating system, the Stirling PDF application itself, and any other services on the host. If memory runs out, the OS will start killing processes and conversions will fail.
-
-**CPU.** Each conversion uses one CPU core at 100% for its duration, regardless of how many cores the host has. A reasonable starting point is one worker per two CPU cores; increase from there if you see queues building up.
-
-**Storage.** Uploaded files are written to temporary disk space at `/tmp/stirling-pdf` while they're being converted. Allow free space of roughly `2 × your maximum upload size × number of concurrent uploads`. On hosts with a small `/tmp` partition (some VPS providers default to 1 or 2 GB) mount a larger volume:
+- **Memory** — ~70 MB idle, 140–250 MB during conversion, per worker. Add headroom for the OS and Stirling PDF itself.
+- **CPU** — one core pinned per active conversion. Start with one worker per two cores.
+- **Storage** — `/tmp/stirling-pdf` holds files mid-conversion. Allow roughly `2 × max upload × concurrent uploads`. On small `/tmp` partitions, mount a volume:
```yaml
services:
@@ -256,18 +238,16 @@ volumes:
## Worked example: 4 remote workers
-A reasonable starting point for a small team or trial deployment is one Stirling PDF instance plus four `stirling-unoserver` containers on the same host, with the conversion pool capped at 4. This caps memory predictably and lets all four conversions run truly in parallel:
+One Stirling PDF instance, four `stirling-unoserver` containers, pool capped at 4:
```yaml
services:
stirling-pdf:
image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
- ports:
- - "8080:8080"
+ ports: ["8080:8080"]
environment:
PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "4"
- PROCESS_EXECUTOR_TIMEOUT_MINUTES_LIBRE_OFFICETIMEOUT_MINUTES: "5"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT: "2003"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION: "remote"
@@ -280,11 +260,7 @@ services:
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST: "unoserver4"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_PORT: "2003"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST_LOCATION: "remote"
- depends_on:
- unoserver1: { condition: service_started }
- unoserver2: { condition: service_started }
- unoserver3: { condition: service_started }
- unoserver4: { condition: service_started }
+ depends_on: [unoserver1, unoserver2, unoserver3, unoserver4]
unoserver1: &uno
image: ghcr.io/stirling-tools/stirling-unoserver:latest
@@ -299,14 +275,7 @@ services:
unoserver4: { <<: *uno }
```
-Stirling PDF distributes incoming conversions evenly across all configured workers. Extra requests above the worker count simply queue and wait for a free slot. The system stays stable under high concurrency. The practical limits you'll hit, in order, are:
-
-1. Per-conversion time on heavy documents (a complex PPTX or large spreadsheet can take tens of seconds, which lowers your effective throughput regardless of worker count)
-2. Host CPU saturation
-3. Free `/tmp` disk space if many large uploads queue at once
-4. Stirling PDF's `libreOfficeTimeoutMinutes` for any single request that waits too long
-
-If your workload is mostly heavy documents, run more workers with smaller per-worker memory limits rather than fewer larger ones. That gives you better parallelism per dollar of RAM.
+Conversions distribute evenly across workers; excess queue. Bottlenecks in order: heavy-document conversion time → host CPU → `/tmp` space → `libreOfficeTimeoutMinutes`.
---
diff --git a/docs/Configuration/Performance-Optimization.md b/docs/Configuration/Performance-Optimization.md
index 2a7ef01d..1bd71901 100644
--- a/docs/Configuration/Performance-Optimization.md
+++ b/docs/Configuration/Performance-Optimization.md
@@ -146,7 +146,7 @@ Some operations require significantly more resources than others. If your organi
|---|---|---|---|
| Merge / Split | Low | Proportional to total file sizes | Lightweight file operations |
| OCR (Tesseract) | Very High | High | CPU-bound image analysis |
-| File Conversion (LibreOffice) | High | High | Single-threaded per instance. Scales by running multiple instances. Per-conversion time varies widely with document complexity and host hardware. See [LibreOffice Parallel Processing](./LibreOffice-Parallel-Processing.md). |
+| File Conversion (LibreOffice) | High | High | Single-threaded per instance — see [LibreOffice Parallel Processing](./LibreOffice-Parallel-Processing.md) to scale. |
| PDF-to-Image | Moderate | Very High | Page rendering expands memory significantly |
| PDF/A Conversion | Moderate | High | Font embedding and color profiles |
| Compression | Moderate | High | Rewriting internal PDF structures |
From f6853a56eb05dec36a2532ec326a151afec5b57e Mon Sep 17 00:00:00 2001
From: a
Date: Tue, 12 May 2026 14:39:01 +0100
Subject: [PATCH 3/7] Replace em-dashes with hyphens
---
.../LibreOffice-Parallel-Processing.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index 3919fc26..5d237414 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -55,7 +55,7 @@ The default `libreOfficeSessionLimit` is `1`, meaning only one conversion runs a
### Throughput expectations
-Per-conversion time varies from sub-second (small DOCX) to tens of seconds (complex PPTX, large spreadsheets). Pool throughput scales roughly linearly with worker count up to host CPU saturation — benchmark a representative document before sizing.
+Per-conversion time varies from sub-second (small DOCX) to tens of seconds (complex PPTX, large spreadsheets). Pool throughput scales roughly linearly with worker count up to host CPU saturation - benchmark a representative document before sizing.
---
@@ -157,7 +157,7 @@ Use `remote` when running UNO servers in separate Docker containers, even if the
| `:alpha` | Pre-release testing |
| `:1.0.0`, `:1.0.1`, … | Pinned version |
-The image is versioned independently from Stirling PDF — pin a version and update it on its own cadence. Compatibility breaks are called out in release notes.
+The image is versioned independently from Stirling PDF - pin a version and update it on its own cadence. Compatibility breaks are called out in release notes.
### Configuration
@@ -221,9 +221,9 @@ If conversions are consistently timing out, this usually indicates the system is
## Host resource requirements
-- **Memory** — ~70 MB idle, 140–250 MB during conversion, per worker. Add headroom for the OS and Stirling PDF itself.
-- **CPU** — one core pinned per active conversion. Start with one worker per two cores.
-- **Storage** — `/tmp/stirling-pdf` holds files mid-conversion. Allow roughly `2 × max upload × concurrent uploads`. On small `/tmp` partitions, mount a volume:
+- **Memory** - ~70 MB idle, 140–250 MB during conversion, per worker. Add headroom for the OS and Stirling PDF itself.
+- **CPU** - one core pinned per active conversion. Start with one worker per two cores.
+- **Storage** - `/tmp/stirling-pdf` holds files mid-conversion. Allow roughly `2 × max upload × concurrent uploads`. On small `/tmp` partitions, mount a volume:
```yaml
services:
@@ -281,6 +281,6 @@ Conversions distribute evenly across workers; excess queue. Bottlenecks in order
## Related
-- [Process Limits](./Process-Limits.md) — Configure session limits and timeouts for all external tools
-- [Production Deployment Guide](../Server-Admin-Onboarding.md) — Sizing recommendations for different workloads
-- [Diagnostics](./Diagnostics.md) — Collect system and application diagnostics for troubleshooting
+- [Process Limits](./Process-Limits.md) - Configure session limits and timeouts for all external tools
+- [Production Deployment Guide](../Server-Admin-Onboarding.md) - Sizing recommendations for different workloads
+- [Diagnostics](./Diagnostics.md) - Collect system and application diagnostics for troubleshooting
From 96fd141c3e3734c7db7171fe035b3fdefe085ec2 Mon Sep 17 00:00:00 2001
From: a
Date: Tue, 12 May 2026 15:16:34 +0100
Subject: [PATCH 4/7] Restructure multi-unoserver guidance
- Drop Storage bullet (generic Stirling-PDF advice, not LibreOffice-specific).
- Drop redundant "Multiple workers" stub under the image section.
- Replace 4-worker worked example with 3-worker "Running multiple unoservers"
section with Compose and docker run tabs, plus explicit instructions for
adding more workers.
---
.../LibreOffice-Parallel-Processing.md | 129 +++++++++++-------
1 file changed, 76 insertions(+), 53 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index 5d237414..5d281181 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -172,10 +172,6 @@ The image is versioned independently from Stirling PDF - pin a version and updat
The default image covers European languages with hyphenation for EN/FR/DE/ES/IT/PT/NL/PL/RU. For Chinese/Japanese/Korean, rebuild with `--build-arg INSTALL_CJK_FONTS=true` (~120 MB extra).
-### Multiple workers
-
-One container is one worker. To run four, declare four services using the same image and list all four endpoints in Stirling PDF's configuration.
-
---
## Running UNO Servers Without Docker
@@ -223,59 +219,86 @@ If conversions are consistently timing out, this usually indicates the system is
- **Memory** - ~70 MB idle, 140–250 MB during conversion, per worker. Add headroom for the OS and Stirling PDF itself.
- **CPU** - one core pinned per active conversion. Start with one worker per two cores.
-- **Storage** - `/tmp/stirling-pdf` holds files mid-conversion. Allow roughly `2 × max upload × concurrent uploads`. On small `/tmp` partitions, mount a volume:
-
-```yaml
-services:
- stirling-pdf:
- volumes:
- - stirling-tmp:/tmp/stirling-pdf
-volumes:
- stirling-tmp: {}
-```
---
-## Worked example: 4 remote workers
-
-One Stirling PDF instance, four `stirling-unoserver` containers, pool capped at 4:
-
-```yaml
-services:
- stirling-pdf:
- image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
- ports: ["8080:8080"]
- environment:
- PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
- PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "4"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION: "remote"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST: "unoserver2"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION: "remote"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST: "unoserver3"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION: "remote"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST: "unoserver4"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST_LOCATION: "remote"
- depends_on: [unoserver1, unoserver2, unoserver3, unoserver4]
-
- unoserver1: &uno
- image: ghcr.io/stirling-tools/stirling-unoserver:latest
- environment:
- UNOSERVER_RECYCLE_INTERVAL_SECONDS: "3600"
- deploy:
- resources:
- limits: { cpus: "1.0", memory: 1g }
- restart: on-failure:5
- unoserver2: { <<: *uno }
- unoserver3: { <<: *uno }
- unoserver4: { <<: *uno }
-```
+## Running multiple unoservers on one host
+
+Each `stirling-unoserver` container is one worker. To scale, run more containers on the same host and list each as an endpoint in Stirling PDF. The example below runs three workers with hourly recycling and a 1 GB per-worker memory cap:
+
+
+
+ ```yaml
+ services:
+ stirling-pdf:
+ image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
+ ports: ["8080:8080"]
+ environment:
+ PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
+ PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "3"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION: "remote"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST: "unoserver2"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION: "remote"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST: "unoserver3"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT: "2003"
+ PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION: "remote"
+ depends_on: [unoserver1, unoserver2, unoserver3]
+
+ unoserver1: &uno
+ image: ghcr.io/stirling-tools/stirling-unoserver:latest
+ environment:
+ UNOSERVER_RECYCLE_INTERVAL_SECONDS: "3600"
+ deploy:
+ resources:
+ limits: { cpus: "1.0", memory: 1g }
+ restart: on-failure:5
+ unoserver2: { <<: *uno }
+ unoserver3: { <<: *uno }
+ ```
+
+
+ ```bash
+ docker network create stirling-net
+
+ # Three unoserver workers on the shared network
+ for i in 1 2 3; do
+ docker run -d --name unoserver$i --network stirling-net \
+ -e UNOSERVER_RECYCLE_INTERVAL_SECONDS=3600 \
+ --memory 1g --cpus 1.0 --restart on-failure:5 \
+ ghcr.io/stirling-tools/stirling-unoserver:latest
+ done
+
+ # Stirling PDF pointed at all three
+ docker run -d --name stirling-pdf --network stirling-net -p 8080:8080 \
+ -e PROCESS_EXECUTOR_AUTO_UNO_SERVER=false \
+ -e PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT=3 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST=unoserver1 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT=2003 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION=remote \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST=unoserver2 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT=2003 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION=remote \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST=unoserver3 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT=2003 \
+ -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION=remote \
+ docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
+ ```
+
+
+
+### Adding more workers
+
+To grow the pool from three to four:
+
+1. Start a fourth `unoserver4` container using the same image.
+2. Add a fourth endpoint to Stirling PDF (`PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST`, `_PORT`, `_HOST_LOCATION`).
+3. Bump `PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT` to `4` so the pool actually uses the new endpoint.
+4. Restart Stirling PDF to pick up the new endpoint list.
-Conversions distribute evenly across workers; excess queue. Bottlenecks in order: heavy-document conversion time → host CPU → `/tmp` space → `libreOfficeTimeoutMinutes`.
+Each conversion pins one CPU core, so don't run more workers than the host has cores available.
---
From 2f55eb30c406b5c895a3e9b0f9756f40cbaead43 Mon Sep 17 00:00:00 2001
From: a
Date: Tue, 12 May 2026 15:29:30 +0100
Subject: [PATCH 5/7] Split startup and connect docs for remote unoservers
Move the unoserver service definitions out of the "Remote UNO Server
Endpoints" section (which is about pointing Stirling PDF at endpoints)
into a new "Starting Remote unoserver Containers" section that comes
first. Keeps each section focused on one concern.
---
.../LibreOffice-Parallel-Processing.md | 53 +++++++++++++------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index 5d281181..47925099 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -59,11 +59,44 @@ Per-conversion time varies from sub-second (small DOCX) to tens of seconds (comp
---
-## Remote UNO Server Endpoints
+## Starting Remote unoserver Containers
+
+Before configuring Stirling PDF to connect to remote endpoints, you need one or more `stirling-unoserver` containers running. Each container is a single worker that listens internally on port `2003`. Expose it on a different host port per instance if you want to reach them from outside Docker or from another host.
+
+
+
+ ```yaml
+ services:
+ unoserver1:
+ image: ghcr.io/stirling-tools/stirling-unoserver:latest
+ ports:
+ - "2003:2003"
+
+ unoserver2:
+ image: ghcr.io/stirling-tools/stirling-unoserver:latest
+ ports:
+ - "2004:2003"
+ ```
+ Add these alongside your `stirling-pdf` service. Host-port mappings are only required if Stirling PDF runs outside Docker, on a different host, or on a separate Docker network.
+
+
+ ```bash
+ docker run -d --name unoserver1 -p 2003:2003 \
+ ghcr.io/stirling-tools/stirling-unoserver:latest
+
+ docker run -d --name unoserver2 -p 2004:2003 \
+ ghcr.io/stirling-tools/stirling-unoserver:latest
+ ```
+
+
-For larger deployments or when you want to isolate LibreOffice from the main application, you can run UNO servers as separate containers and configure Stirling PDF to connect to them remotely.
+For tunable options (timeouts, periodic recycling, CJK fonts), see [The `stirling-unoserver` Image](#the-stirling-unoserver-image) below. For a fuller multi-worker layout with resource limits and recycling, see [Running multiple unoservers on one host](#running-multiple-unoservers-on-one-host).
-Set `autoUnoServer` to `false` and define your remote endpoints:
+---
+
+## Remote UNO Server Endpoints
+
+Once your unoserver containers are running, set `autoUnoServer` to `false` and point Stirling PDF at them:
@@ -103,6 +136,8 @@ Set `autoUnoServer` to `false` and define your remote endpoints:
services:
stirling-pdf:
image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
+ ports:
+ - "8080:8080"
environment:
PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
@@ -111,18 +146,6 @@ Set `autoUnoServer` to `false` and define your remote endpoints:
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST: "unoserver2"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT: "2003"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION: "remote"
- ports:
- - "8080:8080"
-
- unoserver1:
- image: ghcr.io/stirling-tools/stirling-unoserver:latest
- ports:
- - "2003:2003"
-
- unoserver2:
- image: ghcr.io/stirling-tools/stirling-unoserver:latest
- ports:
- - "2004:2003"
```
From 5e3e35d28a724e639a5dff6badcbb782648fc1c5 Mon Sep 17 00:00:00 2001
From: a
Date: Tue, 12 May 2026 15:33:04 +0100
Subject: [PATCH 6/7] Group Remote unoserver subsections under one parent
Wrap "Starting unoserver Containers" and "Connecting Stirling PDF to
Remote Endpoints" as H3 subsections under a single "Remote unoservers"
H2 parent. Demote "Endpoint Configuration" to H4 under Connecting.
Replace remaining em-dash in Performance-Optimization.md.
---
.../LibreOffice-Parallel-Processing.md | 14 ++++++++------
docs/Configuration/Performance-Optimization.md | 2 +-
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index 47925099..e5af90ef 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -59,9 +59,13 @@ Per-conversion time varies from sub-second (small DOCX) to tens of seconds (comp
---
-## Starting Remote unoserver Containers
+## Remote unoservers
-Before configuring Stirling PDF to connect to remote endpoints, you need one or more `stirling-unoserver` containers running. Each container is a single worker that listens internally on port `2003`. Expose it on a different host port per instance if you want to reach them from outside Docker or from another host.
+For larger deployments, or when you want to isolate LibreOffice from the main application, run UNO servers as separate containers and configure Stirling PDF to connect to them remotely. This is a two-step setup: start the unoserver containers, then point Stirling PDF at them.
+
+### Starting unoserver Containers
+
+Each container is a single worker that listens internally on port `2003`. Expose it on a different host port per instance if you want to reach them from outside Docker or from another host.
@@ -92,9 +96,7 @@ Before configuring Stirling PDF to connect to remote endpoints, you need one or
For tunable options (timeouts, periodic recycling, CJK fonts), see [The `stirling-unoserver` Image](#the-stirling-unoserver-image) below. For a fuller multi-worker layout with resource limits and recycling, see [Running multiple unoservers on one host](#running-multiple-unoservers-on-one-host).
----
-
-## Remote UNO Server Endpoints
+### Connecting Stirling PDF to Remote Endpoints
Once your unoserver containers are running, set `autoUnoServer` to `false` and point Stirling PDF at them:
@@ -152,7 +154,7 @@ Once your unoserver containers are running, set `autoUnoServer` to `false` and p
To add more endpoints, add additional entries to the `unoServerEndpoints` list in settings.yml, or for environment variables, increment the index number (e.g. `_0_` for the first, `_1_` for the second, `_2_` for the third, and so on).
-### Endpoint Configuration
+#### Endpoint Configuration
The `host` field accepts a Docker service name (e.g. `unoserver1`), a DNS hostname (e.g. `uno.internal.example.com`), or an IP address (e.g. `192.168.1.50`). The default is `127.0.0.1`.
diff --git a/docs/Configuration/Performance-Optimization.md b/docs/Configuration/Performance-Optimization.md
index 1bd71901..320e19e5 100644
--- a/docs/Configuration/Performance-Optimization.md
+++ b/docs/Configuration/Performance-Optimization.md
@@ -146,7 +146,7 @@ Some operations require significantly more resources than others. If your organi
|---|---|---|---|
| Merge / Split | Low | Proportional to total file sizes | Lightweight file operations |
| OCR (Tesseract) | Very High | High | CPU-bound image analysis |
-| File Conversion (LibreOffice) | High | High | Single-threaded per instance — see [LibreOffice Parallel Processing](./LibreOffice-Parallel-Processing.md) to scale. |
+| File Conversion (LibreOffice) | High | High | Single-threaded per instance - see [LibreOffice Parallel Processing](./LibreOffice-Parallel-Processing.md) to scale. |
| PDF-to-Image | Moderate | Very High | Page rendering expands memory significantly |
| PDF/A Conversion | Moderate | High | Font embedding and color profiles |
| Compression | Moderate | High | Rewriting internal PDF structures |
From 43d490ec4061bab98b5517527610edb6c49f909e Mon Sep 17 00:00:00 2001
From: a
Date: Tue, 12 May 2026 15:37:29 +0100
Subject: [PATCH 7/7] Drop redundant "Running multiple unoservers" section
The Starting and Connecting subsections under "Remote unoservers" already
cover the multi-worker case. Fold the one genuinely new bit (matching
libreOfficeSessionLimit to endpoint count) into Connecting as a tip and
remove the now-orphaned forward link.
---
.../LibreOffice-Parallel-Processing.md | 86 ++-----------------
1 file changed, 5 insertions(+), 81 deletions(-)
diff --git a/docs/Configuration/LibreOffice-Parallel-Processing.md b/docs/Configuration/LibreOffice-Parallel-Processing.md
index e5af90ef..83af9e0e 100644
--- a/docs/Configuration/LibreOffice-Parallel-Processing.md
+++ b/docs/Configuration/LibreOffice-Parallel-Processing.md
@@ -94,7 +94,7 @@ Each container is a single worker that listens internally on port `2003`. Expose
-For tunable options (timeouts, periodic recycling, CJK fonts), see [The `stirling-unoserver` Image](#the-stirling-unoserver-image) below. For a fuller multi-worker layout with resource limits and recycling, see [Running multiple unoservers on one host](#running-multiple-unoservers-on-one-host).
+For tunable options (timeouts, periodic recycling, CJK fonts), see [The `stirling-unoserver` Image](#the-stirling-unoserver-image) below.
### Connecting Stirling PDF to Remote Endpoints
@@ -154,6 +154,10 @@ Once your unoserver containers are running, set `autoUnoServer` to `false` and p
To add more endpoints, add additional entries to the `unoServerEndpoints` list in settings.yml, or for environment variables, increment the index number (e.g. `_0_` for the first, `_1_` for the second, `_2_` for the third, and so on).
+:::tip
+Set `libreOfficeSessionLimit` to match your endpoint count so the pool uses all of them concurrently. With 3 endpoints and a session limit of 1, you'll only ever use one at a time.
+:::
+
#### Endpoint Configuration
The `host` field accepts a Docker service name (e.g. `unoserver1`), a DNS hostname (e.g. `uno.internal.example.com`), or an IP address (e.g. `192.168.1.50`). The default is `127.0.0.1`.
@@ -247,86 +251,6 @@ If conversions are consistently timing out, this usually indicates the system is
---
-## Running multiple unoservers on one host
-
-Each `stirling-unoserver` container is one worker. To scale, run more containers on the same host and list each as an endpoint in Stirling PDF. The example below runs three workers with hourly recycling and a 1 GB per-worker memory cap:
-
-
-
- ```yaml
- services:
- stirling-pdf:
- image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
- ports: ["8080:8080"]
- environment:
- PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
- PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "3"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION: "remote"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST: "unoserver2"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION: "remote"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST: "unoserver3"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT: "2003"
- PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION: "remote"
- depends_on: [unoserver1, unoserver2, unoserver3]
-
- unoserver1: &uno
- image: ghcr.io/stirling-tools/stirling-unoserver:latest
- environment:
- UNOSERVER_RECYCLE_INTERVAL_SECONDS: "3600"
- deploy:
- resources:
- limits: { cpus: "1.0", memory: 1g }
- restart: on-failure:5
- unoserver2: { <<: *uno }
- unoserver3: { <<: *uno }
- ```
-
-
- ```bash
- docker network create stirling-net
-
- # Three unoserver workers on the shared network
- for i in 1 2 3; do
- docker run -d --name unoserver$i --network stirling-net \
- -e UNOSERVER_RECYCLE_INTERVAL_SECONDS=3600 \
- --memory 1g --cpus 1.0 --restart on-failure:5 \
- ghcr.io/stirling-tools/stirling-unoserver:latest
- done
-
- # Stirling PDF pointed at all three
- docker run -d --name stirling-pdf --network stirling-net -p 8080:8080 \
- -e PROCESS_EXECUTOR_AUTO_UNO_SERVER=false \
- -e PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT=3 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST=unoserver1 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT=2003 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION=remote \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST=unoserver2 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT=2003 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION=remote \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST=unoserver3 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT=2003 \
- -e PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION=remote \
- docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
- ```
-
-
-
-### Adding more workers
-
-To grow the pool from three to four:
-
-1. Start a fourth `unoserver4` container using the same image.
-2. Add a fourth endpoint to Stirling PDF (`PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_3_HOST`, `_PORT`, `_HOST_LOCATION`).
-3. Bump `PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT` to `4` so the pool actually uses the new endpoint.
-4. Restart Stirling PDF to pick up the new endpoint list.
-
-Each conversion pins one CPU core, so don't run more workers than the host has cores available.
-
----
-
## Related
- [Process Limits](./Process-Limits.md) - Configure session limits and timeouts for all external tools