Case study 04 · Scale and search
SRH Engineering
A corporate platform for a Saudi engineering consultancy holding more than 60,000 clients and 70,000 projects. The interesting problem was keeping search and listings fast while the dataset kept growing.
- Client
- Engineering consultancy, Saudi Arabia
- Role
- Full-stack developer
- Delivered via
- Al Jaami Technologies, UK
- Stack
- Next.js, TypeScript, Tailwind, EC2

01The problem
The consultancy's records had outgrown the tooling around them: tens of thousands of clients, tens of thousands of projects, and staff whose first action every morning is a search. When search takes seconds, people stop using the system and go back to asking each other.
The brief was a platform that stayed responsive at that size and could be handed to a client team afterwards, which made predictable performance and a boring, well-typed codebase the two requirements that mattered.
02Architecture
Next.js with TypeScript on the front, Tailwind and Shadcn UI for the interface layer, RTK Query holding all server state. Behind it, MongoDB with indexes designed around the actual access patterns rather than the entity diagram, and a tokenized search index that answers across more than twenty million records in under a second.
- Client
- Next.js with TypeScript, Tailwind and Shadcn UI components.
- Server state
- RTK Query with explicit cache tags; no parallel local copies.
- Data
- MongoDB, with compound indexes shaped around real query paths.
- Search
- A tokenized index built for prefix and partial matching across 20M+ records.
- Operations
- EC2, PM2, Husky-gated commits, staged deploys.
Deployment sits on EC2 with PM2 for zero-downtime restarts, and Husky gates commits so the type and lint contract holds even under delivery pressure.
03Decisions
- 01
Tokenized search instead of regex lookups
Naive substring matching over that many documents cannot stay fast. Records are tokenized on write into a purpose-built index, so reads are index hits rather than scans, and partial-name lookups behave the way staff expect.
Trade-off Write paths got heavier and the index needs reconciliation when documents change shape.
- 02
Pagination and projection as defaults, not options
Every list endpoint pages and returns only the fields the view renders. Nothing in the app is allowed to request an unbounded collection, which keeps the worst-case response predictable as the data grows.
Trade-off Aggregate views need dedicated endpoints rather than filtering a full fetch on the client.
- 03
TypeScript strictness enforced in CI
The platform was always going to be handed onward, so types and lint rules are gated at commit time by Husky and again in CI. The next developer inherits a codebase that tells them what a payload contains.
Trade-off Slower onboarding for contributors used to loose JavaScript, and occasional friction on urgent fixes.
04Proof
- 20M+
- Records in the search index
- <1s
- Query response at that size
- 70,000+
- Projects, across 60,000+ clients
NextTalk
Slow queries at scale are a design problem.
If your listings and search have stopped feeling instant, that is a conversation I enjoy.