Third-year CS student at Simon Fraser University, Minor in Statistics, graduating May 2028. Grew up between Pakistan and Dubai, now in Vancouver.
Open to Winter, Summer, and Fall 2027 internships. Most interested in infrastructure, platform, and ML serving teams.
May 2026 - Aug 2026
ECHO, a patent-pending fraud detection platform that reads call transcripts and classifies them against a taxonomy of threat indicators. The interesting constraint was cost: running an LLM over every call at bank scale is not affordable, so the system is a two-stage cascade where a cheap embedding-based classifier gates the expensive model and only escalates what looks suspicious. I owned the orchestration layer and the service contracts, which meant thinking hard about idempotency, since a pipeline that re-ingests on failure has to be safe to rerun. Built from an empty repo by a four-person team over 16 weeks, deployed on OpenShift, demoed at RBC AmpExpo, and going into production.
Jan 2026 - Apr 2026
Led six developers building a membership platform for a poverty-reduction nonprofit. Most of the job was architectural judgment rather than code: splitting the system into services so pairs could ship in parallel, deciding against Kafka once load projections showed a managed queue would do, and refusing to hand a volunteer team infrastructure they'd have to be on-call for. The rest was the usual, chasing down N+1 queries and building a deploy pipeline that could roll itself back.
Aug 2025 - Dec 2025
Multi-tenant event processing on Kafka, where the core design question is what you partition on. Partitioning by tenant gives you throughput and isolation but gives up global ordering, which was the right trade here. Spent most of my time on the things that only show up under load, profiling thread contention in the JVM and replacing unbounded thread creation with a properly sized pool, and on making incidents traceable by keying structured logs to message IDs instead of grepping across instances.
Apr 2025 - Jul 2025
Migrated a PHP/Laravel monolith serving live radio into separate services, with the goal of making sure an encoding failure couldn't take playback down with it. The best bug of the term was a TOCTOU race causing intermittent silent shows, fixed by making broadcast slot claiming atomic at the database level rather than in application logic. Also built listener analytics, batching writes through Redis rather than hammering PostgreSQL per event.
A live case competition platform used across a dozen universities, which makes it a multi-tenant system where a leak between tenants is the worst thing that could happen. So isolation lives in PostgreSQL row-level security driven by JWT claims rather than in application code, because a rule the database enforces can't be forgotten by a developer in a hurry. Payments follow the same principle: Stripe guarantees at-least-once webhook delivery, so the handlers are idempotent and deduplicated on event ID, and duplicate delivery is a non-event rather than a double charge.
A batch inference server in Go, built to understand how serving systems actually earn their throughput. Model inference is far more efficient on batches than on single requests, so the server holds arriving requests briefly and coalesces them into batches bounded by either size or deadline, which is the tradeoff at the heart of every real serving stack: latency for efficiency. The other half of the problem is what happens when demand exceeds capacity, handled with bounded queues and admission control so the server sheds load deliberately instead of collapsing. Benchmarked against fixed batching under burst traffic to confirm the dynamic approach is worth its complexity.
Models fail quietly. Nothing throws, the latency looks fine, and the predictions slowly stop meaning what they used to because the world moved and the training data didn't. This is monitoring for that failure mode: ingest prediction logs, measure how far the live feature distribution has drifted from the training baseline using PSI and KL divergence, and alert on it the same way you'd alert on an SLO burn rate. Drift past a threshold can fire a retraining trigger automatically, which is the part that makes it a platform rather than a dashboard.
Scheduling a dependency graph of jobs under a hard memory ceiling, which is NP-hard and therefore a question about what you're willing to give up. Branch-and-bound gives you the optimal schedule and no bound on how long it takes to find it, so I went with beam search guided by critical-path priority, then validated the output against MILP solutions to confirm the approximation held up in practice. Won the Huawei challenge and presented it to their research engineers in Vancouver.
HeatSpace · Next.js, Flask, OpenCV, NumPy/SciPy, Redis Hackathon winner. Parses 3D floor plans with OpenCV and graph segmentation, then runs Gaussian heat diffusion solvers to place heaters for balanced airflow. Redis caching keeps a multi-room simulation under two seconds.
WebTraceAI · Next.js, Flask, OpenCV, scikit-learn An AI detector for web design. Hand-labeled a dataset of 200+ screenshots and benchmarked several classifiers. Random Forest landed around 80% accuracy at sub-500ms inference.
Languages
Backend
Cloud and infra
ML and observability
Distributed systems and tooling
Concurrency, thread pools, message queues, backpressure, performance profiling, query optimization, SQLAlchemy, VisualVM, pprof, k6
2x MLH hackathon winner. Peer tutor at SFU, 100+ students through data structures and algorithms. Community advisor for 200+ residents in student housing, which turns out to have more in common with debugging a distributed system than you'd expect.


