# Abu Ashraf Masnun > Software Architecture · Distributed Systems · Go · Node.js · Python ## Summary Over 15 years of building and scaling distributed systems has taught me what makes software last - and exactly where it breaks. These days, I pair that hard-won judgment with modern AI tooling to ship faster without compromising on code quality. The AI handles the boilerplate and accelerates execution, but I make the architectural calls and keep the quality bar high. The craft is still human; I just have better leverage now. ## FAQ ### Who is Abu Ashraf Masnun? Abu Ashraf Masnun is a software architect and full-stack engineer with 15+ years of experience building and scaling distributed systems. He works mostly on the backend - email and SMS delivery platforms, real-time analytics pipelines, API gateways and lead routers that serve millions of people a month. ### What technologies and languages does he work with? His daily drivers are Go, Node.js/TypeScript and Python. He has deep experience with distributed systems and background jobs (Celery, BullMQ, Asynq), databases and caching (PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch), and cloud/DevOps (AWS, Terraform, Docker). He also works across the stack with React. ### Is Abu Ashraf Masnun available for freelance or contract work? He freelanced on Upwork from 2009 to 2021 (58 jobs, 2.9K+ hours, 4.7-star rating across 57 reviews) and is not actively freelancing now, as a full-time role has his focus. He remains open to the right proposal - for an interesting problem, reach out by email, WhatsApp or Upwork. ### Where is Abu Ashraf Masnun based? He is based in Khulna, Bangladesh, and has worked directly with founders and teams around the world throughout his career. ### What kinds of systems has he built? High-throughput messaging platforms, exactly-once data pipelines into Snowflake, caching API gateways, a self-scaling worker fleet, a real-time campaign analytics platform, and a custom background-worker framework - alongside years of polyglot code review across PHP, Python, Node.js, Go and Java. ## About I've been writing code since 2006. I started as a self-taught teenager in Khulna, Bangladesh, building entire mobile community sites in PHP just to see if I could - and because people actually used the things I made. That itch never went away. Two decades later, it's still the exact same loop: find something I don't understand, build the smallest real version of it, and keep going until it clicks. I'm a business graduate (BBA, Khulna University) who chose engineering anyway. I went professional with PHP in 2008 and started freelancing on oDesk (now Upwork) in 2009, working directly with founders and teams around the world. The PHP years were good to me - I shipped plenty of products using Laravel, Symfony, CodeIgniter, and WordPress. But somewhere along the way I fell hard for Python, and Django and DRF quickly became the tools I reached for first. Since then, I've never stopped collecting languages. Go and Node.js are daily drivers now, and I've got a soft spot for Clojure, Elixir, Kotlin, and Rust. Today, my work lives mostly on the backend, usually at the architecture and distributed-systems level. Over the last 15 years, I've built systems that have to stay up while serving millions of people a month, including email and SMS delivery platforms, real-time analytics pipelines, API gateways, and lead routers. The problems I enjoy most are the unglamorous-but-critical ones: managing concurrency and async execution (like Python's asyncio internals and Go's goroutines), building exactly-once data pipelines, and designing clean REST APIs. I really care about why a thing works, not just that it does. I have strong opinions held loosely. I tend to reach for boring, proven technology when the goal is to ship something that lasts - tools like Celery, Redis, Postgres, and MySQL. I prefer matching the tool to the job's real risks rather than chasing hype. I also deploy what I build. These days that mostly means AWS (ECS with Docker), though over the years I've run everything from Linux boxes with Nginx to serverless AWS Lambda functions. I've also spent a lot of time as a third-party code reviewer on Upwork, auditing PHP, Python, Node.js, Go, and Java codebases. Sharing what I know matters to me just as much as building. I co-founded Python Bangladesh (the country's largest Python user group), founded NodeSchool Khulna, and co-founded Google Business Group Khulna. I speak at local conferences and record screencasts in my mother tongue so more people can get started. If you want to see how I actually think, the hundreds of blog posts on masnun.com and masnun.rocks are the most honest record - less structured tutorial, and more about how things actually work under the hood. ## Skills ### Go (Golang) My go-to for high-throughput, reliable distributed services. I've built SMS delivery engines, a caching API gateway, an SMTP email-verification service, an open-tracking pixel server and infrastructure watchdogs in Go. I lean on goroutines and channels for concurrency, Chi or Echo for routing, and sqlx over heavy ORMs. The simplicity, speed and predictable deploys are exactly what large systems need. It's my pick when something has to stay up under load. Tags: Go, Chi, Echo, Goroutines, Asynq ### Node.js / TypeScript My main stack for service APIs and data pipelines in recent years. I favor Koa for its lightweight middleware and BullMQ/Bull over Redis for background work, and I've adopted TypeScript across the board for the safety types bring. I've built job-aggregation services, a central analytics pipeline into Snowflake, scraping fleets and a five-year real-time analytics backend with it. Clean, layered architectures are a recurring theme in this work. It scales well across a team. Tags: Node.js, TypeScript, Koa, BullMQ, Bull, JavaScript ### Python My first-choice language and the one I've shipped the most production code in. I've built large email and SMS platforms, REST APIs, self-scaling worker systems and a nine-year university results system with Django, DRF, Flask and Celery. I know its concurrency model deeply - asyncio, the event loop and the GIL - and have written widely-read posts on it. I co-founded Python Bangladesh, the country's largest Python community. It's where I'm fastest and most opinionated. Tags: Python, Django, DRF, Flask, Celery, RQ ### PHP Where my career began - I shipped professional PHP from 2008 onward. I built Q&A platforms, deployment tooling, e-commerce search, concert and rent-management apps, and community sites on Zend Framework, Yii and WordPress. I moderated phpXperts, the largest PHP group in Bangladesh, and spoke at its conferences. I respect what PHP taught me about the web, even though I reach for other tools today. It's still a language I can move fast in. Tags: PHP, Zend Framework, Yii Framework, WordPress ### Distributed Systems & Background Jobs The throughline of most of my work: reliable systems built from queues, workers and services. I've designed self-scaling worker fleets, exactly-once data pipelines, multi-provider delivery with failover, and a background-worker framework from scratch. I've used Celery, BullMQ, Asynq, Gearman and RQ to move heavy work off the request path safely. The hard parts - backpressure, idempotency, failure recovery, graceful shutdown - are the parts I enjoy most. This is where I do my best engineering. Tags: Asynq, BullMQ, Bull, Celery, Gearman, RQ, IronMQ, Snowflake ### Databases & Caching I've run MySQL, PostgreSQL, MongoDB, Redis and Elasticsearch in production across many systems. I use the right store per job - relational for transactional data, documents for flexible and analytics data, Redis for caching, queues and locks. I've done schema design, query profiling and cache-aside layers with sensible invalidation. Keeping data correct and fast under concurrent writes is a problem I've solved repeatedly. Redis in particular shows up almost everywhere I build. Tags: MongoDB, PostgreSQL, MySQL, Redis, Elasticsearch, Caching ### Cloud, DevOps & IaC I deploy and operate what I build. I've provisioned full AWS environments as Terraform code - VPC, ECS, RDS, S3, EFS, secrets and scheduled jobs - and run services on Docker with CI, process managers and serverless Lambda. Years of Linux sysadmin back it up: nginx, uWSGI, Daphne and Supervisord. Observability matters to me, so Sentry, structured logging and Slack alerting come standard. The goal is always reproducible, boring, reliable infrastructure. Tags: AWS, AWS Lambda, Terraform, Docker, Supervisord ### Web Scraping & Automation I've built large-scale scraping and automation systems end to end. That includes a distributed crawl engine that grew to 750+ employer scrapers with headless browsers, an automated anime aggregator, and a Twitter keyword-and-reply automation engine. I handle the messy parts - concurrency and locking, per-source quirks, bot-like patterns and rate limits. Turning unstructured web content into clean structured data is something I've done many times. It pairs naturally with my queue-and-worker background. Tags: Puppeteer, PHP Simple HTML DOM, Twitter APIs ### Frontend (React) A backend engineer at heart who works comfortably across the stack. I've led React/Redux dashboards for real-time analytics and scraping tools, built management UIs, and shipped a full Next.js storefront app. My front-end history runs jQuery → AngularJS → React, so I've watched the patterns evolve. I'm not a designer, but I build clean, functional interfaces that make systems usable. Owning both halves means the API and the UI get designed together. Tags: React, Redux, Next.js, jQuery, Bootstrap ## Projects ### Shopify Like E-Commerce SaaS URL: https://masnun.me/project/ecommerce-saas/ Tags: TypeScript, Next.js, React, PostgreSQL, MongoDB, Redis, Terraform, AWS ## Overview A **multi-tenant, Shopify-like e-commerce SaaS** - a single platform where any merchant can spin up their own online store, manage their catalog and orders, point a custom domain at it, and pick a fully custom storefront theme. I worked across the whole system: the full-stack web application, a sandboxed theme engine with its own build-and-deploy pipeline, and the cloud infrastructure that runs it all. It's the kind of product where one codebase has to safely serve many independent shops at once - isolated data, isolated domains, and isolated, untrusted theme code - while still feeling like a fast, modern app to each merchant and shopper. ## What It Does - **Runs many stores from one platform.** Each shop is fully tenant-isolated, resolved per request from either a platform subdomain or the merchant's own custom domain (with automated DNS and SSL). - **Manages the full commerce domain.** Products with categories, variants, SKUs and tiered pricing; multi-location inventory; weight- and zone-based shipping with cash-on-delivery and packing slips; configurable payment capture; plus blogging, content pages and navigation menus. - **Gives each merchant a custom storefront.** Shops choose from interchangeable themes; the storefront (home, product, blog, page views) renders from theme code that the platform executes safely on the server. - **Two-tier administration.** A per-shop dashboard for merchants and staff, and a platform-admin surface for managing every shop, user, media asset and audit log across the tenancy. - **Integrates with the channels merchants care about.** Social commerce catalog sync and webhook handling so products stay in step with external marketplaces. ## Engineering Highlights ### Multi-tenant, full-stack application The web app is a single full-stack TypeScript codebase: server-rendered storefronts and dashboards, server actions and API routes for mutations, webhooks and scheduled jobs, all backed by a relational database for transactional commerce data, a document store for flexible/audit data, and an in-memory cache. Tenancy is enforced at the data-access boundary - every shop request resolves to a tenant context, and a strict, lint-enforced layering (integrations → services → actions → features → UI) keeps that isolation from leaking. Auth supports OAuth, email OTP and phone sign-in with role-based access for owners, staff and platform admins. ### Sandboxed theme rendering The hardest, most interesting problem: letting merchants run **arbitrary storefront theme code** without letting it compromise the platform or other tenants. Themes are authored as components, then **executed inside a hardened server-side sandbox** (an isolated VM) with a tightly controlled API surface and the rendering runtime injected from outside rather than bundled in. Compiled views are cached (in-memory LRU plus a shared cache) and invalidated on theme changes, so the security boundary doesn't cost render latency. ### Theme build & deploy pipeline Theme authoring is decoupled from the live app by a dedicated build tool. It validates that a theme provides every required view, compiles each one independently to a runtime-ready bundle, and assigns a **stable identifier that persists across rebuilds** so deployments stay idempotent - the same theme always lands on the same paths, never breaking a merchant's selection. Deployment is a deliberate two-step dance around network isolation: assets and bundles are pushed to object storage from outside the private network, then the in-network app is signaled to pull them onto its shared file system and bust its cache. The trigger uses **exponential-backoff retries** so a brief deploy-window outage never strands a half-finished upload, and teardown is ordered to never leave orphaned assets. ### Cloud infrastructure as code The entire production environment is defined as code and provisioned reproducibly: a VPC across multiple availability zones, a load balancer fronting a container service, a managed relational database, shared network storage for theme content, versioned object storage with public/private access policies, a container registry, secrets management for credentials and tokens, scheduled jobs via cloud cron hitting a secured endpoint, and centralized logging. Remote state with locking keeps changes safe. A notable bit of real-world tuning: the container runtime's heap is explicitly capped to respect cgroup memory limits, with a deployment strategy chosen to fit tight memory budgets without out-of-memory failures. ## Why It Matters This is a product with genuinely hard, distinct problems stacked on top of each other - multi-tenant isolation, safe execution of untrusted code, a decoupled build/deploy pipeline that survives network isolation and transient failures, and reproducible cloud infrastructure - and I worked across all of them. It's full-stack and full-lifecycle: from the merchant clicking "publish theme" in a dashboard down to the Terraform that provisions the database it writes to. ## Tech Stack | Layer | Technology | |---|---| | **Web app** | TypeScript, Next.js (App Router), React, Tailwind | | **Backend** | Server actions & API routes, layered service architecture | | **Auth** | OAuth, email OTP, phone - role-based access | | **Databases** | PostgreSQL (transactional), MongoDB (flexible/audit), Redis (cache) | | **Theme engine** | Server-side sandbox (isolated VM), esbuild compilation, LRU + shared cache | | **Theme pipeline** | CLI build tool, stable theme IDs, object-storage staging, retried sync | | **Infrastructure** | Terraform, AWS (VPC, ECS/EC2, RDS, S3, EFS, ECR), Secrets Manager | | **Ops** | Cloud-cron scheduled jobs, centralized logging, error tracking | ### SMS Delivery Platform URL: https://masnun.me/project/sms-delivery-platform/ Tags: Go, Asynq, Redis, MongoDB, Chi ## Overview I designed and built the messaging platform that runs a staffing company's job-alert business - the system that turns job leads into text messages people actually receive. Every day it delivers **400,000+ messages** across multiple brands and six different SMS providers, on time and in each recipient's own time zone. This is the revenue engine of the product, so the bar was simple and unforgiving: never text the same person twice, never break SMS regulations, and never go down when a provider does. I took it from a blank page to production in Go, and I keep it running as the dependable backbone the business relies on. ## What It Does - **Sends the right message at the right time.** Hundreds of thousands of time-zone-aware job alerts a day, across multiple brands, each with its own templates and rules. - **Speaks to six SMS providers as one.** Plivo, Sinch, SimpleTexting, TextBack, PineApple and Slooce all work differently - different logins, message formats, and status reports. The platform hides all of that behind one clean interface, so providers can be swapped or load-balanced without touching code. - **Stays on the right side of the law.** STOP/HELP/JOIN opt-out keywords, per-person rate limits, and daily send caps are built into the pipeline - and they fail safe, so a glitch slows sending down rather than risking an over-send or a violation. - **Tracks every click and reply.** Inbound replies and delivery reports from every provider are normalized into one model, and a custom link shortener tracks clicks with built-in bot detection. - **Reports on it all.** Live delivery numbers, click data, and a dashboard for inspecting the message queue in real time. ## The Hard Problems I Solved **Never sending a duplicate - even with 30 workers racing each other.** At this scale, many machines process the queue at once, all capable of grabbing the same lead. I made duplicates impossible using distributed locks (keyed on the lead, campaign, and schedule) that expire automatically so nothing ever gets stuck. And once a provider accepts a message, the system is built so that no later failure can ever cause a re-send. **Staying up when a provider goes down.** Provider outages are a question of *when*, not *if*. The platform isolates each send as its own unit of work and handles failures deliberately - a single provider failing never cascades into the rest of the system. **Making a complex send safe and debuggable.** Sending one alert involves a dozen steps - load the lead, check compliance, acquire the lock, check caps, build a tracking record, shorten the link, render and send, save the result. I modeled this as an explicit pipeline where every step is isolated, so when something fails it's obvious exactly where and why. **Knowing the moment something breaks.** Structured logging on every task, Sentry for crashes, and Slack alerts that group errors by brand and provider instead of flooding the channel - so on-call sees signal, not noise. ## How It's Built to Scale The platform splits into three independent pieces, each scaled on its own: - A **web service** handling the dashboard, provider webhooks, and campaign setup. - A fleet of **background workers** (30 at a time) that do the actual sending, each send an isolated, retryable job. - A **scheduler** that only ever *hands out* work - it never does the work itself, which lets the workers scale out horizontally without coordination headaches. The guiding principle throughout: scheduling and execution are kept separate, correctness is enforced cluster-wide through locks and atomic database operations, and there's no hidden coordination server to fail. ## Why It Matters This is the kind of system a business quietly depends on every single day. It handles money-adjacent, regulation-bound, high-volume work where mistakes are expensive - a duplicate text annoys a customer, a compliance slip is a legal problem, an outage is lost revenue. Building it meant getting the genuinely hard parts of backend engineering right: correctness under concurrency, graceful failure, and dependable operation at scale. It just works - and it has, every day, since I shipped it. ## Tech Stack | Layer | Technology | |-------|-----------| | **Language** | Go 1.22 | | **HTTP** | go-chi/chi v5, chi/render, chi/cors | | **Job Queue** | Asynq (Redis-backed) + asynqmon dashboard | | **Scheduling** | robfig/cron v3 | | **Database** | MongoDB 4.4 | | **Cache / Queue Backend** | Redis 7.0 | | **Distributed Locks** | redsync + custom MongoDB locks | | **SMS Providers** | Plivo, Sinch, SimpleTexting, TextBack, PineApple, Slooce | | **Validation** | go-playground/validator v10 | | **Encryption** | Fernet (go-fernet) | | **Observability** | Sentry, structured `slog`, Slack alerts | | **CLI / Config** | Cobra, env-based configuration | | **IDs / Util** | google/uuid | | **Dev / Deploy** | Docker, docker-compose, `air` hot-reload, 2-stage Dockerfile, runit supervisor | ### Job Aggregation Microservice URL: https://masnun.me/project/job-aggregation-microservice/ Tags: Node.js, JavaScript, Koa, BullMQ, MongoDB, Snowflake ## Overview I designed and built a high-throughput backend platform that pulls job listings from **external job boards and ad networks**, blends them into one unified feed, and serves them through a single API - handling **2.5 million requests per day**. On top of that, it runs a complete revenue pipeline - tracking impressions, clicks and affiliate earnings, and tying every dollar of partner revenue back to the search that produced it. The hard problem it solves is fragmentation. Every partner network speaks a different language: different data formats, different login schemes, different ways of reporting what they paid. This platform hides all of that behind one clean, dependable feed - and accounts for the money accurately, at scale. ## What It Does - **One feed from many sources.** Multiple partner networks, each with its own quirks, normalized into a single consistent set of job listings. - **Smart sourcing.** The platform balances speed against coverage - it can return the fastest result, or cast the widest net across every source, depending on what the request needs. - **Revenue attribution.** It reconciles affiliate earnings that arrive late, in pieces, and with duplicates - matching each payment back to the search that earned it and rolling up earnings, clicks and revenue-per-click by source. - **Trustworthy numbers.** It cross-checks its own revenue totals against what each partner reports and raises an alert when the two drift apart. - **Analytics at scale.** Processed data is exported to a Snowflake data warehouse and surfaced in Metabase dashboards for the business to explore. ## How It's Built to Scale The platform splits into two halves that scale independently: a fast request-handling tier that answers live job searches and click redirects, and a background tier that does the heavy lifting - collecting revenue, enriching data, and exporting to the warehouse. The light, latency-sensitive work never competes with the heavy batch work. It's also built to stay up and stay correct under real-world pressure: - **Reliable money handling** - designed so the same revenue is never double-counted and totals stay accurate even as data arrives messily. - **No double-runs** - scheduled jobs coordinate across multiple servers so the same work never fires twice. - **Handles huge datasets** - it streams large data sets through rather than loading them into memory, so it stays stable no matter how big the data grows. - **Self-healing operations** - automatic retries on failure, error monitoring and alerting, and a scheduled off-peak restart that keeps the service healthy over long runs. ## Why It Matters This platform shows production backend engineering across the genuinely hard parts: integrating many uncooperative vendors, getting financial numbers exactly right, processing very large data sets reliably, and keeping a distributed system dependable day after day. It's the kind of system a business quietly depends on - and it just works. ## Tech Stack | Layer | Technology | |---|---| | **Language / Runtime** | Node.js, JavaScript | | **HTTP framework** | Koa 2 | | **Database** | MongoDB | | **Job queue** | BullMQ (Redis-backed workers, retries, backoff) | | **Cache / coordination** | Redis + distributed locks | | **Scheduling** | node-cron | | **Cloud / analytics** | AWS S3 → Snowflake → Metabase | | **Observability** | Sentry, Winston | | **Infra / tooling** | Docker, docker-compose, Jest | ### Central Data Pipeline Service URL: https://masnun.me/project/central-data-pipeline-service/ Tags: Node.js, Koa, BullMQ, Redis, MongoDB, Snowflake ## Overview I designed and built the **central data pipeline** that unifies analytics from an entire product suite into one warehouse. 10+ internal services and platforms send their analytics events to a single API. The service validates, batches, deduplicates, transforms, and lands them in **Snowflake** for business reporting, handling **60+ distinct event types** across the whole company. Think of it as the routing layer between "everything the product does" and "the numbers the business reports on." When the company wants to know what happened - who got a message, what an ad earned, which jobs were viewed - those answers flow through this system. ## What It Does - **One front door for all analytics.** Every app POSTs events to the same API. No app needs to know anything about the warehouse - they just send events and move on. - **Never loses, never duplicates.** Apps retry deliveries when networks hiccup. The system is built so a re-sent event lands exactly once, and a re-run of a day's data cleanly replaces it instead of doubling the numbers. - **Add a new source without writing code.** Onboarding a new app or event type is a declarative config entry - the SQL, validation rules, and field transformations all generate from it. New data sources go live in minutes, not sprints. - **Built for spikes.** Incoming events are queued instantly rather than written on the spot, so the API stays fast and absorbs traffic surges without falling over. ## How It's Built to Scale The service runs as three independent processes - request handling, background processing, and scheduling - selectable from a single setting, so each part scales on its own. Fast event ingestion never competes with the heavy lifting of loading the warehouse. It's engineered to stay correct and stay up under real production pressure: - **Memory-safe at any size** - instead of loading whole datasets into memory, it *streams* events straight through to cloud storage and into Snowflake. Memory stays flat whether it's a thousand events or a million, running comfortably under a tight 200 MB cap. - **No double-runs across servers** - in a multi-server deployment every instance fires the same scheduled tick. A distributed lock guarantees only one actually runs the job, so the warehouse is never loaded twice. - **Exactly-once accounting** - composite-key upserts make ingestion idempotent; the warehouse load replaces a day's partition atomically rather than appending duplicates. - **Secure, keyless warehouse auth** - Snowflake connections use key-pair (JWT) authentication instead of passwords. - **Clean deploys** - an ordered shutdown sequence drains in-flight work before exiting, so jobs aren't dropped when the service restarts. - **Operable in production** - error reporting with profiling across the API, workers, and scheduler; alerts fire only on the *final* failed retry to cut noise; structured logging carries full context end-to-end; a self-cleaning janitor removes stale temp files automatically. ## Why It Matters This is the kind of system a business quietly depends on. It demonstrates production backend engineering across the hard parts: distributed-systems design (queues, distributed locks, idempotency), backpressure-aware stream processing that stays memory-flat at scale, schema-driven architecture that makes the system extensible by config, and production-grade operability. Every BI dashboard in the company is downstream of getting this right. ## Tech Stack | Layer | Technology | |---|---| | **Language / Runtime** | Node.js 18, JavaScript | | **API** | Koa, Joi (validation), Swagger UI | | **Job queue** | BullMQ (Redis-backed workers, tuned concurrency, backoff retries) | | **Cache / coordination** | Redis + Redlock (distributed locking) | | **Staging store** | MongoDB | | **Cloud / warehouse** | AWS S3 (streaming NDJSON multipart upload) → Snowflake (`COPY INTO`, JWT key-pair auth) | | **Scheduling** | node-cron | | **Observability** | Sentry (with profiling), Winston | | **Infra / tooling** | Docker, docker-compose, Makefile, runit | ### Marketing Analytics Data Platform URL: https://masnun.me/project/marketing-analytics-platform/ Tags: Go, Node.js, AWS Lambda, Asynq, BullMQ, MongoDB, Snowflake ## Overview I designed and built an end-to-end **marketing analytics platform** - a suite of services that turns raw advertising traffic into the numbers a business uses to decide where its ad money goes. It ingests click-level traffic and conversion events from a third-party ad-tracking platform in real time, enriches each event with ad-spend data pulled from the major search, social, and push-notification ad networks, and lands the unified result in a **Snowflake** data warehouse - surfaced to the business through **Metabase** dashboards for return-on-investment attribution and campaign analytics. The platform spans two languages and several architectures - real-time, queue-driven, and scheduled-batch - each chosen to fit the failure modes of the data source it talks to. The hard problem it solves: every ad network reports money differently, late, and messily, and the business still needs one trustworthy answer to "what did this campaign earn versus what it cost?" ## What It Does - **Real-time ingestion at the edge.** Live traffic events flow in through a serverless gateway that deduplicates as it ingests - rejecting replays and retries, and identifying unique visitors within a rolling 24-hour window so the metrics stay accurate. - **Full audit trail.** Every raw event is archived before it's parsed, so the whole pipeline can be replayed if downstream logic ever changes - nothing is lost. - **Cost enrichment across networks.** Each traffic event is matched against spend data from multiple ad networks in priority order, tying every conversion back to what it actually cost to acquire. - **Revenue unification.** Earnings from several different ad and push-notification platforms - each with its own data format and quirks - are normalized into one consistent reporting shape. - **Trustworthy numbers at scale.** The result is a single warehouse of unified cost-and-revenue data the business can slice by campaign, source, and time. ## Engineering Highlights - **Beating a hard API limit.** One upstream platform caps how many results it returns per request, but a single high-traffic campaign can produce far more conversions than that cap in a single hour. I built an adaptive algorithm that automatically splits any over-sized time window in half - recursively - until each slice fits under the limit, replacing fragile manual per-campaign tuning with something self-adjusting. It respects the platform's awkward constraints and alerts a human only when even the smallest possible window still overflows. - **High-throughput batch processing.** Instead of querying per record - the classic performance trap - the enrichment engine streams events in, gathers the IDs it needs, and resolves them in a handful of bulk lookups held in memory. Orders of magnitude fewer database round-trips. - **Two-stage warehouse writes.** Processing separates *sending* from *committing*, batching many sends into larger warehouse writes for efficiency. - **Resilient by design** - retries with exponential backoff and jitter (retry on transient failures, fail fast on permanent ones), cached authentication tokens with safe refresh, distributed locking so scheduled jobs never double-run across servers, and bot filtering across known IP ranges, providers, and user agents. - **Asynchronous report handling.** Some ad networks deliver reports asynchronously - request, poll, download, unpack, parse - and quirk-laden exports (odd encodings, vendor-specific formats) are cleaned up automatically so the data lands consistently. - **Self-healing operations** - idempotent writes (a re-run cleanly replaces a day's data rather than duplicating it), worker pools for fast concurrent loading, structured logging keyed for traceability, and error monitoring throughout. ## Why It Matters This is polyglot, production systems engineering across the genuinely hard parts: real-time ingestion that stays correct under replays and retries, integrating many uncooperative vendor APIs, getting financial attribution exactly right, and processing large data sets reliably day after day. The services trace a clear arc of iterative refinement - naive processing hardened into bulk operations, adaptive rate limiting, and full observability - all driven by real production constraints. It's the kind of platform a marketing business quietly runs on. ## Tech Stack | Layer | Technology | |---|---| | **Languages** | Go, Node.js | | **Cloud / serverless** | AWS Lambda, SNS, SQS, S3, Elasticache | | **Web frameworks** | Koa (Node), Chi (Go) | | **Job queues** | BullMQ (Node/Redis), Asynq (Go/Redis) | | **Scheduling** | node-cron, in-process Go crons | | **Distributed locking** | Redlock | | **Databases** | MongoDB, Redis | | **Data warehouse / BI** | Snowflake → Metabase | | **External integrations** | Ad-tracking platform, search / social / push ad-network APIs (OAuth2) | | **Observability** | Sentry, Winston, structured JSON logging | | **Infra / deploy** | Docker, docker-compose, Runit, AWS SAM/CloudFormation, GitHub Actions → ECR | ### Heimdall - API Caching Gateway URL: https://masnun.me/project/heimdall-api-gateway/ Tags: Go, Node.js, Koa, Chi, MongoDB, Caching ## Overview **Heimdall** is a caching gateway that sits in front of paid third-party verification APIs - email validation and phone-number lookups - and shields the business from their cost and latency. Every verification provider charges per call and answers slowly; Heimdall checks its own cache first and only reaches out to a provider when it genuinely has to. Repeated lookups become instant and free. I built it **in Go first**, then **re-implemented it in Node.js** - a deliberate move to scale the service across the development team, since more developers knew Node and could own and extend it. The Node.js rewrite also grew the feature set: the Go version is a lean, single-purpose email validator, while the Node.js version is the fuller implementation, adding phone-number lookups and multi-provider fallback on top. Together they show the same architecture expressed idiomatically in two languages - and a real-world platform decision driven by team scalability, not just preference. ## What It Does - **Read-through caching.** A lookup checks the local cache first; on a miss it calls the external provider, returns the answer, and stores it for next time - with a configurable time-to-live so cached results stay fresh without going stale. - **Multi-provider fallback.** Email verification doesn't depend on a single vendor. It tries one provider and, if that call fails, gracefully falls back to a second - so a single vendor outage never takes verification down. - **Phone intelligence.** Phone-number lookups resolve carrier and country information through a telephony provider, cached the same way. - **Usage analytics.** The service tracks its own activity in daily buckets - cache hits versus live provider calls per source - using atomic, concurrency-safe counters, so the cost savings are measurable. - **Validated, traceable requests.** Every request is schema-validated at the edge and tagged with a unique request ID that flows through the logs for end-to-end tracing. ## Engineering Highlights - **Staged middleware pipeline.** Each endpoint runs as a chain of stages - validate → check cache → call provider → update cache - where each stage only runs if the previous one didn't already resolve the request. This makes the cache-then-fallback logic clean and easy to extend with new providers. - **Cost-aware by design.** The whole point is to minimize paid API calls; the caching layer, the per-request TTL, and the analytics all exist to drive and prove that down. - **Concurrency-safe accounting.** Statistics use atomic increment operations into daily buckets, so counts stay correct under concurrent load without locks. - **Production observability.** Structured logging shipped to a central aggregator, error tracking with performance profiling, request-ID correlation across logs, and self-documenting APIs via an OpenAPI/Swagger UI. - **Resilience details that matter.** Hard timeouts with forced connection cleanup so a slow provider can't hang the service, defensive handling of vendor quirks (odd response codes, response cleanup), and dependency-injected services that keep the layers testable. ## Why It Matters A small service that quietly saves real money. It demonstrates pragmatic backend engineering: read-through caching, graceful multi-vendor failover, production observability, and clean layered architecture - and the discipline of building the same well-specified system idiomatically in two different languages. ## Tech Stack | Layer | Node.js version | Go version | |---|---|---| | **Language** | Node.js | Go | | **HTTP framework** | Koa | Chi | | **Cache / store** | MongoDB | MySQL | | **Validation** | Joi schema validation | Request decoding + checks | | **Providers** | Email validation (two providers, with fallback) + phone lookup | Email validation provider | | **Observability** | Sentry (with profiling), Winston → central syslog | Sentry, structured logging, APM | | **Docs** | OpenAPI / Swagger UI | Static API docs | | **Infra** | Docker, docker-compose | Docker-based deploy | ### User Engagement Tracking URL: https://masnun.me/project/user-engagement-tracking/ Tags: Python, Flask, Celery, Redis, MongoDB ## Overview This is the user-engagement-tracking engine behind a suite of job-board marketing campaigns. Every marketing email and SMS a job board sends carries trackable links and an invisible tracking pixel; this service is what those point back to. It records who opened a message, who clicked which link, and who unsubscribed - then fires those events as webhooks to the originating platform in real time, so the business knows exactly how its outreach is performing. It's built for the unglamorous-but-critical job of being fast and always-on: a redirect or pixel hit has to resolve in milliseconds (a user is waiting on the other end), while the heavier work of recording the event and notifying downstream systems happens asynchronously in the background. ## What It Does - **Click tracking.** Outgoing links are rewritten as short, encoded redirect URLs. When a recipient clicks, Tracer records the event and instantly forwards them to the real destination. - **Open tracking.** A tiny invisible pixel embedded in each email reports back when the message is opened, including where in the message (header or footer). - **Multi-channel.** Handles email and SMS messages alike, across more than twenty distinct job-board brands, each routed to its own destination. - **Real-time event webhooks.** Every tracked event - sent, opened, clicked, unsubscribed - is pushed back to the originating platform as a webhook carrying the relevant context, so downstream systems react immediately. - **Revenue attribution.** Events are tagged with their job source and brand, tying engagement back to where the traffic - and the revenue - came from. ## Engineering Highlights - **Fast front, heavy back.** The user-facing request (redirect or pixel) does the bare minimum and returns immediately; recording the event and posting webhooks is handed off to a background task queue so the redirect never waits on slow downstream work. - **Short, collision-free links.** Message IDs are compressed into short URL slugs using a compact encoding, generated from an atomic counter so IDs never collide even across multiple running instances. - **Bot filtering.** Known crawlers and automated clients are filtered out before an event is counted, keeping engagement metrics honest rather than inflated by bots prefetching links. - **PII protection.** Personal data (email, phone) embedded in tracking URLs is encrypted, not exposed in the clear. - **Multi-tenant routing.** A single deployment serves 20+ brands, each with its own destination URLs and webhook endpoints, driven by configuration rather than separate codebases. - **Operable in production** - distributed background workers, scheduled periodic jobs, error tracking, and a live worker-monitoring dashboard, deployed behind a production app server and reverse proxy. ## Why It Matters Tracer is the kind of infrastructure a marketing operation quietly runs on - invisible when it works, immediately missed when it doesn't. It demonstrates low-latency request handling paired with asynchronous background processing, multi-tenant architecture, real-time event delivery, and the practical concerns that come with running PII-bearing, high-volume traffic in production: bot filtering, encryption, monitoring, and clean separation between the fast path and the heavy path. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Python | | **Web framework** | Flask | | **Background processing** | Celery (distributed workers + scheduled jobs) | | **Broker / cache** | Redis | | **Database** | MongoDB | | **App server / proxy** | uWSGI behind nginx | | **Observability** | Sentry, Flower (worker dashboard), structured logging | | **Integrations** | Per-brand event webhooks, message-queue fallback, S3-hosted assets | ### Logo Service URL: https://masnun.me/project/logo-service/ Tags: Node.js, BullMQ, Redis, MongoDB, Sentry, Docker ## Overview Logo Service is a **company-logo management and delivery service** - the single source of truth for brand logos across a product suite. Any application asks for a company by name and gets back a clean, CDN-hosted logo, in the right format and aspect ratio, matched through a full-text search engine. It's a **team project**: the original logo CRUD, search, and asset pipeline were built by another engineer before I joined. **My contribution** was the layer that turned it from a request/response API into a self-maintaining, observable, production-grade service - background processing, external data enrichment, observability, and the deployment setup - plus a structural refactor of the codebase along the way. ## What I Built ### Background processing layer The service originally did everything inline. I introduced a **dedicated workers layer** backed by a job queue (BullMQ over Redis), moving slow and periodic work off the request path. This included queue configuration, concurrency control, and automatic cleanup of completed and failed jobs so the queue doesn't grow without bound. ### Scheduled jobs & concurrent enrichment I built the **scheduling system** (cron) that keeps the logo data enriched over time. A key job enriches every company with **related keywords pulled from an external keywords service** - and because doing that one company at a time wouldn't scale, I designed it to **distribute the work across concurrent tasks**, fanning the companies out through the queue so enrichment runs in parallel rather than serially. ### Architecture restructure I reorganized the codebase into clear functional areas - **grouping the data layer together, consolidating the web layer, and introducing the workers layer as a first-class part of the system** - and refactored the MongoDB connection so the pool is initialized cleanly and shared. This made the service easier to reason about and set the structure the later work built on. ### Observability I wired in **production monitoring** - error tracking (Sentry) and application performance monitoring (New Relic) across the web, worker, and cron processes - and standardized logging configuration so failures in background jobs surface instead of disappearing silently. ### Deployment & infrastructure I added the **containerization and CI/CD**: the Dockerfile and docker-compose setup, the GitHub Actions workflow, and the process-manager configuration - making the service reproducible to run locally and straightforward to deploy. ## Why It Matters This is the work that makes a service dependable in production rather than just functional in development: moving heavy work to a background queue, scaling enrichment with concurrent task distribution, making the system observable when something breaks, and packaging it for repeatable deployment. It's a focused, honest slice - the operational and data-enrichment backbone layered onto an existing search service. ## Tech Stack (my parts) | Layer | Technology | |---|---| | **Language / Runtime** | Node.js | | **Background jobs** | BullMQ (workers, concurrency, auto-cleanup) over Redis | | **Scheduling** | node-cron | | **Data enrichment** | External job-keywords service, fanned out across concurrent tasks | | **Database** | MongoDB (connection-pool refactor) | | **Observability** | Sentry, New Relic, structured logging | | **Infra / deploy** | Docker, docker-compose, GitHub Actions, PM2 | *Built on an existing service whose core (Express API, Elasticsearch search, S3/CDN asset pipeline) was authored by another engineer.* ### Text Messaging Platform URL: https://masnun.me/project/text-messaging-platform/ Tags: Python, Node.js, React, Celery, Koa, MongoDB ## Overview A **multi-tenant SMS job-alert platform** that I designed, built, and ran end to end - ingesting leads, scheduling personalized text alerts, delivering them across multiple carriers, handling opt-outs and replies, and reporting the revenue back to the business. It powered daily SMS job alerts across more than twenty job-board brands. I built this **twice**. The first version was in **Python** (Flask + Celery), which I developed and operated for several years. As the system grew I **rewrote the backend in Node.js** (Koa + a Redis-backed job queue) for a cleaner architecture, and built a dedicated **React management-and-analytics dashboard** on top. The three repositories - original Python service, Node.js rewrite, and dashboard - are really one product across its lifecycle. > *Note: this is a separate, earlier system from the [Go-based SMS Delivery Platform](#/project/sms-delivery-platform) elsewhere in this portfolio. This one is the lead-alert messaging platform and its rewrite; that one is a later high-throughput delivery engine.* ## What It Does - **Lead ingestion.** Accepts leads over an API - phone, location, job interest, attribution - validating and deduplicating them across every list and a cold-lead store so the same person isn't messaged twice. - **Personalized job alerts.** Composes each message from live job listings pulled from external job-board feeds, personalized per recipient, with rotating ad creatives - sent through short, trackable links. - **Timezone-aware scheduling.** Alerts go out at the right local time for each recipient, not a single global moment - non-trivial when batching across the whole country. - **Multi-carrier delivery.** Routes messages through several SMS providers for redundancy and cost, with per-list gateway configuration and graceful fallback when a provider fails. - **Two-way handling & compliance.** Processes inbound replies - auto-unsubscribing on STOP (tolerant of misspellings), serving "more jobs" follow-ups, and enforcing a global opt-out blocklist. Also auto-unsubscribes inactive recipients. - **Delivery & click tracking.** Provider webhooks update delivery state; short-link clicks are tracked - all feeding analytics. - **Revenue attribution.** Ties earnings back to source, list, and template, with per-brand profit-share accounting. ## The Dashboard The React/Material-UI dashboard is the control room for the whole platform: - **Analytics** - date-range stats broken down by source, carrier, keyword, ad type, and template, with multi-series charts over dozens of metrics. - **List management** - full CRUD over messaging lists, each with its own schedule, gateway, cadence, and a rich rule engine (carrier targeting, dedup, reactivation, incoming-lead handling). - **Multi-tenant accounting** - aggregates revenue across 20+ partner backends at once, with graceful handling when one is unavailable. - **Role-based access** - admins see full granular metrics; partners see a restricted view of their own numbers. ## Engineering Highlights - **Process separation.** Web API, background workers, and the scheduler run as independent processes, so ingestion, sending, and event handling scale and fail independently. - **Queue-driven, carefully serialized.** Fine-grained queues with deliberately tuned concurrency prevent duplicate sends and race conditions on per-lead state. - **Multi-provider abstraction.** A pluggable gateway layer hides the differences between half a dozen SMS providers (REST and XML APIs alike) behind one interface. - **Privacy in tracking.** Personal data carried through click-tracking URLs is encrypted, not exposed. - **Resilience & operability.** Retries with backoff on sends, error tracking, and structured logging throughout. ## Why It Matters This is a system I owned across its entire lifecycle - from the original build to a full rewrite to the tooling around it - and ran in production for years. It demonstrates the hard parts of messaging at scale: timezone-correct scheduling, multi-vendor delivery with failover, two-way compliance handling, accurate multi-tenant revenue accounting, and a real operator-facing dashboard. The same domain, solved once in Python and again, better, in Node. ## Tech Stack | Layer | Technology | |---|---| | **Initial version** | Python, Flask, Celery, MongoDB, Redis | | **Rewritten backend** | Node.js, Koa, Bull (Redis-backed queues), MongoDB | | **Dashboard** | React, Material-UI, Redux Toolkit, Chart.js | | **Processes** | Separate web / worker / scheduler processes | | **Delivery** | Multiple SMS providers / carriers, per-list routing & fallback | | **Integrations** | External job-board feeds, provider delivery & click webhooks | | **Observability** | Sentry, structured logging | | **Infra** | PM2, multi-tenant per-brand deployment | ### Email Job-Alert Platform URL: https://masnun.me/project/email-job-alert-platform/ Tags: Python, Celery, MongoDB, Redis, Flask ## Overview A **distributed background-processing platform** that powered daily personalized **job-alert emails** across a network of eight job-board brands. It ingests candidate leads from partner boards, validates and deduplicates them, sends each candidate a tailored daily email of matching jobs, tracks how they engage, and prunes the list as people go cold - all run by a fleet of background workers that **scale themselves up and down with the workload**. I designed, built, and operated this single-handedly over roughly four years. It's the email sibling of the [Text Messaging Platform](#/project/text-messaging-platform) - same lead-engagement business, the SMS channel's counterpart. ## What It Does - **Lead ingestion per partner.** Leads arrive from eight partner job boards through a queue. Each is validated (email verification, blacklist and opt-out checks) and deduplicated before being stored. - **Personalized daily alerts.** For every active candidate, the platform pulls matching jobs from multiple external job feeds, composes a personalized email, and sends it through transactional email providers. - **Engagement tracking.** Opens (via tracking pixels), clicks (via short links), unsubscribes and bounces flow back in through provider webhooks and update each lead's engagement state. - **Automatic list hygiene.** Candidates who stop engaging are auto-unsubscribed after a configurable window, keeping deliverability healthy and sending honest. - **Analytics feed.** Every meaningful event - sent, failed, opened, clicked, unsubscribed - is emitted to a stats pipeline for business reporting. - **Compliance built in.** Opt-out handling and a global blocklist are enforced on every send. ## Engineering Highlights - **Self-scaling worker fleet.** A scheduler runs every few minutes, measures the depth of each work queue, and **dynamically spawns workers in proportion to the backlog** - so the system absorbs surges automatically instead of needing manual capacity tuning. This is the heart of the platform. - **Prioritized, segregated queues.** Work is split across separate named queues (incoming leads, welcome emails, sending, events) so latency-sensitive work never gets stuck behind big batch jobs, and each can scale independently. - **Multi-tenant by construction.** A single pipeline - ingest, validate, welcome, queue, send, track, clean up - is parameterized per brand, so eight partner boards run on one codebase with per-partner queues, mailers, and rules rather than eight copies. - **Rate limiting & throttling.** Daily send caps protect provider reputation and stay within limits. - **Resilient delivery.** Per-task retries with context-aware error handling, primary-plus-failover routing for outbound webhooks, and batch pulls from the queue for throughput. - **Operable in production.** Error tracking, centralized structured logging, and proactive alerting - including Slack alerts when cache memory crosses a threshold - kept a high-volume system healthy with a single operator. ## Why It Matters This is a system I owned completely, end to end, for years - and the engineering that stands out is the operational maturity: a worker fleet that scales itself to demand, clean multi-tenant abstraction across eight brands, real engagement-driven list hygiene, and the observability to run it all without a team. It's the unglamorous backbone that quietly delivered a business's daily outreach. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Python | | **Task framework** | Celery (distributed workers, prioritized queues, scheduled jobs) | | **Queue / broker** | Message queue + Redis | | **Database** | MongoDB | | **Web layer** | Flask (task submission, health/inspection endpoints) | | **Email** | Transactional email providers + inbound engagement webhooks | | **Job data** | Multiple external job-board feeds | | **Engagement** | Tracking pixels + short-link click tracking | | **Observability** | Sentry, centralized syslog logging, Slack alerting | | **Infra** | AWS (managed Redis, Elasticsearch), cloud queue service | ### Large Scale Job Scraping Service URL: https://masnun.me/project/job-scraping-service/ Tags: Node.js, Puppeteer, Bull, Redis, MongoDB, React ## Overview A **large-scale job-scraping service** that crawls the career sites of hundreds of employers, extracts their open positions, and feeds them as structured data into the wider job-board business. Company career pages are all different - different layouts, different pagination, plenty of JavaScript - so each employer needs its own scraper, and the system needs to run hundreds of them reliably, on a schedule, at scale. It's a **team project**, and I was its **original architect**. I founded the project, designed its structure, and built the core engine - the distributed crawl orchestration, the scheduling, the API, the monitoring dashboard, and the first scrapers that set the template. The team then scaled that foundation out to **750+ employer scrapers** over the following couple of years. ## What I Built ### The crawl orchestration engine The heart of the platform: the machinery that turns "run all the scrapers" into reliable, distributed work. I built the **queue-based job-distribution system** (Bull over Redis) that runs many headless-browser scrapers concurrently with tuned concurrency and lock durations, so hundreds of crawls execute in parallel without stepping on each other or losing work to stalls. I designed the **store and aggregate tasks** that collect scraped jobs and roll them up, and **decoupled job distribution** from scraping so the two scale independently. ### Crawl tracking & stats I implemented the **crawl-ID system** that ties every scraped job back to the specific crawl run that produced it - giving the platform per-crawl and per-employer statistics, finish-status tracking, and job counts broken down by scraper. This is what makes a sprawling fleet of scrapers observable instead of a black box. ### Scheduling, API & CLI I built the **cron-driven scheduling**, a **CLI** (for running and testing scrapers on demand), an **HTTP module** and the **web API** exposing crawl status, job counts, and crawl stats - the control surface the rest of the system and the dashboard talk to. ### The monitoring dashboard I built the initial **React dashboard** that surfaces crawl activity, per-employer job counts, and run status - the operator's window into what the fleet is doing. ### The scraper pattern I wrote the **first batch of employer scrapers** myself, establishing the shared structure and helpers (headless-browser handling, multi-page pagination, normalization) that every later scraper followed - the template the team used to scale to hundreds. ### Operations Headless-browser tuning for reliable large-scale crawling, job-retention and old-crawl cleanup to keep the queue healthy, environment-aware logging, and the deployment setup. ## Why It Matters This is the kind of contribution that's easy to undersell and hard to do: not the hundreds of individual scrapers, but the **engine that makes hundreds of scrapers possible** - distributed orchestration, crawl tracking, observability, and a clean template pattern, architected so a team could scale it 8× without re-architecting. I set the foundation; it held. ## Tech Stack (my parts) | Layer | Technology | |---|---| | **Language / Runtime** | Node.js | | **Scraping** | Headless browser automation (Puppeteer) | | **Orchestration** | Bull job queues over Redis, tuned concurrency & locking | | **Crawl tracking** | Per-crawl IDs, per-employer stats & finish status | | **Database** | MongoDB | | **Scheduling / CLI** | Cron-driven scheduler, Commander-based CLI | | **API / web** | HTTP API for crawl status, job counts, stats | | **Dashboard** | React monitoring UI | *A team project that I architected and seeded; it was scaled out to 750+ employer scrapers by the team afterward.* ### Lead Distribution Router URL: https://masnun.me/project/lead-distribution-router/ Tags: Python, TypeScript, Node.js, Celery, Koa, MongoDB ## Overview A **real-time lead distribution router** - the hub that sits in the middle of a lead-generation business and fans every incoming lead out to all the systems that need it, the instant it arrives. A lead comes in through one API; this service enriches it, decides where it belongs, and dispatches it simultaneously to a primary consumer, the SMS platform, and a search index - falling back to a queue if any destination is down so a lead is never dropped. I designed and built it solo - **first in Python** (Flask + Celery), which I ran in production, then **rewrote it in Node.js and TypeScript** for a cleaner, more responsive architecture. It's the connective tissue between several of the other systems in this portfolio - including the [Heimdall verification gateway](#/project/heimdall-api-gateway) and the messaging platforms. ## What It Does - **One front door, many destinations.** A lead is POSTed to a single endpoint and the router dispatches it to every downstream that needs it - the primary lead consumer, the SMS messaging system, and a search/analytics index - in real time. - **Enrichment on the way through.** Before routing, each lead is enriched: its email is verified for deliverability via an external verification service, its timezone is resolved from its ZIP code so downstream systems know when it's appropriate to contact the person, and the job-title it searched for is normalized - fuzzy-matched against a canonical job taxonomy and stripped of noise (brand names, shift and employment-type labels) so downstream matching is consistent. - **Smart, board-aware routing.** Routing decisions are driven by the lead's source and target market (for example, a separate path for UK leads), with guards that reject self-referential leads to prevent routing loops. - **Never lose a lead.** Every dispatch validates the downstream's response - not just the status code but that the body is well-formed - and on any failure the lead is handed to a backup queue for retry instead of being lost. - **Multiple channels.** Dedicated routing paths handle different SMS providers, each with its own queue. ## Engineering Highlights - **Real-time fan-out with failover.** The core value is reliable one-to-many dispatch. Each destination call checks the response is genuinely healthy before considering it delivered; anything else falls through to a durable backup queue. The result is at-least-once delivery to every consumer without blocking the inbound request. - **Queue-driven throughput.** Distribution runs through Redis-backed job queues with tuned concurrency, so the API accepts leads instantly and the heavy fan-out happens asynchronously. A live queue dashboard makes in-flight work visible. - **O(1) timezone resolution.** Rather than calling an external geolocation API per lead, timezones are resolved against an embedded ZIP-to-offset table - an in-memory lookup that adds no latency and no external dependency to the hot path. - **Fault-tolerant storage.** Lead history is persisted to a replica-set database for durability. - **Aggressive queue hygiene.** Completed jobs are removed immediately and failed jobs retained briefly for inspection, with scheduled cleanup, so the queue never bloats under sustained load. - **Production-grade lifecycle.** Process signal handling closes queues cleanly on shutdown, and uncaught errors and rejections are captured and reported before exit - wired to error tracking and centralized logging throughout. ## Why It Matters Distro is the kind of small, central service that everything else quietly depends on: if it's down or drops data, the whole lead pipeline feels it. It demonstrates real-time fan-out architecture, defensive integration with unreliable downstreams (validate-then-failover), latency-conscious enrichment, and the operational discipline - graceful shutdown, observability, queue hygiene - that keeps a hub like this dependable. A clean, focused TypeScript service doing one important job well. ## Tech Stack | Layer | Technology | |---|---| | **Original version** | Python, Flask, Celery (Redis broker), MongoDB | | **Rewritten version** | TypeScript, Node.js | | **Web framework** | Koa (rewrite) / Flask (original) | | **Queues** | Bull (Redis-backed), with a queue-monitoring dashboard | | **Database** | MongoDB (replica set) | | **Enrichment** | External email-verification service, embedded ZIP→timezone lookup | | **Routing targets** | Primary lead webhook + backup queue, SMS platforms, search index | | **Observability** | Sentry, Winston → centralized logging | ### Worker Monitoring & Background Jobs URL: https://masnun.me/project/worker-monitoring-service/ Tags: Python, Celery, Redis, Flower, Slack, MongoDB ## Overview A shared **background-jobs and worker-monitoring service** - a Celery-based utility that ran an assortment of miscellaneous scheduled tasks for a job-board business, and, most importantly, **watched over the other background-worker fleets** and raised the alarm when one went down. It's a **team project** I built with another engineer. My main contribution was the **health-monitoring and alerting subsystem** - the part that keeps an eye on the platform's other Celery workers and tells a human the moment something breaks - along with the service's Celery foundation, observability wiring, and stats processing. My collaborator built the bulk of the miscellaneous business tasks. ## What I Built ### Worker health monitoring & alerting The core of my work. Across the platform, several services ran their own pools of Celery workers (the SMS platform, the engagement tracker, and others). When one of those pools silently died, nobody knew until something downstream broke. I built a **monitoring system that periodically inspects each worker fleet's live status** - querying the queue/worker introspection layer - and **detects when expected workers are missing or unresponsive**. I iterated on the detection itself ("a more effective way of detecting worker status") to cut false positives, and wired it to **post down-and-recovery alerts to Slack**, so the team learns about an outage - and its resolution - in real time rather than after the fact. ### Celery foundation & observability I set up the service's Celery application, settings, signal handlers, and task routing, and wired in **error tracking (Sentry) and application monitoring (New Relic)** across the tasks - including tuning monitoring to alert only on genuine errors to keep the noise down. ### Stats processing I built and then **optimized the stats-handling pipeline** (including lock tuning and removing a contended task lock), and contributed the Elasticsearch processing and scheduler pieces. ## Why It Matters This is operations engineering - the unglamorous work that makes a distributed system trustworthy. A platform made of many independent worker pools is only as reliable as your ability to notice when one stops. The monitoring-and-alerting subsystem I built turned silent worker failures into immediate, actionable Slack alerts with automatic recovery notifications - exactly the kind of safety net that lets a small team confidently run a lot of moving parts. ## Tech Stack (my parts) | Layer | Technology | |---|---| | **Language** | Python | | **Task framework** | Celery (workers, scheduled jobs) | | **Monitoring** | Worker-fleet introspection (Flower), Redis | | **Alerting** | Slack down/recovery notifications | | **Observability** | Sentry, New Relic | | **Data** | MongoDB, Elasticsearch (stats processing) | *A team project; I built the worker-monitoring/alerting subsystem, Celery foundation, observability and stats processing. The miscellaneous business tasks were largely built by a collaborator.* ### Infrastructure Health Monitor URL: https://masnun.me/project/infrastructure-health-monitor/ Tags: Go, Chi, Redis, Slack, Cron ## Overview A lean **infrastructure health monitor and auto-remediation service**, written in Go, that watched over an entire microservices platform and acted the moment something went wrong. It continuously checks that every internal service is up, keeps an eye on the memory pressure of the platform's caches, alerts the team on Slack when something breaks - and, for one well-understood failure mode, **fixes it automatically** before a human even sees the alert. I designed and built it solo. It's the always-on watchdog that let a small team trust a sprawling system of independent services to keep running. ## What It Does - **Service uptime monitoring.** On a short interval it health-checks every service in the platform - roughly half a dozen internal APIs - with a timeout, and treats any error or bad status as down. - **Cache memory monitoring.** It periodically inspects the platform's Redis/ElastiCache clusters, reading their live memory usage. - **Smart Slack alerting.** When a service goes down it posts an alert; when it comes back, it posts a recovery notice. Crucially, it alerts **once** per outage rather than on every failed check. - **Automatic remediation.** When a cache cluster's memory crosses a safe threshold, the monitor doesn't just warn - it **flushes the cache automatically**, then re-checks and reports the reclaimed memory, resolving a recurring operational headache without waking anyone. ## Engineering Highlights - **Idempotent, fatigue-free alerting.** The naive version of a monitor spams you every cycle a service stays down. I made alerting **state-aware**: the down/up state of each service is tracked in Redis, so the team gets exactly one "down" alert and one "recovered" alert per incident - no noise, no missed recoveries. This is what makes a monitor something people actually keep enabled. - **Automated self-healing.** Detecting a problem is half the job; the memory monitor closes the loop by remediating the most common cause of cache failures itself, then verifying the fix - turning a recurring 2 a.m. page into a logged, self-resolved event. - **Clean concurrent design.** The HTTP surface and the background monitoring run as coordinated goroutines, with graceful shutdown via wait-group coordination and a bounded timeout so the process exits cleanly on signal. - **Config-driven.** Every monitored service, cache cluster, schedule, and integration is declared in a single configuration file - adding a new service to watch is a config change, not a code change. - **Layered observability.** Structured logging fans out to both error tracking and centralized log aggregation, so the monitor is itself observable. ## Why It Matters This is pure operations engineering - the safety net under everything else. A platform built from many small services needs something watching the whole, and ideally something that can heal the easy failures on its own. Guardian did both: state-aware alerting that respects people's attention, and closed-loop auto-remediation that quietly fixed the most common failure mode. It's a small, sharp Go service that punched well above its line count in operational value. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Go | | **HTTP** | Chi router | | **State / targets** | Redis (down-state tracking + cache monitoring) | | **Scheduling** | Cron-driven background tasks | | **Alerting** | Slack (state-aware down/recovery notifications) | | **Remediation** | Threshold-triggered automatic cache flush + verification | | **Concurrency** | Coordinated goroutines, graceful shutdown | | **Observability** | Sentry, centralized syslog logging | ### Email Open-Tracking Pixel Service URL: https://masnun.me/project/pixel-tracking-service/ Tags: Go, Echo, Goroutines, Elasticsearch, IronMQ ## Overview A high-performance **email open-tracking service**, written in Go. It serves the invisible 1x1 pixel embedded in marketing emails: when a recipient opens a message, their email client loads the pixel, and this service records the open - capturing who, when, and from where - then hands the event off to the analytics pipeline. Simple in concept, demanding in practice, because it has to answer an enormous volume of pixel requests instantly without ever making the email client wait. I designed and built it solo. It's the open-tracking counterpart to the click/redirect side of the [engagement-tracking system](#/project/user-engagement-tracking) - the piece that turns "email opened" into data. ## What It Does - **Serves the tracking pixel.** A request to a per-message pixel URL returns a tiny transparent PNG immediately, so the recipient's email renders normally and instantly. - **Records the open.** From each request it captures the IP address, user agent, hostname, timestamp, and any campaign/lead metadata passed in the URL - and derives the recipient's email domain. - **Routes events downstream.** Every open is published to a message queue for the engagement pipeline and indexed into a search store for analytics dashboards. - **Multi-tenant.** A single deployment serves several email brands, mapping each incoming hostname to its own project bucket and event queue. ## Engineering Highlights This is a latency- and throughput-sensitive service, and the design reflects that: - **Never make the client wait.** The HTTP handler returns the pixel **immediately** and does all the real work - queue publish, search indexing - asynchronously on a background goroutine. Recording an open never adds latency to serving it. - **Pixel served from memory.** The PNG is loaded from disk once at startup and served from memory on every request - zero per-request disk I/O on the hot path. - **Buffered-channel decoupling.** Incoming events are pushed onto a buffered channel that a dedicated worker goroutine drains sequentially. This absorbs bursts, decouples the HTTP layer from slower downstream writes, and keeps concurrency bounded - no goroutine explosion under load, no locks needed thanks to channel-based synchronization. - **Failure-isolated.** Errors talking to the queue or search store are logged and reported, never propagated back to the pixel response - a downstream hiccup can't break email rendering for recipients. - **Observability built in.** Application performance monitoring, error tracking, and centralized structured logging across the request path. ## Why It Matters Pixelz is a textbook example of building for high volume at low latency in Go: serve the cheap thing instantly, do the expensive thing asynchronously, and bound your concurrency with channels. It demonstrates exactly the systems instincts that matter for request handling at scale - non-blocking I/O, in-memory hot paths, backpressure-friendly buffering, and failure isolation - in a small, sharp, single-purpose service. It quietly recorded the opens behind a whole network's email marketing. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Go | | **HTTP framework** | Echo | | **Concurrency** | Goroutines + buffered channel + single drain worker | | **Event sink** | Message queue (per-project) + search store for analytics | | **Multi-tenancy** | Hostname → project routing | | **Observability** | APM, error tracking, centralized logging | ### Blockchain From Scratch (Go) URL: https://masnun.me/project/blockchain-from-scratch/ Tags: Go, Chi, SHA-256, Learning ## Overview A **from-scratch minimal blockchain**, built in Go to understand how blockchains actually work under the hood. Rather than read about it, I implemented the core data structure myself: a chain of cryptographically linked blocks, exposed through a small REST API. It's a focused learning exercise - built in a day in early 2018 - not a production system, and I'd rather present it honestly as that: a curiosity-driven dive into the fundamentals. ## What It Does - **Builds a chain of blocks.** Each block holds its data, a timestamp, the hash of the previous block, and its own hash - so every block is cryptographically chained to its predecessor, the property that makes a blockchain tamper-evident. - **SHA-256 linking.** A block's hash is computed (SHA-256) over its data, timestamp, and the previous block's hash. Change any earlier block and every subsequent hash no longer matches - the chain breaks. - **Genesis block.** The chain bootstraps from a genesis block with no predecessor. - **REST API.** Two endpoints: add a new block with a JSON payload, and fetch the full chain - built on the Chi router with request logging middleware. ## What I Learned The point was the fundamentals, and they came through clearly: how hash-linking creates immutability, why each block must commit to the previous hash, and how a genesis block anchors the chain. I deliberately kept the scope tight - the chain lives in memory and there's no proof-of-work or mining - so the cryptographic linking idea stayed front and center rather than getting buried in consensus machinery. It's the kind of small build I reach for when I want to *understand* something rather than just use it. ## Honest Scope This is a learning project, and I'm listing it as one. No persistence, no proof-of-work, no networking or consensus - just the core idea of a cryptographically linked chain, implemented cleanly in idiomatic Go. It reflects how I like to learn: build the smallest real version of a thing to see how it ticks. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Go | | **HTTP framework** | Chi router + logging middleware | | **Crypto** | SHA-256 hash linking | | **State** | In-memory chain | ### Custom Background-Worker Framework URL: https://masnun.me/project/custom-worker-framework/ Tags: Python, Flask, Redis, RQ, MongoDB, Framework Design ## Overview A **background-worker framework I built from scratch** in Python, and the production lead-processing application that ran on top of it. Long before reaching for an off-the-shelf task queue, I wanted a clean way to write background jobs where all the cross-cutting concerns - queue access, database connections, logging, error reporting, lifecycle - were handled *once*, by the framework, so each job only had to express its own business logic. So I built one. It powered a job-board business's email and SMS lead pipelines for roughly two years. This was foundational, early work (2015–2017) and one of my favorite things I've built: not using a framework, but *designing* one. ## The Framework The core idea: a worker is a plugin. Every background job subclasses a single `Worker` base class and implements one method - `run()`. Everything else comes for free: - **Dependency injection.** Each worker is handed its configuration, a logger, and its payload. Database, queue, and Slack clients are exposed as **lazily-initialized properties** - a connection is only opened the first time a worker actually touches that service, so a job never pays for clients it doesn't use. - **Centralized error handling.** If a job throws, the base class catches it, logs the full traceback with a unique ID to centralized logging, and posts a color-coded alert to Slack - escalating to a direct message for anything unhandled. A worker can also opt to *recover*: override one method to, say, re-queue the items it didn't finish, and the failure is treated as handled instead of escalated. Individual jobs never have to write error plumbing. - **Two execution modes, one code path.** The same worker runs either from the **command line** (for cron and manual runs) or under a **long-running daemon** that listens on a Redis pub/sub channel and dispatches jobs into a thread pool - sized per task. Both paths funnel through the same orchestrator, so a job behaves identically however it's triggered. - **Graceful shutdown.** The daemon traps termination signals, stops accepting new work, and waits for in-flight jobs to finish before exiting - no dropped work on deploys. - **Structured, observable logging.** Custom log formatters produce colored output for local development and structured JSON shipped asynchronously to a central log stack in production - non-blocking, so logging never slows a job. Adding a new background job to the system was nearly zero-boilerplate: subclass `Worker`, write `run()`, register a name. Around twenty production jobs were built this way. ## The Application On top of the framework ran a full **lead-qualification and engagement pipeline** for a job board: onboarding new leads with verification emails, sending daily personalized job-alert emails and SMS, processing delivery and engagement webhooks, and automating the lead lifecycle - unsubscribing people who stopped engaging, pausing inactive recipients, and rolling up daily stats. It integrated email and SMS providers, job-feed APIs, geolocation, search, and an internal email-verification service. The lead-lifecycle engine in particular was a careful state machine driven by precise database queries over each lead's engagement history. ## Why It Matters Anyone can wire up a task queue; this project shows I can **design the abstraction itself** - separating framework concerns from application concerns, making the right calls about dependency injection, lifecycle, failure recovery, and observability, and doing it in a way that made every job after the first trivial to write. The framework choices were deliberate and held up across two years and twenty-plus production workers. It's the early work where I learned to think in terms of platforms, not just programs. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Python | | **Framework (mine)** | Custom worker base class, orchestrator, DI, lifecycle & logging | | **Web** | Flask (webhook → enqueue API) | | **Queues** | Redis (RQ + pub/sub control plane), message queue for tasks | | **Concurrency** | ThreadPoolExecutor, per-task sizing, graceful shutdown | | **Database** | MongoDB | | **Search** | Elasticsearch | | **App integrations** | Email & SMS providers, job-feed APIs, geolocation, internal email verification | | **Observability** | Centralized logging (async), Slack error reporting | ### SMTP Email Verification Service URL: https://masnun.me/project/smtp-email-verifier/ Tags: Go, Echo, SMTP, DNS, MySQL ## Overview A **real email-verification microservice** written in Go that checks whether an email address is actually deliverable - not by guessing from a list of known providers, but by talking to the recipient's mail server directly. Given an address, it confirms the format is valid, finds the domain's mail servers, and performs an SMTP handshake to ask the server whether the mailbox exists - caching the verdict so the same address is never re-checked. I built it solo in early 2017. It's an early, lower-level cousin of the later [Heimdall verification gateway](#/project/heimdall-api-gateway): where Heimdall caches results from third-party verification vendors, this service *is* the verifier - it does the network-level checking itself. ## What It Does - **Syntax validation.** A precise regular expression rejects malformed addresses before any network work happens. - **MX lookup.** It resolves the domain's mail-exchange (MX) DNS records to find the real mail server responsible for the address - caching the lookup in memory so a busy domain is only resolved once. - **SMTP deliverability check.** It opens an SMTP connection to that mail server and walks the handshake - `MAIL FROM`, then `RCPT TO` for the target address - to confirm the server will accept mail for that mailbox. This catches non-existent addresses that pass every syntactic check. - **Persistent caching.** Verified results are stored in a database keyed uniquely by address, so a repeat verification is an instant cache hit instead of another network round-trip. - **Clear verdicts.** It returns a simple deliverable/not-deliverable answer, surfacing the mail server's own response code when an address is rejected. ## Engineering Highlights - **Verification at the protocol level.** The interesting part is doing real SMTP - most "verifiers" only check syntax and maybe MX. By actually performing the `RCPT TO` exchange, this service detects addresses that look perfect but don't exist, which is exactly the kind of bad lead a business wants to filter before spending money mailing it. - **Two-layer caching.** An in-memory MX cache avoids repeated DNS lookups within a run, and a persistent database cache avoids re-verifying any address ever seen before - two different time horizons, each with the right store. - **Lean and fast.** Built on a lightweight Go HTTP framework with a single focused endpoint and no heavyweight dependencies - a small service that does one thing well. ## Why It Matters This is the kind of focused systems work I enjoy: drop below the API abstractions and speak the actual protocol. It demonstrates real understanding of how email delivery works - DNS, MX records, the SMTP conversation - plus pragmatic caching to make something network-bound feel instant. It was the early building block that fed clean, deliverable leads into the rest of the platform. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Go | | **HTTP framework** | Echo | | **Verification** | Regex syntax check, DNS MX lookup, live SMTP `MAIL`/`RCPT` handshake | | **Caching** | In-memory MX cache + persistent database cache (MySQL via ORM) | ### Campaign & Path Routing Engine URL: https://masnun.me/project/campaign-routing-engine/ Tags: Node.js, Koa, BullMQ, Redis, MongoDB ## Overview A **campaign-and-path routing engine** for a staffing business: given a search (a keyword and a location), it decides which jobs to surface by running them through reusable, configurable filtering rules. I founded this service and built its functional core - the campaign model, the filtering pipeline, and the path-processing orchestration. A second engineer later added request validation and docs. The idea is to turn "which jobs should this lead see?" from hard-coded logic into **data-driven configuration** that non-engineers can compose. ## What I Built ### Campaigns - configurable filtering rules A **campaign** is a named set of filters bound to a job source. Each filter is a small rule - *only* these origins, *block* those, *match* this keyword - expressed as data, not code. Processing a campaign means: fetch jobs for the given search from the job feed, run every filter against each job's metadata, and keep only the jobs that pass all of them. One failing filter rejects the job. I built the campaign model, its storage, and the filter-operator engine (allowlist / denylist / exact-match, with sensible handling of single values versus lists). ### Paths - composing campaigns A **path** is a named collection of campaigns. Processing a path applies *all* of its campaigns to the same input search and aggregates the results - so a path is a reusable routing strategy assembled from smaller rule sets. I designed paths to **process their campaigns in parallel**, gracefully tolerating individual failures: one broken campaign logs its error and drops out without taking down the rest of the path. ### The service around it I set up the whole service skeleton: a cleanly **layered architecture** - HTTP transport, service layer, and utilities kept strictly separate, with no business logic leaking into request handlers - plus the API endpoints (create campaign, create path, process path), a job-feed client, MongoDB persistence, a background-worker setup, and cron with **distributed locking** so scheduled work never double-runs across horizontally scaled instances. ## Engineering Highlights - **Configuration over code.** The filtering logic lives in stored campaign definitions, so routing behavior changes by editing data, not deploying code. - **Parallel, fault-tolerant processing.** Paths fan their campaigns out concurrently and aggregate only the successes, so any single campaign erroring never sinks the whole request. - **Clean layering.** Transport → services → utils separation makes the core testable and the responsibilities obvious - the kind of structure a team can extend without friction. - **Horizontal-scale ready.** Redis-backed distributed locks on scheduled jobs and graceful shutdown make it safe to run multiple instances behind an orchestrator. ## Why It Matters This is a compact example of turning bespoke business logic into a configurable engine - the difference between writing a filter and building the system that lets anyone compose filters. The campaign/path model, the parallel fault-tolerant processing, and the clean layered foundation are all mine, and they set the shape the service grew into. ## Tech Stack | Layer | Technology | |---|---| | **Language / Runtime** | Node.js | | **Web framework** | Koa | | **Background jobs** | BullMQ over Redis | | **Scheduling** | node-cron with Redis distributed locking | | **Database** | MongoDB | | **Integration** | External job-feed API | | **Observability** | Sentry, Winston | | **Infra** | Docker | *I built the founding core - campaign model, filter engine, path processing, and the layered service skeleton. A second engineer later added request validation and documentation.* ### Real-Time Campaign Analytics Platform URL: https://masnun.me/project/realtime-analytics-platform/ Tags: TypeScript, Koa, React, Redux, MongoDB, Redis ## Overview A **full-stack, real-time marketing analytics platform** - the live dashboard the business actually watched to see how its email and SMS campaigns were performing, minute by minute. Events stream in from every channel (email sends/opens/clicks, SMS activity, job clicks, unsubscribes), get aggregated server-side into time-bucketed metrics, and surface in a rich React dashboard of charts, breakdowns, and cohort reports. It was one of my largest and longest-running projects, built and evolved over five years. I drove this end to end: I built the **backend almost entirely** and **led the frontend**, partnering with one other engineer on the UI. ## What It Does - **Ingests events in real time.** Upstream systems - the engagement tracker, the lead distributor, the SMS and email platforms - push events to the platform's queue endpoints continuously. - **Aggregates as it goes.** A background pipeline runs every minute, draining the queues and rolling raw events up into multi-dimensional daily stats: by channel, source, provider, template, campaign type, and device - all bucketed to a consistent timezone. - **Visualizes everything.** The React dashboard renders time-series charts and segmented breakdowns of sends, opens, clicks, and unsubscribes, with date-range pickers and year-over-year trend comparison. - **Goes beyond vanity metrics.** Cohort analysis (retention and value by signup cohort), per-source revenue/profit, and traffic breakdowns turn raw activity into decisions. - **Manages the campaigns too.** Beyond analytics, it includes management surfaces - email/SMS template editing, lead-feed configuration with selectable optimization algorithms, incoming-SMS log review - and CSV/Excel report exports. ## Engineering Highlights ### Real-time aggregation pipeline (backend) The core challenge was turning a firehose of individual events into live, queryable metrics without falling behind. I built a **concurrent, fault-tolerant consumption pipeline**: it drains a high-volume external queue in parallel batches plus a local Redis queue, with the batch count **capped to apply graceful backpressure** so a spike can't overwhelm the system. Each event is de-normalized into several aggregation trees (by source, provider, device, campaign…), and the day's stats document is **read, merged, and written back incrementally** so concurrent updates never clobber each other. A schema-flexible document design means a brand-new tracking dimension can be added without a migration. ### Performance & resilience A Redis caching layer with sensible TTLs shields the database from repeated dashboard queries. Per-queue error isolation means one failing source drops out of a cycle without halting the pipeline. Scheduled jobs handle the heavier daily rollups (cohorts, active counts) off the real-time path. Error tracking, centralized logging, and Slack alerting keep the whole thing observable. ### Full-stack delivery On the frontend I led a React + Redux single-page app with charting, autocomplete search, date-range controls, and drag-and-drop configuration - talking to a typed Koa/TypeScript API with JWT auth. Owning both halves meant the data model, the API, and the visualizations were designed together rather than bolted on. ## Why It Matters This is enterprise-grade, full-stack systems engineering sustained over five years: high-volume real-time ingestion with backpressure, multi-dimensional incremental aggregation, a caching strategy that keeps dashboards snappy, and a polished operator-facing UI on top - all designed and largely built by me. It's the project where the backend systems work and the product-facing frontend met in one codebase, and I owned the whole span. ## Tech Stack | Layer | Technology | |---|---| | **Backend** | TypeScript, Node.js, Koa | | **Frontend** | React, Redux, React Router, ECharts, Sass | | **Real-time** | Background queue consumption (external MQ + Redis), per-minute aggregation | | **Jobs / scheduling** | Bull queues over Redis, cron-scheduled rollups | | **Database** | MongoDB (replica set), schema-flexible stat documents | | **Caching** | Redis (TTL-based query cache) | | **Auth** | JWT | | **Exports** | CSV / Excel report generation | | **Observability** | Sentry, centralized logging, Slack alerts | ### Multi-Tenant Webhook & Config Hub URL: https://masnun.me/project/webhook-config-hub/ Tags: Go, Chi, Redis, MongoDB, Webhooks ## Overview A **multi-tenant webhook hub and configuration service**, written in Go, that sat at the edge of a job-board network and handled two jobs for nine different brands at once: serving each app its configuration, and receiving the flood of delivery and engagement webhooks from email and SMS providers - classifying each event and routing it onward. It's the single place where "the outside world tells us what happened to a message" was turned into clean, actionable events. I built it solo, start to finish, over roughly four years. ## What It Does - **Per-app configuration API.** Each of nine job-board brands fetches its own settings - email and SMS templates, subject-line pools, ad configurations - from one service, with the right config selected by app. - **Email webhook processing.** It ingests delivery events from email providers and classifies them precisely - hard bounce, soft bounce, spam complaint, unsubscribe, rejection - and decodes inbound messages. - **SMS webhook processing.** It handles SMS delivery callbacks and inbound replies across multiple providers, with **stop-word detection** (recognizing the many ways people type "STOP", plus "more" and "help" keywords) to drive opt-outs and follow-ups correctly. - **Blacklist enforcement.** Opt-outs are recorded to a global blacklist so the network never contacts someone who asked to stop. - **Event fan-out.** Classified events are routed to the right downstream queues and services for each brand. - **Live stats streaming.** Incoming stat events are streamed asynchronously to the analytics platform without blocking the webhook response. ## Engineering Highlights - **Cache-aside with introspection.** Per-app config is served from Redis with a multi-hour TTL, falling back to the database on a miss and writing back. I built a custom cache layer that **tracks its own keys**, so the cache can be inspected and bulk-invalidated through admin endpoints rather than blindly scanning the store. - **Multi-tenant router composition.** Nine brand-specific route groups mount under one service with identical endpoint shapes but app-scoped config lookups - one codebase, nine tenants, no duplication. - **Non-blocking stats pipeline.** Stat events are handed to a channel drained by a pool of worker goroutines sized to the available CPUs, decoupling ingestion from the HTTP response so webhooks stay fast. - **Provider-agnostic event model.** Different email and SMS providers report differently; the service normalizes all of them - bounce classification, stop-word parsing, event-type mapping - into one consistent internal event vocabulary. - **Resilient by default.** Panic-recovery middleware, request logging, body-size limits, and wired-in error tracking and centralized logging. ## Why It Matters This is the unglamorous integration layer that a messaging business lives or dies on: if a webhook hub misclassifies an unsubscribe or drops a bounce, you keep mailing people you shouldn't and your data goes wrong. Built as a lean, single-purpose Go service, it consolidated configuration and event handling for an entire multi-brand network behind one dependable front door - and I owned every line of it for four years. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Go | | **HTTP framework** | Chi router (panic recovery, logging, body limits) | | **Database** | MongoDB (per-app config, blacklist) | | **Cache** | Redis, cache-aside with key tracking + admin invalidation | | **Concurrency** | CPU-sized goroutine pool for async stats streaming | | **Integrations** | Email & SMS provider webhooks, downstream event queues, analytics stream | | **Observability** | Sentry, centralized syslog logging | ### University Exam & Result Management System URL: https://masnun.me/project/university-ems/ Tags: Python, Django, MySQL, Education ## Overview A **university examination and result management system** I designed, built, and maintained single-handedly for the Business Administration Discipline at **Khulna University** - and kept running in production for nearly a decade. It manages the full academic cycle for the department's programs: student course registration, faculty mark entry, multi-stage result tabulation, GPA computation, and official mark sheets - encoding years of accumulated academic rules into software that real administrators, faculty, and students depend on. This is the project I'm quietly proudest of: not the flashiest stack, but a real system, used by a real institution, that I owned end to end from 2014 to 2023. ## What It Does - **Course registration.** Students register for courses each term with add/drop, credit-limit enforcement, special-term handling, retake tracking, and per-student registration locks that freeze submissions after a deadline. - **Component-based mark entry.** Faculty enter marks broken into their real components - attendance, continuous assessment, mid-term, term-final, section assessments, sessional and viva, thesis supervisor/external/viva - with the exact component set depending on the program and course type. - **Multi-role tabulation workflow.** Results move through a real approval chain: instructor enters marks → scrutiny audits them → tabulation finalizes grades and GPAs - each role seeing its own filtered view, with result locks and an audit log recording every change. - **GPA & grading engine.** Letter grades and grade points on a 4.0 scale, computed from the mark components per the department's official scale. - **Mark sheets & reports.** Paginated, print-ready tabulation sheets and result documents. - **Faculty payment tracking.** A dashboard where faculty declare examination work (question setting, invigilation, tabulation, sessional assessment, thesis examination…) against configurable per-program rates, with individual and summary views. ## The Interesting Part: a Real Academic Rules Engine Universities don't have one set of rules - they have many, accreted over years, differing by program and cohort. This system encodes them: - **Program-specific grading.** BBA, MBA, EMBA and Executive MBA - plus their outcome-based-education (OBE) variants - each use a different combination of mark components. The system models all seven configurations. - **Retake grade downgrading.** For BBA retakes above a threshold, the system applies a points penalty before computing the grade - letting a student replace a grade while still penalizing the retake, exactly as the department's policy requires. - **Absent handling, thesis evaluation, sessional courses, cohort-dependent thresholds** (e.g. rules that differ for students who enrolled before a certain year) - all captured as concrete logic rather than left to manual judgment. Getting these right matters: this drives the actual grades on students' transcripts. ## Why It Matters Most projects are measured in months; this one ran for **nine years**. That longevity is the achievement - a solo-built system stable and trustworthy enough to remain the department's system of record across many cohorts, with thousands of students and years of historical data. It shows sustained ownership, careful domain modeling of genuinely complex rules, role-based workflows with proper locking and audit trails, and the patience to keep a real production system correct as policies evolved. It's also work I'm glad I did - software built for my own university that made academic administration measurably easier. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Python | | **Framework** | Django (server-rendered, role-based access) | | **Database** | MySQL | | **Frontend** | Django templates, Bootstrap, jQuery; customized admin | | **Domain** | Academic rules engine - program-specific grading, GPA, retake policy, tabulation workflow | | **Scale** | Thousands of students, multiple programs, 9 years in production (2014–2023) | ### Social Shopping App - REST API URL: https://masnun.me/project/social-shopping-api/ Tags: Python, Django, DRF, MySQL ## Overview A **REST API backend for a social fashion-shopping app** - boutiques and products to discover, social gifting between friends, group "birthday list" wish lists, follows, likes, and orders. I built it as the server side for a mobile app concept: a Django REST Framework API designed to be consumed by a phone client, covering the whole domain from catalog to checkout to social features. It was a focused MVP - built solo over about six weeks in 2016 to stand up a working backend for the product idea quickly. ## What It Does - **Catalog & discovery.** Boutiques (with hours, location, discounts, tags) and products (sizes, pictures, ratings, tags), plus view-tracking and search history to power discovery. - **Social layer.** Users follow boutiques, like products, message each other, and curate private product lists. - **Social gifting.** Send gifts to friends, and run group "birthday lists" - shared wish lists multiple people contribute toward. - **Commerce.** Orders, sales, reservations, product requests, and time-limited exclusive offers. - **Flexible authentication.** A token-based auth service supporting **three login modes through one API** - standard username/password, phone-number, and social-network login - issuing an API token the mobile client carries on every request. ## Engineering Notes - **Mobile-first API design.** Stateless token authentication and a clean resource-oriented REST surface - the right shape for a phone app talking to a server. - **Broad domain modeled fast.** Two-dozen related resources (catalog, social, gifting, commerce) exposed as a consistent CRUD API via DRF's serializers, viewsets, and routers - getting a wide feature surface usable quickly, which is exactly what an MVP needs. - **Pluggable login.** The multi-mode auth (password / phone / social behind one endpoint) anticipated the reality that a consumer app needs several sign-in paths. ## Honest Scope This was an early-stage product backend, not a hardened production system - a six-week MVP to make the concept real and demoable. I'm listing it as that: a complete, working REST API across a genuinely broad consumer domain (commerce + social + gifting), built quickly and cleanly with Django REST Framework. ## Tech Stack | Layer | Technology | |---|---| | **Language** | Python | | **Framework** | Django + Django REST Framework | | **API** | Token auth (password / phone / social), ModelViewSets + routers | | **Database** | MySQL (production), SQLite (development) | | **Media** | Image/file uploads for products, boutiques, gifts | ### Mobile Community Forum Platform URL: https://masnun.me/project/mobile-community-forum/ Tags: PHP, MySQL, Early Work ## Overview A complete **mobile community and forum platform**, built from scratch in PHP - one of my earliest real projects and, the "v5" in its name says it all, one I rebuilt and refined across multiple generations. It was a self-hosted social site for mobile/WAP-era phones: people signed up, posted in forums, messaged each other privately, kept profiles, and saw who else was online. I wrote the whole thing myself - every page, every feature, the database, the moderation tools. I'm including it because it's where I come from. Long before queues and warehouses and Go services, this is the project where I taught myself to build a real, multi-user web application end to end - and people actually used it. ## What It Did - **Forums.** Boards, topics, and posts - create topics, reply, view active discussions, move topics between boards, with a moderation control panel. - **Private messaging.** A full inbox: send, read, reply, forward, and delete private messages, with sent-mail and conversation views. - **User accounts & profiles.** Registration, sign-in, public and extended profiles, account activation, and user moderation tools. - **Presence.** Live "who's online" tracking and member/activity counts. - **Search.** Across posts, topics, users, and private messages. - **Owner control panel.** Admin tooling to run the community - moderate users, manage the site. - **Anti-abuse.** A text-based CAPTCHA on registration, banned user-agent handling, and a "shielded login" gate to block abusive clients - homegrown spam and abuse defenses. ## Why It Matters Everyone's career starts somewhere, and this is mine: a young developer building an entire social platform alone, in raw PHP, because he wanted to - and iterating on it enough times to reach a fifth version. It shows the instinct that's run through everything since: take a whole problem, from database schema to user-facing features to fighting spam, and build the complete thing. The tools have changed enormously; the drive to ship a real product that real people use hasn't. It's a nostalgic piece, and an honest one - early, self-taught work that I'm fond of and that set me on the path. ## Tech Stack | Layer | Technology | |---|---| | **Language** | PHP (procedural, from scratch - no framework) | | **Database** | MySQL | | **Platform** | Mobile / WAP-era web (lightweight HTML) | | **Features built by hand** | Forum, private messaging, profiles, presence, search, moderation, CAPTCHA, anti-abuse | ### 2Deal - eBay Product Search URL: https://masnun.me/project/2deal-ebay-search/ Tags: PHP, Zend Framework, MySQL, jQuery ## Overview **2Deal.de** is a German shopping site that lets people quickly search products on eBay and pick one to buy. It wraps the raw search experience with extra product information and relevant related products, so customers can browse and find what they need with much less friction. I joined to **port the existing application onto the Zend Framework**. I was the sole developer on the effort and handled every task the port required, end to end. ## What It Does - **Fast eBay product search** - customers search and get back matching products ready to buy. - **Enriched product views** - each result is shown with additional information beyond the bare listing. - **Related products** - surfaces relevant alternatives to make browsing and discovery easier. ## My Role The project was a **full migration of an existing application to Zend Framework**, and I owned it alone - architecture, routing, models and data access over MySQL, the eBay-backed search and product pages, and the jQuery-driven front-end behavior. Working solo on a framework port meant taking the existing functionality apart and rebuilding it cleanly within Zend's MVC structure, without losing features along the way. ## Tech Stack | Layer | Technology | |---|---| | **Framework** | Zend Framework (PHP) | | **Language** | PHP | | **Database** | MySQL | | **Front end** | jQuery | ### Animeplex - Automated Anime Aggregator URL: https://masnun.me/project/animeplex/ Tags: PHP, WordPress, MySQL, PHP Simple HTML DOM, jQuery ## Overview **Animeplex** is an automated website that gathers and displays the latest anime videos. It runs largely on its own - pulling fresh content from across the web and presenting it as a browsable WordPress site so visitors always land on the newest episodes without anyone curating by hand. My job was the engine behind it: **scrape a set of predefined anime sources and present the results nicely on the WordPress site.** ## What It Does - **Aggregates anime automatically** - continuously collects the latest videos from a fixed set of source sites. - **Scrapes and normalizes** - extracts the relevant data (titles, episodes, video links, metadata) from each source's markup and feeds. - **Publishes to WordPress** - lands the gathered content into the site so it's displayed cleanly and stays current on its own. ## My Role I built the **scraping and presentation layer**. Using PHP with PHP Simple HTML DOM (plus XML feeds where sources provided them), I parsed each predefined source, pulled out the anime videos and their details, and pushed them into the WordPress site - then made sure they were presented nicely on the front end with JavaScript and jQuery. The result was a hands-off content pipeline: the site keeps itself fresh with the latest anime without manual posting. ## Tech Stack | Layer | Technology | |---|---| | **Language** | PHP | | **Scraping** | PHP Simple HTML DOM, XML feeds | | **CMS** | WordPress | | **Database** | MySQL | | **Front end** | JavaScript, jQuery | ### Deployninja - Painless Repo Deployment URL: https://masnun.me/project/deployninja/ Tags: PHP, Zend Framework, Python, Gearman, Supervisord, MySQL ## Overview **Deployninja** lets you deploy your SVN and Git repositories to your web server in a painless fashion - point it at a repo, and it takes care of fetching the code and getting it onto your servers without the usual manual ceremony. It was built at Leevio. I worked on Deployninja as a **backend engineer**, and I built **all the algorithms that fetch the repositories and upload them to the servers** - the core of what the product actually does. ## What It Does - **Connects to your repositories** - works with both SVN and Git source repos. - **Fetches the code** - pulls the right revision/branch from the repository. - **Uploads to your servers** - pushes the fetched code out to the target web server, painlessly. - **Runs the heavy lifting in the background** - deployment work is queued and processed by long-running workers rather than blocking the user. ## My Role I owned the **repository fetch-and-deploy engine** on the backend. That meant building the logic to talk to SVN (via php-svn) and Git (via GitPython) repositories, fetch their contents, and transfer them onto the destination servers reliably. To keep the experience painless, the work runs **asynchronously**: jobs are dispatched to Gearman and executed by background workers kept alive and supervised by Supervisord, with PHP/Zend Framework on the application side and Python handling parts of the repository and deployment work. The result is a system that turns "deploy my repo to my server" into a single, hands-off action. ## Tech Stack | Layer | Technology | |---|---| | **Application** | PHP, Zend Framework | | **Repository / deploy logic** | Python, php-svn, GitPython | | **Background processing** | Gearman, Supervisord | | **Database** | MySQL | | **Source control supported** | SVN, Git | ### Endless Video - Refactor & Optimization URL: https://masnun.me/project/endless-video/ Tags: PHP, Yii Framework, MySQL, Flash, JavaScript ## Overview **Endless Video** is a video application I came onto as an existing codebase. My work was about making it better and faster rather than building it from scratch: I **refactored and optimized the codebase, fixed existing bugs, added new features, and boosted the application's performance.** ## What I Did - **Refactored the codebase** - cleaned up and restructured existing code to make it more maintainable. - **Optimized performance** - found and removed bottlenecks to make the application noticeably faster. - **Fixed bugs** - worked through existing defects in the running product. - **Added new features** - extended the application with new functionality on top of the existing base. ## My Role This was maintenance-and-improvement engineering on a live product. Working in PHP on the Yii Framework with a MySQL backend - and a Flash-based video layer with JavaScript on the front end - I took an existing application and made it cleaner, more reliable and faster: untangling existing code, profiling and optimizing the slow paths, squashing bugs, and shipping new features without destabilizing what was already there. ## Tech Stack | Layer | Technology | |---|---| | **Framework** | Yii Framework (PHP) | | **Language** | PHP | | **Database** | MySQL | | **Front end / media** | Flash, JavaScript | ### Kuestions - Q&A Platform URL: https://masnun.me/project/kuestions/ Tags: PHP, Zend Framework, MySQL, jQuery ## Overview **Kuestions** is a StackOverflow-like question-and-answer platform - a community site where people post questions and others answer, vote and discuss. I worked on it as part of a team, owning several of its core pieces. ## What I Built - **User login & social integration** - built the authentication system and integrated sign-in with social networks. - **Questions & answers** - worked on the question display and the answering system that the whole platform revolves around. - **Database architecture** - contributed to the data model behind questions, answers and users. - **Ops & tuning** - did some system administration and database profiling to keep things healthy. ## My Role My main responsibility was the **user login system and social-network integration** - letting people sign up and log in, including via their social accounts. From there I worked on the **question display and answering system**, the heart of a Q&A site. I also contributed to the **database architecture**, and pitched in on **system administration and database profiling** to find and smooth out slow queries. Built in PHP on the Zend Framework with a MySQL backend and a jQuery front end. ## Tech Stack | Layer | Technology | |---|---| | **Framework** | Zend Framework (PHP) | | **Language** | PHP | | **Database** | MySQL | | **Front end** | jQuery | ### Kunstreminder - Concert Listings & Alerts URL: https://masnun.me/project/kunstreminder/ Tags: PHP, Zend Framework, MySQL, jQuery ## Overview **Kunstreminder** is a concert-listing application. People follow their favorite musicians and music, and the app notifies them about events where those artists or that music will be available - so fans never miss a show they'd care about. ## What It Does - **Concert listings** - browse upcoming concerts and events. - **Follow artists & music** - users follow the musicians and music they love. - **Event notifications** - when a followed artist or piece of music is playing somewhere, the app lets the user know. ## My Role I worked on building the application - the listings, the follow relationships between users and artists/music, and the notification flow that ties a user's follows to relevant upcoming events. Built in PHP on the Zend Framework with a MySQL backend and a jQuery front end. ## Tech Stack | Layer | Technology | |---|---| | **Framework** | Zend Framework (PHP) | | **Language** | PHP | | **Database** | MySQL | | **Front end** | jQuery | ### Rent Payment Schedule URL: https://masnun.me/project/rent-payment-schedule/ Tags: PHP, Zend Framework, MySQL ## Overview **Rent Payment Schedule** is a web app that lets people calculate and print their rent payment schedules - and even pay their rent online. It comes with both a user control panel and an admin control panel for better management on each side. ## What It Does - **Calculates rent schedules** - works out a tenant's full payment schedule. - **Print-ready output** - schedules can be printed for record-keeping. - **Online rent payment** - tenants can pay their rent directly through the app. - **User control panel** - tenants manage their own schedules and payments. - **Admin control panel** - administrators oversee and manage everything from one place. ## My Role I worked on building the application - the rent-schedule calculation and printable output, the online payment flow, and the two management surfaces (user and admin control panels). Built in PHP on the Zend Framework with a MySQL backend. ## Tech Stack | Layer | Technology | |---|---| | **Framework** | Zend Framework (PHP) | | **Language** | PHP | | **Database** | MySQL | ### TwBoost - Twitter Automation Engine URL: https://masnun.me/project/twboost/ Tags: PHP, Twitter APIs, MySQL, jQuery, Bootstrap ## Overview **TwBoost** is a Twitter automation engine. A user defines a set of keywords and an automated reply message; the engine then periodically searches Twitter for those keywords and posts the replies at random intervals - automating outreach while staying natural enough to avoid looking like a rigid bot. The project was built on top of the Twitter APIs. ## What It Does - **Keyword + reply setup** - the user defines keywords to watch and the reply message to send. - **Periodic search** - the engine regularly searches Twitter for matching keywords via the Twitter APIs. - **Randomized auto-replies** - it posts the defined reply at random intervals, so the automation feels organic rather than mechanical. ## My Role I built the automation engine around the Twitter APIs: the keyword-search loop, the scheduling that runs it periodically, and the randomized-interval reply logic that keeps the automated responses from firing in an obvious, uniform pattern. Built in PHP with a MySQL backend, and a jQuery + Twitter Bootstrap front end for configuration. ## Tech Stack | Layer | Technology | |---|---| | **Language** | PHP | | **APIs** | Twitter APIs | | **Database** | MySQL | | **Front end** | jQuery, Twitter Bootstrap | ## Open Source ### PHPTube URL: https://github.com/masnun/phptube A PHP library that extracts direct YouTube video URIs - in multiple formats - straight from a watch URL. ### Avro Phonetic WP Plugin URL: https://github.com/masnun/avro-phonetic-wp-plugin A WordPress plugin that brings Avro Phonetic Bangla typing to any input - type Bengali phonetically, right in the browser. ### PHAR Maker URL: https://github.com/masnun/pharmaker A small CLI tool that packages a directory of PHP source into a distributable PHAR archive, with CLI and web entry points. ### Super Poster URL: https://github.com/masnun/super-poster A browser-based tool to post to multiple Facebook groups at once, built on the Facebook JavaScript SDK. ### Facebook Profile Photo Generator URL: https://github.com/masnun/facebook-profile-photo-generator A Django app that overlays a custom badge onto a user's Facebook profile photo via Facebook OAuth. ### Django ORM Standalone URL: https://github.com/masnun/django-orm-standalone A starter that lets you use Django's ORM on its own - outside a full Django project - for scripts and small tools. ### FTP Server Monitor URL: https://github.com/masnun/ftp_server_monitor An Android app that monitors the status of an FTP server from your phone. ## Writing ### Async & Concurrency - Async Python: The Different Forms of Concurrency (http://masnun.rocks/2016/10/06/async-python-the-different-forms-of-concurrency/): Threads vs. processes vs. asyncio, the GIL, and when each model actually wins. My favorite single piece. - Exploring Asyncio - uvloop, sanic and motor (http://masnun.rocks/2016/11/17/exploring-asyncio-uvloop-sanic-motor/): Building a full async stack end to end - event loop, web framework and database driver - and what it buys you. - Generators, Coroutines, Native Coroutines and async/await (https://masnun.com/python-generators-coroutines-native-coroutines-and-async-await/): How Python's concurrency model evolved from generators to native coroutines - and why each step happened. - Python asyncio: Future, Task and the Event Loop (https://masnun.com/python-asyncio-future-task-and-the-event-loop/): A look under asyncio's hood at the primitives the event loop actually schedules. - A Quick Introduction to the concurrent.futures Module (https://masnun.com/python-a-quick-introduction-to-the-concurrent-futures-module/): Thread and process pools through one clean executor API, and where each fits. ### Language Internals & Design - Interfaces in Python: Protocols and ABCs (http://masnun.rocks/2017/04/15/interfaces-in-python-protocols-and-abcs/): From informal duck typing to formal contracts with abstract base classes. - Understanding Decorators in Python (https://masnun.com/understanding-decorators-in-python/): Decorators built from first principles - closures, wrapping and why they read the way they do. - Composition Over Inheritance (https://masnun.com/composition-over-inheritance/): Why deep class hierarchies hurt, and how composition keeps designs flexible. ### Go & Distributed Systems - Distributed Task Processing in Go (http://masnun.rocks/2016/11/01/distributed-task-processing-in-golang/): A Celery-style distributed task queue in Go using machinery - the patterns behind background work at scale. - Golang: Building a Telegram Bot for Aggregating Content (http://masnun.rocks/2016/11/05/golang-building-a-telegram-bot-for-aggregating-content/): A real, concurrent Go service end to end - fetching, aggregating and serving content. - Golang Interface (https://masnun.com/golang-interface/): How Go's implicit interfaces work and why they shape idiomatic Go design. ### Real-Time & API Design - Introduction to Django Channels (http://masnun.rocks/2016/09/25/introduction-to-django-channels/): Bringing WebSockets and async to Django - the ASGI shift, explained. - Django Channels: Using Custom Channels (http://masnun.rocks/2016/11/27/django-channels-using-custom-channels/): Going beyond the defaults to model your own message channels. - Deploying Django Channels using Daphne (http://masnun.rocks/2016/11/02/deploying-django-channels-using-daphne/): Taking an ASGI app to production with the Daphne server. - Django Admin: Expensive COUNT(*) Queries (http://masnun.rocks/2017/03/20/django-admin-expensive-count-all-queries/): Diagnosing a real database performance problem hiding inside the Django admin. - Understanding JWT (JSON Web Tokens) (https://masnun.com/understanding-jwt-json-web-tokens/): What a JWT actually is, how it's signed, and where stateless auth fits. - REST APIs: Concepts and Applications (https://masnun.com/rest-apis-concepts-applications/): The principles behind REST before reaching for a framework.