Nothing hits the disk
Uploaded bytes live in memory while they are parsed and are gone when the request ends. The services run with a read-only root filesystem, so a document cannot be spooled to a temp file even by accident.
gRPC document parsers
Four gRPC services that read the formats real document pipelines run into: PDFs and scanned images, Word and PowerPoint and their OpenDocument cousins, and spreadsheets in every Excel flavour. Each one wraps a mature parsing engine and speaks the same protobuf contract, so a caller talks to all four the same way.
Rather than force every format through one engine, each service wraps the library that already handles its format well and exposes it over gRPC. The formats decide which engine you reach for. The wire contract stays the same.
| Service | Handles | Engine | Built in | Port |
|---|---|---|---|---|
| gRParse | PDF pages and raster images, with OCR, layout, tables, and reading order | RapidOCR and PicoDet through ONNX Runtime | C++ GPU | 50051 |
| grPOIc | Word, Excel, and PowerPoint content and metadata, modern and legacy | Apache POI | Java | 50052 |
| grpc-libreoffice | Office documents rendered to PNG pages or PDF, plus wide typed extraction | LibreOfficeKit and the UNO SDK | C++ | 50053 |
| grpc-calamine | Excel and OpenDocument workbooks, streamed cell by cell | calamine | Rust | 50054 |
gRParse covers the scanned and image side. The other three cover documents that already carry their structure, so nothing has to be flattened to an image and read back with OCR unless it truly is one.
The four services were built to a shared set of rules, so learning one teaches you most of the next.
Uploaded bytes live in memory while they are parsed and are gone when the request ends. The services run with a read-only root filesystem, so a document cannot be spooled to a temp file even by accident.
A client uploads in chunks and reads structure back as the parser produces it, one page or row or event at a time. A slow reader slows the parser through backpressure instead of forcing the whole document into memory.
Oversized uploads are refused with a clear status rather than an out-of-memory crash. Each service caps how many documents it works on at once, reports the engine version it wraps, and registers gRPC health and reflection.
gRParse is more than the OCR service. It is also a coordinator. Hand it a mixed document and it routes each part to the right collector, does the computer-vision work itself, and sends office documents to LibreOffice for rendering. The pieces come back merged into one result, and if one collector fails the rest still return.
The routing never converts an office file to PDF just to read it. Native formats go to the collector that understands them, and only real images take the OCR path.
The services share the same protobuf document schema, the one the Docling project uses, so their output composes.
Whichever service reads a file, the structure it emits lands in the same shape: text with its position on the page, tables with real cells, headings and reading order, and the offsets that let an annotation point back to exactly where it came from. A pipeline can mix parsers without translating between four different notions of what a document is.
That shared model is also why gRParse can act as a coordinator at all. A collector's output is already in the coordinator's own vocabulary, so merging is addition rather than conversion.
Every service is open source with its protobuf contract in the repo, an end-to-end test suite, and a container image. Pick the one that matches your format, or start with the service page to see the RPCs and the streaming model up close.