Skip to main content
Case Study

HR and Payroll SaaS Platform for Growing Enterprises

SaaS Laravel Multi-Tenant Payroll

Payroll has an unusual property among business systems: it must be exactly right, and it must be right on a date that everybody knows in advance. The client's platform was accurate but fragile, and every month-end concentrated the entire customer base onto the same few hours of infrastructure. ELIVTECH rebuilt it with genuine tenant isolation, statutory rules held as versioned configuration, and a payroll engine that runs as resumable work rather than one long transaction.

The client provides HR and payroll software to mid-sized employers, covering attendance, leave, payroll processing, statutory compliance and employee self-service. The original CodeIgniter product had grown into a multi-tenant system where tenants shared tables and were separated by a filter in application code, which made every query a place isolation could fail. Statutory rules were written into that code, so a regulatory change meant a release. Payroll ran as a single long process that had to restart from the beginning if anything failed, and every customer ran it in the same window. ELIVTECH rebuilt the platform on Laravel with schema-level tenant isolation, versioned statutory configuration, a resumable payroll engine, and a React interface for administrators.

At a glance

0 Weeks End-to-End
0 Product Modules Rebuilt
0 Third-Party Integrations
0 Cross-Tenant Queries Possible by Design

The challenge

Isolation enforced by convention, statutory rules held in code, and every customer processing on the same day.

Tenant separation by application filter

All tenants shared tables, separated by a tenant identifier applied in query code. Correctness depended on every developer remembering the filter in every query, on every code path, indefinitely. For a product holding salary and personal data, that placed the most serious risk in the platform under the weakest possible control.

Statutory rules compiled into the product

Contribution rates, thresholds and filing formats were written directly into application logic. A regulatory change required a code change, testing and a release, and because rules were not versioned, recalculating a historic period applied today's rules to a period governed by different ones.

Payroll as one long transaction

A payroll run processed every employee in a single operation. A failure part-way through meant restarting from the beginning, and for larger customers the run occupied a long enough window that a restart risked missing the payment deadline entirely.

Every tenant peaking together

Month-end is the same date for everyone. The platform sat mostly idle then absorbed the entire customer base within a few hours, and infrastructure sized for that peak was oversized for the rest of the month while still being tight during it.

Payslips that could not be explained

The system produced a net figure without retaining the intermediate calculation. When an employee queried a deduction, payroll staff reconstructed the arithmetic manually, and the answer depended on whoever performed the reconstruction rather than on a record of what the system had actually done.

Attendance corrections applied silently

Retrospective attendance and leave adjustments overwrote the original entries. There was no record of what had changed, who changed it or why, which made an audit of a disputed period impossible and left payroll unable to explain a variance between two runs.

Our solution

Isolation at the schema, statutory rules as versioned data, and payroll that resumes instead of restarting.

Tenancy and Compliance Modelling

Five weeks establishing the tenancy model and separating product logic from statutory logic. Every rule that varies by jurisdiction, employer category or effective date was identified and moved out of code into configuration with validity periods, so a historic recalculation applies the rules that were in force at the time rather than the rules in force today. Filing formats were treated the same way, because a change to a submission layout is a compliance deadline the product should meet without a release.

Schema-Level Tenant Isolation

Each tenant received its own MySQL schema, with connection resolution performed once per request from the authenticated context rather than by a filter in each query. A developer cannot write a cross-tenant query by omission, because the connection itself is scoped. Migrations run per tenant through tooling that reports which schemas are on which version, so a partially applied release across a large tenant estate is a visible state rather than a discovery made when a customer reports an error.

Resumable Payroll Engine with Retained Working

Payroll processes employees in batches as queued jobs with checkpointing, so a failure resumes from the last completed batch. Every component of a calculation is retained alongside the result, which means a payslip can be explained line by line from stored working rather than reconstructed. Runs are previewable and reversible before they are committed, so payroll staff review an exception list and correct source data rather than discovering a problem after payments have been released.

React Administration and Month-End Capacity

Administrators work in a React interface covering employee records, attendance, leave, payroll review and statutory filing, with an exception-first payroll review that surfaces variances against the previous period. Infrastructure scales on queue depth so month-end capacity arrives with the load, and tenants are staggered across the processing window by priority rather than all starting at once. Attendance corrections are recorded as adjustments carrying actor and reason rather than overwriting history.

Technology stack

Laravel CodeIgniter (legacy modules) PHP 8 React MySQL 8 Schema-per-Tenant Laravel Queues Redis AWS ECS Fargate Amazon RDS Amazon SQS AWS KMS Amazon CloudWatch Terraform CI/CD Pipeline

Results

Measured across a full month-end cycle with every tenant migrated to the new platform.

0 Cross-Tenant Queries Possible by Design
0 Payslips Explainable From Stored Working
0 Payroll Runs Restarted From the Beginning
0 Statutory Rule Change, No Release Required

Before and after: platform engineering measures

Before
  • Tenants sharing tables, separated by an application-level filter
  • Isolation dependent on every query remembering the filter
  • Statutory rates and thresholds written into application code
  • Historic recalculation applying present-day rules
  • Payroll as one long run that restarted on failure
  • Net pay produced without retaining intermediate working
  • Attendance corrections overwriting the original entries
After
  • Schema per tenant with connection scoped from authenticated context
  • Cross-tenant access prevented structurally, not by convention
  • Statutory rules held as configuration with validity periods
  • Historic periods recalculated under the rules then in force
  • Batched, checkpointed payroll that resumes from the last batch
  • Full calculation working retained and shown line by line
  • Corrections recorded as adjustments with actor and reason

Project timeline

Weeks 1-5

Tenancy and Compliance Modelling

Tenancy model selection and migration planning, separation of statutory rules from product logic, validity-period configuration design, and an audit of the legacy codebase to sequence module rebuilds safely.

Weeks 6-14

Platform Foundation and Isolation

Laravel core with schema-per-tenant connection resolution, per-tenant migration tooling with version reporting, encrypted storage of sensitive fields, role and permission model, and the deployment pipeline on AWS.

Weeks 15-23

Payroll Engine and Statutory Configuration

Batched checkpointed payroll processing, retained calculation working per component, preview and reversal before commit, statutory configuration with effective dating, and filing output generation per jurisdiction.

Weeks 24-31

Attendance, Leave and Administration

Attendance and leave modules with adjustment records carrying actor and reason, React administration interface, exception-first payroll review against prior period variance, and employee self-service surfaces.

Weeks 32-36

Parallel Payroll and Tenant Migration

Parallel runs comparing new and legacy output for every migrating tenant, month-end load testing on concentrated profiles, monitoring on queue depth and batch failure, then tenant-by-tenant migration across cycles.

Key takeaways

What shaped the engineering decisions

  • Make isolation structural, not disciplined: A shared-table model with query filters was rejected because it relies on every developer being careful forever. Schema-per-tenant with connection scoping means the mistake cannot be made rather than being caught in review.
  • Effective-date the statutory rules: Holding rates in code made every regulatory change a release and made historic recalculation wrong. Configuration with validity periods lets a run for a past period use the rules that governed it.
  • Checkpoint the payroll run: One long transaction meant a failure near the end cost the whole run at the moment there was least time to recover. Batching with checkpoints turned a restart into a resume.
  • Retain the working, not only the result: Storing every calculation component alongside the net figure turned payslip queries into a lookup. It also made parallel running meaningful, because differences could be traced to a component rather than to a total.
  • Adjust, never overwrite: Recording corrections as adjustments with actor and reason preserved the audit trail that a disputed attendance period requires, and made variance between two payroll runs explainable.
  • Prove each migration with a parallel run: Every tenant was processed on both platforms and compared before switching. It is slower than a cutover and it is the only approach that gives a payroll customer a defensible reason to trust the change.
Where this platform goes next. With statutory rules as configuration and isolation enforced structurally, supporting a new jurisdiction becomes a configuration exercise rather than a fork of the product. The team is extending effective-dated configuration to employer-specific policies, adding scenario modelling so a customer can see the effect of a policy change before applying it, and using retained calculation working to power richer workforce cost reporting.

Want results like these?

Let's discuss how ELIVTECH can drive measurable outcomes for your business.

Start your project