Armakuni Contact us
← All case studies

Hiring season used to mean capacity planning.
Now the platform carries ten times the load.

A U.S. hospitality recruitment platform slowed down exactly when hotels and restaurants needed it most. We broke its monolith into services that scale on their own, moved search and bulk posting onto paths built for them, and gave the business one view of how it performs.

Before

The platform struggled most during the busiest week of the hiring season.

The whole platform shared one scaling bottleneck because it ran as a single codebase.

After
10×the capacity, with 600,000+ daily users at peak
60%faster search
80%fewer manual recruiter tasks

As the company reported after the first phases.

The platform struggled most during the busiest week of the hiring season

The platform connects hotels, restaurants and resorts with the people who keep them running. Its customers range from independent operators to hospitality groups hiring for hundreds of roles across many properties, and millions of applications pass through it each year.

Hospitality hiring comes in waves. A seasonal push can double traffic in days, and that's when the platform struggled. Employers uploading large batches of jobs hit timeouts and had to split their submissions or start again. Recruiters worked through applications that had been parsed badly or not at all. Candidates searched against a database already busy running everything else.

Before every busy hiring window, engineers spent their time planning for capacity instead of building the product.

The whole platform shared one scaling bottleneck because it ran as a single codebase

The cause was the shape of the system. A single monolith tied search, posting and recruitment workflows to the same deployment and the same scaling decisions. When search spiked, it pulled capacity away from posting and reporting, and everyone felt it.

The big customers wanted more than speed. Large hospitality groups run their hiring through their own applicant tracking systems (ATS) and need candidate data to flow both ways, and the old architecture had no clean way to do that. It was holding up enterprise contracts at procurement.

Each workload got its own path to scale

Seasonal demand raised several workloads at once, and each needed something different: search had to return an answer fast, bulk posting had to process a large employer submission without failing all at once, and reporting needed history without pulling capacity away from the people using the platform live. We gave each workload its own path, and its own way to scale.

How we built it

5 decisions, in the order we made them. Each one says what we did and why, with what it did drawn beside it.

  1. Split the monolith by what scales differently
  2. Search on its own engine
  3. Bulk posting moved to a queue instead of a single blocking batch
  4. A candidate becomes a structured profile
  5. Reporting that never touches the live application

Split the monolith by what scales differently

Built withECSFargateEC2Lambda
One monolith Containers EC2 Lambda
The engineering

Rewriting everything at once would have frozen the product. We moved the application into independently scalable domains, chosen by how each part of the platform behaves under load:

  • The application services run as containers on Amazon ECS and AWS Fargate, with auto-scaling set so capacity follows whichever service is busy instead of the whole application growing with it.
  • Amazon EC2 for workloads that need a controlled environment.
  • AWS Lambda for event-driven and serverless processing.

A search spike in hiring season should cost search extra capacity, but it should not slow down the rest of the platform.

Search on its own engine

Built withOpenSearchElastiCache
Search on the database OpenSearch ElastiCache
The engineering

Search was the most-used feature and the slowest, because database-backed queries were timing out at peak. Job and candidate search moved to Amazon OpenSearch Service, with indexes carrying role, location, employer and shift attributes. The search path got its own query engine rather than repeatedly scanning the operational database.

Location was a hidden cost. Every location search called the Google Maps API again for the same places. Amazon ElastiCache now stores frequently requested location and metadata lookups, which cuts those repeated calls and takes an external round trip out of the most common searches.

Faster indexing shortened the gap between a new job or an updated profile arriving and showing up in search.

Bulk posting moved to a queue instead of a single blocking batch

Built withSQSLambda
Live job searchAnswered Bulk job postings In parallel
The engineering

A hospitality group posting hundreds of roles across its properties shouldn't wait for one fragile batch to finish. The old workflow ran on a legacy scheduler that processed jobs in slow batches and timed out at scale.

Bulk posting moved to Amazon SQS and AWS Lambda. A large employer submission enters a queue, Lambda functions process the jobs in parallel, and confirmations come back as each posting completes. A failure affects one posting rather than the whole batch, and the employer sees progress instead of a spinner.

A candidate becomes a structured profile

A CVExperienceCertificatesShifts A profile
The engineering

Recruiters were sorting unstructured applications by hand, and good candidates went stale before anyone reached them. We rebuilt the candidate workflow alongside the infrastructure:

  • Resume parsing extracts experience, certifications, shift availability and location preferences into a structured profile.
  • Matching uses those profiles, recruiter filters and candidate preferences to surface relevant applicants for open roles.
  • The ATS integration carries applications into employers' own systems and brings status updates back, so the same candidate isn't handled twice in two places.

Reporting that never touches the live application

Built withGlueS3AthenaCloudWatchCloudTrail
The live applicationUsers Reporting, on copies Reports
The engineering

Product and commercial teams needed to know where applications converted and where users dropped out, without adding reporting load to production:

  • AWS Glue transforms application and engagement data stored in Amazon S3 into Parquet datasets, and authorized analysts query that history through Amazon Athena.
  • CloudWatch Container Insights and Logs Insights expose queue depth, posting throughput, search latency and matching-pipeline health, so engineering can follow a workflow across services instead of investigating a general slowdown.
  • AWS CloudTrail records AWS API and configuration activity for the operational audit trail. Recruitment platforms hold candidate personal data, and enterprise security reviews ask for exactly this.

What we'd tell another CTO

1We split the monolith apart according to how each piece behaved under load. Search had to return an answer fast, bulk posting had to process reliably even when an employer submitted in bulk, and reporting needed history without pulling resources away from people using the platform live. Each piece ended up with its own path and its own way to scale.
2We put a queue in front of anything customers submit in bulk, so one bad posting fails on its own and the employer sees progress instead of a timeout.
3The ATS integration mattered as much as the infrastructure: it was what large hospitality groups needed before they would sign.

What else changed

As the company reported after the first phases.

  • The platform now scales ten times further, handling more than 600,000 daily users at peak without slowing down, and no longer needs capacity planning before each hiring window.
  • 45% less time spent indexing data, so new jobs and updated profiles reach search sooner.
  • Bulk job posting in minutes rather than hours for multi-property employers.
  • Self-service analytics for product, engineering and commercial teams, and observability across every service.

What comes next

We added generative AI to the matching layer, so recruiters can search candidates in natural language and automate parts of their workflow, and extended analytics toward predictive demand forecasting and recruitment ROI modeling.

How we'd do it today

This project came before our current offers. Here's how we'd approach the same work now.

With Modernization with AI, AK Evolve's AI analysis agents would score each part of the monolith on complexity, coupling, testability and change risk before anything was split, with coupling counting shared data as well as calls. Characterization tests would pin what search, posting and matching do today, and each would be rebuilt against those tests behind a routing layer, so every slice could go live on its own and go back. For the natural-language candidate search that comes next, which touches personal data, the AI agents would follow AK AI Factory's rule that none holds private data, reads untrusted text and can send data out at the same time, with one identity per AI agent in AgentCore Identity and Cedar policies at the gateway, deny by default and checked on every tool call. Afterwards, AK Run's AI agents would take the first look at every alert and draft the fix.

Have a problem like this one?

A free workshop: a few hours with the architects who'd do the work, on your own systems. No cost.

Book a free workshop