All posts
·8 min read

Scaling an ERP with Laravel queues

How we moved month-end close from a 2-day spreadsheet marathon to a 4-hour, queue-driven job.

LaravelERPQueuesPostgreSQL

The problem When we first shipped the ERP, month-end close meant a finance lead spent two full days reconciling spreadsheets against the live ledger. The system was correct — it was just synchronous, and every month-end report ran on the request thread.

What we changed We pushed every long-running job onto a Redis-backed queue: payroll runs, depreciation, recurring journals, PDF report generation, and period-close itself. The web request became a lightweight "kick off a job and show a progress card" handler.

The data model bit The real unlock wasn't the queues — it was period locking. Once a month is closed, no entry can mutate that period silently. That meant we could safely cache report aggregates and trust them.

Outcome Close time dropped from two days to four hours, and the finance team stopped fearing the last day of the month.