New release: November 2026

On your server

Self-hosted OCR API: installation guide for a GPU server

After this page the OCR API runs on your own Linux server with an NVIDIA card and has read your first page. From then on your pages stay on the server, on-premise and offline once the models are fetched, so no outside service sees them. A start check tells you which pipelines your card carries. The model weights come from pinned, SHA-256-checked sources; ocr-fetch-models.sh --list prints every source before anything is downloaded.

The whole install, as run in the steps below (the file name and folder come with the package):

sha256sum -c ocr-software-2026.11.11-352765c-linux-amd64.tar.gz.sha256 && tar -xzf ocr-software-2026.11.11-352765c-linux-amd64.tar.gz && cd ocr-software-2026.11.11-352765c-linux-amd64
sudo ./install.sh
sudo /opt/ocr/current/deploy/ocr-fetch-models.sh
sudo /opt/ocr/current/install.sh --start --pipeline scan-ctc@2
sudo /opt/ocr/bin/ocrctl key new -id mykey -paid -keys /etc/ocr/keys.txt

Then the first call.

A client sends a page to the API service on your server. A queue passes it to the worker on the GPU, which runs the pipeline you chose, a row of steps. The result comes back as JSON, text, hOCR or PDF. The documents stay inside your server. A client sends a page to the API service on your server. A queue passes it to the worker on the GPU, which runs the pipeline you chose, a row of steps. The result comes back as JSON, text, hOCR or PDF. The documents stay inside your server.
The path of a page: everything inside the frame runs on your server.

Download the OCR software package and verify its SHA-256

File ocr-software-2026.11.11-352765c-linux-amd64.tar.gz
Version 2026.11.11-352765c
Size 14.7 MB
SHA-256 ff9bdfb2812ba2c5ed038ecf2a7a09f07aaaed60f9e47ab9d77db278b7648ea7
Checksum file ocr-software-2026.11.11-352765c-linux-amd64.tar.gz.sha256
Terms EULA

Download ocr-software-2026.11.11-352765c-linux-amd64.tar.gz

The release contains the API service ocrd, the key tool ocrctl, the installer with update and rollback, and the pipelines, from everyday scans to tables and the hardest pages. The model weights are fetched in step 4. Release notes ยท Everything in the package

Put the checksum file in the same folder as the package and check the package before you unpack it: sha256sum -c ocr-software-2026.11.11-352765c-linux-amd64.tar.gz.sha256. The installer checks every file inside once more. Licence terms: EULA. Private use and tests are free; for productive use in a company, or to run it for others, ask for a contract.

Which NVIDIA GPU does the OCR server need? Cards per pipeline

The start check tells you which pipelines your card carries: the fast reading pipelines from compute capability 7.5 (GTX 16xx, RTX 20xx) with 8,192 MiB of video memory free, and the language-model pipeline from 8.0 (RTX 30 series and newer) with 17,920 MiB free. A GTX 10xx (compute capability 6.1) is below the limit of every pipeline.

The language-model pipeline reads a page with a language model and with a character OCR engine and compares both. That needs video memory: an NVIDIA card with compute capability 8.0 or higher (RTX 30 series and newer), driver 580 or newer and at least 17.5 GiB (17,920 MiB) of video memory free. Measured on an NVIDIA RTX PRO 4500 Blackwell with 32 GB.

Find your own numbers first. Run this on the server:

nvidia-smi --query-gpu=name,compute_cap,memory.free,driver_version --format=csv

The columns are the card, its compute capability, the video memory that is free right now, and the driver. Free means free: a desktop session or another program holding the card lowers it. Compare with the table; the start command in step 5 reads the same numbers from the card and compares them with the limits of the pipeline.

Card Compute capability What it carries
GTX 10xx (Pascal), including Titan X 6.1 No pipeline: the start check stops below 7.5, and the engines of the language-model pipeline need 7.5 or higher
GTX 16xx, RTX 20xx (Turing), including Titan RTX 7.5 The fast pipelines with 8,192 MiB free
RTX 30xx, 40xx, 50xx with less than 17.5 GiB free, for example RTX 3050, 3060, 3070, 4060, 4080, 5080 8.6 and up The fast pipelines with 8,192 MiB free
RTX 30xx, 40xx, 50xx with 17.5 GiB or more free, for example RTX 3090, 4090, 5090 8.6 and up All pipelines pass the check; for the language-model pipeline the start command works out the memory of the language model from the free memory
Datacenter cards (A10, A100, L4, L40S, H100) 8.0 and up Decided by the same numbers
NVIDIA RTX PRO 4500 Blackwell 12.0 The language-model pipeline with 32 GB, test card

The start command in step 5 checks compute capability, driver and free memory and stops with exit code 4 if one is too low; it says what your card does carry. Above the limit it works out how much memory the language model gets from the memory that is free on your card (the rule is in the file deploy/gpu-vlm.conf of the package) and prints "same memory size as the card we measured (only the RTX PRO 4500 Blackwell has run)" for every card within three percent of the test card (32,623 MiB), "not verified on this card size, it may fail to start or run out of memory" for the others. Only the first card (GPU 0) is checked and used, also on a server with several: the services run with CUDA_DEVICE_ORDER=PCI_BUS_ID and CUDA_VISIBLE_DEVICES=0, so the card that is checked is the card that is used.

  • The language-model process held 16,544 MiB on the 32 GB card, set to use half of it (own measurement, test GPU, 6 Nov 2026).

  • If the start fails or the language model runs out of memory, the command stops with exit code 6 and names the service; each service gets up to eleven minutes to start, then the API up to ten more, so this can take longer than eleven minutes. A failed start stops everything it began, ocrd too, so the services show as inactive and the reason is in the log. Read why with

    journalctl -u 'ocr*' --since '30 minutes ago' --no-pager
    

    (the log of all services of this package), close other programs that hold the card, and start again; the second start stops the package services first and measures again. If it fails again, send the card, the line "model sidecar: ..." and the log through the contact page.

  • The fast reading pipeline used 3.5 GB of video memory with one worker and 14.1 GB with four on the test card (own measurement, 5 Nov 2026); the start check asks for 8,192 MiB free.

GPU too small: what the start check reports

  • Before it installs anything, install.sh asks nvidia-smi -L. If no card answers, it stops with exit code 4 and starts nothing.
  • The start command (step 5) reads the compute capability, the free memory and the driver from nvidia-smi and compares them with the limits of the pipeline (file deploy/gpu-grenzen.tsv of the package). If one is below, it stops with exit code 4, names the number and the cards it does carry, and starts nothing. It also stops if the memory left for the language model is below its least. Only GPU 0 is read and used, also for foreign processes. A second start stops the services of this package that are running (only those, never a foreign process), waits five seconds and measures again (if the card has not freed its memory by then, the check stops with exit code 4 and "does not fit"); if the check then fails, the workers of this package no longer run; ocrd keeps running.
  • Before each service starts, a check stops it with a clear line in the log if another program already computes on GPU 0. It kills nothing; stop that program first.
  • If a page does not fit into memory anyway, it comes back as failed with an error code. It is never returned empty and never guessed. A failed page costs nothing.
  • Then start a pipeline from the table that your card passes (--pipeline), or use a bigger card. A card below compute capability 7.5, such as every GTX 10xx, passes none.

Driver and CUDA: NVIDIA driver 580 or newer with the open kernel module.

System requirements of the on-premise OCR server

Need What
System Linux x86_64 with systemd, root. Built for Ubuntu 22.04 (Ubuntu 24.04: see below); NVIDIA driver 580 or newer.
GPU NVIDIA with driver 580 or newer. Which card: see the table above.
Main memory Peak per page, measured on CPU: up to 3.6 GiB. The service unit limits itself to 8 GiB.
Disk Room for the model weights and the Python packages under /var/lib/ocr. Step 4 prints the weights (about 3,587 MiB, 3.5 GiB) and says the Python environments need several GiB more.
Packages python3.10 with venv and pip (not in the standard repositories of Ubuntu 24.04; install.sh checks it first and stops with exit code 7 if it is missing), poppler-utils, libgl1, libglib2.0-0, libgomp1, curl.
Internet For step 4 only.

On Ubuntu 24.04, step 3 (install.sh) stops with exit code 7 and installs nothing until python3.10 is installed, because step 4 needs it and 24.04 does not ship it; the message names the command. That command uses the deadsnakes package source (PPA). After it, install.sh runs through.

Install the OCR server and read your first page

Run these in the folder with the package. Steps 1 to 3 can be repeated without harm. Step 4 can be repeated after it has finished; if it was cut off, run it again with --rebuild (see step 4). Step 5 stops the services of this package that are running before it measures the card, so a running service is interrupted. Step 6 makes a new key every time.

  1. Check.

    sha256sum -c ocr-software-2026.11.11-352765c-linux-amd64.tar.gz.sha256
    

    Must print OK. If not, download again.

  2. Unpack.

    tar -xzf ocr-software-2026.11.11-352765c-linux-amd64.tar.gz
    

    and

    cd ocr-software-2026.11.11-352765c-linux-amd64
    
  3. Install.

    sudo ./install.sh
    

    First checks that python3.10 with the venv module exists; if not, it stops with exit code 7 and installs nothing (see "Install errors"). Then checks every file and installs. It listens on 127.0.0.1 only. On the first install add --listen 0.0.0.0:8080 to open it to your network; later runs keep your config.yaml and say so, then edit listen: in /etc/ocr/config.yaml.

  4. Fetch the models.

    sudo /opt/ocr/current/deploy/ocr-fetch-models.sh
    

    Shows source, licence and size, then asks "Fetch this now? [y/N]" each time you run it; without a terminal add --yes. The only step that downloads, several GiB of models. It fetches all environments of the package, also those the language-model pipeline does not need. If GPU 0 is below the limit of the language-model pipeline, this step prints a warning before it asks; it does not stop. Step 5 checks the card before it looks at the models. Check your card against the table above first: the warning points to it. With --list it only shows, and needs no root. If step 4 was cut off and the next run says "venv differs", an environment was left half built: run

    sudo /opt/ocr/current/deploy/ocr-fetch-models.sh --rebuild
    

    (the script prints this hint itself and exits with code 4). A finished step 4 is skipped on a second run.

  5. Start.

    sudo /opt/ocr/current/install.sh --start --pipeline scan-ctc@2
    

    Starts only the services this pipeline needs, after the card check above. Needs the models and a GPU; only GPU 0 is used. If the card is too small it starts nothing. If you start again, it first stops the services of this package that are running, and only those. It waits until the API answers; each service gets up to eleven minutes to start, then the API up to ten more, before an abort comes. If it stops earlier, it prints the reason and an exit code; the table under "Install errors" explains them. If a service does not start (exit code 6) or the language model runs out of memory on a 24 GB card, the start stops everything it began, so the services show as inactive; read why with

    journalctl -u 'ocr*' --since '30 minutes ago' --no-pager
    

    To see what runs after a good start:

    systemctl status 'ocr*' --no-pager
    
  6. Make a key.

    sudo /opt/ocr/bin/ocrctl key new -id mykey -paid -keys /etc/ocr/keys.txt
    

    The key is printed once. Keep it.

  7. Read a page. The calls below go to your own server, http://127.0.0.1:8080. The hosted API at https://api.ocr-software.com takes the same calls.

export OCR_KEY=<your key>
curl -s -X POST "http://127.0.0.1:8080/v1/jobs?pipeline=scan-ctc@2&formats=json" \
  -H "Authorization: Bearer $OCR_KEY" --data-binary @page.pdf

The answer names a job_id. Ask for the job until its state is done, then fetch the result (pipeline choice, reading the result, errors and retries: API guide):

JOB_ID=<the job_id from the answer>
curl -s "http://127.0.0.1:8080/v1/jobs/$JOB_ID" -H "Authorization: Bearer $OCR_KEY"
curl -s "http://127.0.0.1:8080/v1/jobs/$JOB_ID/result?format=json" -H "Authorization: Bearer $OCR_KEY" -o result.json

Each word in result.json carries its text, a confidence and where it came from. The format is described on the page about JSON output.

Step 3 installs to /opt/ocr/releases/<version>; the installer creates the configuration and the key file only if they are missing, so a second run never overwrites yours. Step 5 stops at the first problem and names the service. Check the API with

curl -s http://127.0.0.1:8080/healthz

Third-party software and model weights of the OCR package

Part Where from Licence Size
The API service ocrd, the key tool ocrctl, the pipelines, the worker code, the install script In the package The licence terms (see above); Go libraries under their own licences, listed in NOTICE 14.7 MB
Python packages of the workers You fetch them (step 4): pypi.org, download.pytorch.org, paddlepaddle.org.cn; pinned versions, every file hash-checked Their own, shown by step 4 Several GiB
Model weights: text, layout, tables, language model You fetch them (step 4): huggingface.co, pinned by commit, every file checked against a SHA-256 list Apache-2.0, MIT or CDLA-Permissive-2.0 per model, shown by step 4 Shown by step 4
NVIDIA driver, CUDA parts You install them NVIDIA Not part of the package
poppler (PDF to image) You install it from your distribution GPL, from your distribution Not part of the package

Before anything is downloaded, ocr-fetch-models.sh --list prints every source, licence, size and checksum, without root and without a connection.

The full list of licences is on the page third-party software; the licence texts of the Go libraries are in the file NOTICE inside the package.

Not in the package: model weights, NVIDIA parts, poppler and your keys. After the model step the package processes everything locally: on-premise and offline, with no mail and no alerts sent. Your documents stay on your server, inside your network.

OCR speed: seconds per page per pipeline

How fast each pipeline reads, in seconds per page and pages per second (multiply by 3,600 for pages per hour), with the run behind each figure, is in the speed table on the pipelines page. Your card and your pages will differ; measure a sample of your own.

More pages at a time make the language-model pipeline faster. Set it with scheduler.vlm_slots in the server config (default 8, at most 64). Read one page at a time, the output is the same after every restart; use a fast reading pipeline for identical bytes at any load.

Update and roll back the OCR server

  • Update. Unpack the new package and run sudo ./install.sh in it. The old release stays as previous (the last three are kept); your configuration, keys and models are kept. Run the first call of the API guide again afterwards as the acceptance. The database is at /var/lib/ocr/ocr.db; ocrctl backup copies it online and ocrctl restore puts it back with ocrd stopped. Keep that copy, /etc/ocr and the key file on another machine.
  • Roll back. sudo /opt/ocr/current/install.sh --rollback switches to the previous release in one command. If the services do not start with a new release, the installer goes back by itself.

Install troubleshooting: errors and exit codes

Its exit code tells you where to look; 0 means it worked.

Exit code Meaning What to do
2 Wrong option, for example a bad --listen; or step 4 without a terminal Use HOST:PORT with a port from 1 to 65535. ./install.sh --help shows the options. Step 4 without a terminal stops with "ERROR: not a terminal: add --yes to confirm the download": add --yes.
3 Wrong machine, not root, or no systemd Run as root on Linux x86_64 with systemd. Step 4 not run as root says "ERROR: run as root (sudo): the files are fetched as user ocr into /var/lib/ocr". Git Bash, MSYS and Cygwin are refused, because the release switch needs real symbolic links.
4 No GPU answers, the models are missing, or step 4 failed Check nvidia-smi -L shows a card, then run step 4 (ocr-fetch-models.sh) before --start. A card that is too small is covered under "Which NVIDIA GPU does the OCR server need?". If the model step stops with "venv differs", run it again with --rebuild (step 4). Step 4 before step 3 says "ERROR: user ocr does not exist: run install.sh first". If the download fails, step 4 ends with "ERROR: fetching the models failed (see above). Nothing runs on half-fetched models: fix the cause and run this again."; the cause is in the lines above it.
5 A file of the package is missing or differs Download it again and compare the .sha256 file. A file added or removed also stops the install. If the message says fetch/pins/models.tsv is missing, the package is not intact: download it again and check it (step 1). Step 4 says "ERROR: fetch/pins is incomplete: this is not an intact package": the same remedy.
6 A service did not start, or the install failed Read journalctl -u 'ocr*' --since '30 minutes ago' --no-pager; the message names the unit that failed. On a 24 GB card the language model may not fit: close other programs that use the card and run step 5 again. A failed start stops everything it began, ocrd too, so the units show as inactive and the log has the reason. A version is never overwritten: the same version with other content is refused.
7 python3.10 with the venv module is missing (install.sh, before anything is installed) Install it with the command in the message, then run install.sh again. The message reads, on stderr: "ERROR: python3.10 with the venv module is missing, but the model step (fetch/pins/models.tsv) builds its environments with it. Detected: <your system>. Install it, then run this again: <command>. Nothing was installed." On Ubuntu 22.04 the command is sudo apt install python3.10 python3.10-venv. On Ubuntu 24.04 it is sudo apt install software-properties-common && sudo add-apt-repository ppa:deadsnakes/ppa && sudo apt update && sudo apt install python3.10 python3.10-venv; the deadsnakes PPA is not tested. Other systems: your package manager (Debian and Ubuntu: python3.10 and python3.10-venv).
  • The API does not answer. Check

    curl -s http://127.0.0.1:8080/healthz
    

    the first start can take ten minutes.

  • No access from other machines. Default is localhost only, plain HTTP: put TLS or a firewall in front.

  • A new release does not start. The installer switches back by itself.

  • Not solved. Send the exit code and the log through the contact page.

OCR release notes: what changed in each version

Version What changed Your action
2026.11.11-352765c First version listed on this page. Install as described above.

Each later package adds a row here: version, what changed, and whether you need to do anything. An update keeps your configuration, keys and fetched models; if a version needs more than sudo ./install.sh, the row says so.

Support, managed server and custom OCR pipeline

Running it for third parties, support, maintenance or a fixed update promise come with a contract. Prices are on the pricing page.

Production use, high volume or your own server?

Private use and tests are free. For a company in production, a server of your own or a pipeline built on your pages, send the kind of page and the volume, and get a written offer, or a clear no when the fit is not there.

Ask for an offer