Laravel SaaS Rescue Case Studies
Four representative rescue engagements — abandoned handovers, silent queue failures, billing drift and stalled upgrades — with the diagnosis, the work done and how each was scoped.
Rescue work follows patterns. Below are four representative engagements, described by shape rather than by client name, because most rescue work happens under NDA. Each one starts the same way: a read of the codebase before any code is changed.
1. The abandoned handover
Situation. A founder had shipped a Laravel B2B tool with a contractor who stopped responding. The repository lived in the contractor's personal GitHub account, deployment was a manual git pull over SSH, and nobody knew the database backup schedule.
Diagnosis. The code was fine. The operations around it did not exist. Laravel was one major version behind, dependencies were mostly current, and there were no tests.
Work. Ownership transfer of repository, hosting and DNS. A tested backup and restore process. A scripted deploy with queue:restart in it. Characterisation tests on signup, billing and the core workflow. A written runbook.
Shape. Audit first, then a single rescue sprint. Nothing was rebuilt.
2. The silent queue failure
Situation. A marketplace noticed that seller payout notifications had not gone out for six weeks. Support had been manually emailing people without realising why.
Diagnosis. Supervisor had not come back after a server reboot. Workers were dead, the scheduler cron entry had been lost during a server migration, and failed_jobs held tens of thousands of rows spanning several distinct causes.
Work. Workers and scheduler restored under Supervisor with onOneServer() and withoutOverlapping() on the schedule. Failed jobs grouped by class and exception, then triaged into retry, discard and careful-replay sets so no notification went out twice. Queue-depth and oldest-job alerting added, plus a scheduler heartbeat.
Shape. A rescue sprint with the replay plan agreed in writing before anything was retried. The full method is in recovering broken Laravel queues.
3. Billing drift
Situation. A subscription product where the database and Stripe disagreed. Some customers had access without an active subscription; others were paying for plans they had downgraded months earlier.
Diagnosis. The Cashier webhook endpoint was returning 500s on one event type, and the handler was not idempotent, so Stripe's retries had also duplicated rows. Nothing reconciled the two systems.
Work. Webhook route, signature verification and event selection fixed. Handlers made idempotent on the Stripe event id. Historical events replayed in order. A reconciliation report produced before a single row was corrected, so the commercial decisions — who gets a refund, who gets a credit note — stayed with the founder. A nightly reconciliation job now alerts on drift.
Shape. Rescue sprint. Details in fixing Stripe Cashier subscription and webhook failures.
4. The stalled upgrade
Situation. An internal operations app three major Laravel versions behind, on a PHP version past end of life, with a half-finished upgrade branch nobody had touched in a year.
Diagnosis. Two abandoned packages blocked every hop. There were no tests, so nobody could tell whether the abandoned branch worked. Rebuild had been quoted by another supplier at several times the upgrade cost.
Work. The stale branch was discarded. Characterisation tests were written for the three flows the business depended on. PHP was raised to the highest version the current Laravel supported, the two blocking packages were replaced, then the framework hops were taken one at a time with a deploy between each.
Shape. Audit, then staged sprints — each stage independently shippable. Budgeting logic is in how much a Laravel version upgrade costs.
What is consistent across all four
- The read comes before the repair. Every engagement starts with an audit, and in two of the four the audit changed the plan.
- Nothing was rebuilt. Rebuild is the right answer far less often than it is proposed.
- The commercial decisions stayed with the client. We produce the reconciliation report; you decide the refunds.
- Every engagement ended with something written down — a runbook, an access matrix, a known-issues list.
Where to start
If your application is in one of these states, the entry point is the $299 Laravel Triage Audit: five business days, a ranked risk register, and a plain-language recommendation you can hand to any developer. If it is already on fire in production, go straight to the Laravel application rescue sprint.