# Hassan Abrar Senior Backend Engineer · distributed systems and multi-tenant architecture Lahore, Pakistan · remote · hassanabrar202@gmail.com · https://www.linkedin.com/in/hassanabrar202/ I'm a senior backend engineer with 5+ years building and operating production systems across enterprise fintech, adtech and high-volume SaaS. I work across both major backend ecosystems, Java/Spring Boot and Node.js/TypeScript, with depth in event-driven microservices, multi-tenant architecture and real-time data pipelines. I led the decomposition of a monolith into 12 production microservices, architected multi-tenant infrastructure for 1,000+ isolated tenant databases at 99.9% uptime, and have mentored 5+ engineers. I work remotely with teams across Saudi Arabia, Europe and North America. ## Products - **ClickFortify** (https://www.clickfortify.com): Scores every paid click and excludes bots, click farms and repeat offenders in Google Ads and Meta. - **VoxRange** (https://www.voxrange.com): AI voice infrastructure: one platform for every voice interaction. - **Pedibee** (https://pedibee.com): CRM and email marketing for growing teams: campaigns, sequences and automations sent from your own Gmail, plus an MCP server. - **GeoIPHub** (https://geoiphub.com): IP geolocation, VPN/proxy/Tor detection and an explainable 0–100 risk score in one REST API. - **Inposty** (in development): Social content planning and publishing. - **Keplaris** (https://keplaris.com): Product engineering studio behind ClickFortify, Pedibee, Inposty and GeoIPHub. ## Selected architectures - **ClickFortify**: Real-time ad-fraud detection for Google Ads and Meta Ads. Lead architect. Stack: NestJS, TypeScript, PostgreSQL, Redis, BullMQ, Kubernetes, Next.js. - **Masdr payroll platform**: Enterprise fintech and payroll for large Saudi employers. Senior Backend Engineer (contract) via Mission.dev. Stack: Java, Spring Boot, JMS, Apigee, Splunk, Jenkins, IBM UrbanCode Deploy, WebLogic. - **Southville multi-tenant platform**: From one monolith to 12 production microservices. Senior Software Engineer. Stack: NestJS, Node.js, Spring Boot, MongoDB, PostgreSQL, Redis, JMS, Docker, Kubernetes. - **VoxRange**: Voice AI and call analytics infrastructure. Builder. Stack: Telephony, Speech-to-text, Text-to-speech, Self-hosted GPU. - **Lytics · PEMRA**: Media monitoring and intelligence for the Pakistan Electronic Media Regulatory Authority. Software Engineer. Stack: Node.js, React, MongoDB, PostgreSQL. ## Experience ### Senior Backend Engineer · Mission.dev (client: Masdr) 2025-05 – present · Remote · Riyadh, Saudi Arabia - Own end-to-end feature delivery across Spring Boot microservices in a multi-tenant, multi-database payroll architecture. - Design asynchronous JMS pipelines for payroll processing, bank verification and inter-service communication. - Manage the API lifecycle on Apigee: rate limiting, auth policy and request/response validation. - Build Splunk dashboards and alerting that shorten diagnosis of payroll and verification incidents. ### Senior Software Engineer · Southville Solutions 2023-02 – present · Lahore, Pakistan - Led the decomposition of a monolith into 12 production microservices. - Architected multi-tenant infrastructure for 1,000+ isolated tenant databases at 99.9% uptime. - Built a NestJS/MongoDB booking platform handling 10,000+ daily transactions; improved API response times by 40%+. - Centralized observability across GCP Logging, CloudWatch and Splunk, cutting incident resolution time by 60%; mentored 5+ engineers. ### Associate Software Engineer · Stack Intel .IO 2021-05 – 2023-01 · Lahore, Pakistan - Built real-time chat on Node.js, WebSockets and Redis Pub/Sub for 10,000+ concurrent users at 99.8% delivery. - Shipped sub-100ms push notifications with Socket.io and Redis Streams; integrated Stripe with zero security incidents. - Raised test coverage to 85% with Jest, Mocha and Supertest, reducing defects by 45%. ### Developer Head · MSP Community, University of Lahore 2021-10 – 2022-04 · Lahore, Pakistan - Led the developer track: technical sessions and hands-on support for student engineers. ### BS Computer Science · The University of Lahore 2017-09 – 2021-06 · Lahore, Pakistan - Bachelor of Science in Computer Science. Languages: English, Urdu --- # Blocking invalid ad clicks while the campaign is still running Advertisers pay for every click. Some of those clicks come from bots, VPNs, proxies and data centers, and a report that arrives weeks later only documents the loss. I am the lead architect of ClickFortify. Its job is to notice invalid traffic and exclude it **while the campaign is still spending**. ## The shape of the problem Three properties drive almost every design decision: - **It never stops.** Clicks arrive continuously, around the clock, across time zones. - **Every advertiser is a tenant.** Each one has its own accounts, rules and data, and they must never leak into each other. - **The action happens somewhere else.** Detecting a bad click is only half the job. The exclusion has to be written back into the advertiser's Google Ads or Meta ad account through their APIs, which have quotas and occasionally fail. ## Separate services, joined by queues Collecting clicks, scoring them and syncing exclusions have very different load profiles. Collection is spiky and must stay fast. Scoring is CPU-bound. Sync is limited by someone else's API. Putting them in one process would let the slowest part set the pace for all of them. So each concern is its own NestJS service: a tracker that collects clicks, workers that score them and sync exclusions, a webhook service for ad-platform and billing events, and the API behind the dashboard. They hand work to each other through **Redis-backed queues** (Bull and BullMQ). A click is collected and queued; a worker scores it and records a decision; decisions that need an exclusion are queued for sync. Each service scales on its own, and a slow ad-platform API never backs up collection. The useful question was not "how fast can we score a click?" but "what happens to everything else when one step is slow?". A queue turns that from an outage into a backlog. ## Scoring a click No single signal proves a click is invalid, so scoring combines several: behavioural signals, device fingerprinting, and filtering for VPN, proxy and data-center traffic. Keeping scoring separate from collection means the rules can change without touching the part that has to stay up. ## Writing back without hammering the APIs The write-back is the part that fails in interesting ways. Exclusions go through **Bull** job queues so that every sync has retries with backoff, and a burst of decisions turns into a steady stream of API calls instead of a spike. ```ts // Illustrative: one queued exclusion per tenant, platform and IP await exclusions.add( 'exclude-ip', {tenantId, platform, ip}, { jobId: `${tenantId}:${platform}:${ip}`, // idempotent: the same IP is never queued twice attempts: 5, backoff: {type: 'exponential', delay: 30_000}, removeOnComplete: true } ); ``` A stable job id makes the operation idempotent: if the same IP is flagged ten times in a minute, it is synced once. ## Workspaces, and shipping safely Every advertiser works inside its own workspace: accounts, rules and data are scoped per workspace on a shared PostgreSQL database. Schema changes ship through the same GitOps pipeline as the code. On Kubernetes, database migrations run as a pre-sync step before new pods roll out, and a failed migration stops the release, so a service never runs against a schema it doesn't expect. ## What I would tell someone building the same thing 1. Treat the write-back to the ad platform as the hard part, not the detection. 2. Separate services by load profile, not by noun. 3. Make every external side effect idempotent before you need to retry it.