Case study
Investor reporting at a UK investment fund: a 25-worker batch PDF pipeline
The situation
A UK investment fund with a recurring, unforgiving job: generating branded financial statements for investors against structured fund data, on a legacy PHP stack, on a schedule that doesn't move. Reporting cycles in finance are a hard deadline. When statements are due, they're due.
This is also the kind of system nobody wants to own. It's legacy, it's batch, and it only gets noticed when it breaks. I ran it, extended it, and made it boring in the best sense: it produced what it needed to produce, every cycle.
What I built
A batch PDF processing system running on Azure, scaling to 25 concurrent workers per run. Each worker renders branded statement documents against structured fund data, and Ghostscript handles the PDF merge stage to assemble final outputs. The stack underneath is PHP 7 on a Zend codebase, which meant working with the grain of a mature system rather than rewriting it.
That last point mattered. The codebase spanned Zend 1 and Zend 2, and the right engineering call was to maintain and extend it carefully: tightening the batch orchestration, making worker failures recoverable mid-run, and keeping throughput predictable as the document volume grew with the fund. I also brought the local and deployment story up to date with Docker, multi-stage builds for the legacy PHP app so the system could be developed and shipped consistently.
The outcome
A reporting pipeline that holds its schedule. Statement runs that load 25 workers complete predictably, failed documents can be retried without restarting a cycle, and the fund's operations team gets branded, accurate investor statements out of structured data without manual assembly.
For companies sitting on legacy PHP that runs the actual business, this is the realistic path: senior hands that respect the existing system, modernise the parts that hurt, and keep the lights on the entire time.
“Legacy systems run real businesses. The job is to make them dependable, and you do that by understanding them before you change them.”
Built with: PHP 7, Zend Framework, Azure, Ghostscript, Docker.