Data & Cloud Engineer · Lagos, Nigeria
Azure data platforms built on a foundation of real network and systems engineering — so the pipeline works, and so does everything it runs on.
I came to data engineering through IT infrastructure, networking, and cloud engineering — which means I think about pipelines the way I used to think about networks: what happens when a link drops, where the bottleneck actually is, and who gets paged.
Today I build cloud data platforms on Azure — Data Factory for orchestration, Databricks and PySpark for transformation, Data Lake for zoned storage, SQL for the modelling layer. The goal is always the same: turn raw, inconsistent source data into datasets people are willing to make decisions on.
The infrastructure background still does work. I've built and run three-tier applications on AWS, designed VPC networking with private endpoints, and handled snapshot-and-AMI disaster recovery. Most data engineers can write the transformation; fewer can tell you why the subnet routing broke it.
I'm also working on where AI genuinely helps a data workflow — quality monitoring, documentation, anomaly explanation — with a firm line: models explain and draft, tests decide.
Four Nordic countries, four ERP exports, four incompatible formats — different delimiters, encodings, date formats, decimal separators, currencies and column names. A medallion platform reconciling all of it into one tested star schema, running end to end on a laptop with no cloud subscription required.
. separator passed to regexp_replace is a regex wildcard — it stripped every character, emptying all 4,000 Danish prices. Denmark would have silently contributed zero revenue had the quality layer not caught it.Migrated a batch ETL workflow to a cloud-native, event-driven pipeline on Azure. Airflow handled orchestration and dependency resolution; Data Lake Storage managed raw-to-curated zoning so reprocessing never hit source systems twice.
An automated data quality layer where deterministic tests decide pass or fail, and an LLM generates plain-language summaries of what broke and where it came from — so stakeholders get an explanation instead of a red square, and engineers start triage with context.
Streaming pipeline ingesting live transaction data via Kafka into a dashboard the business team uses daily to track transaction trends. The design work was less about throughput than about defining "current" when late-arriving events and business-day boundaries disagree.
Refactored a growing Snowflake warehouse — partitioning, query tuning, and workload isolation so competing workloads stopped contending for the same compute. Query times improved for the analytics team alongside the cost reduction.
A complete serverless three-tier web application, built one tier at a time, plus an analytics layer over S3. Self-directed hands-on builds; each write-up documents the design decisions and the failures.
Static front end delivered globally through CloudFront, with the origin bucket never public. Access flows through Origin Access Control, so the distribution is the only path to the objects.
REST API fronting a Lambda function via proxy integration, deployed to a prod stage. API Gateway acts as the traffic manager — it reduces backend load, decides whether a request is authorised, and only then passes it through.
DynamoDB table keyed on userId, with a Lambda function that extracts the ID from the triggering event, queries for the matching record, and handles errors. The access pattern is a single-partition key lookup, which is exactly what the application needs.
Dataset in S3 connected to QuickSight through a manifest file — the map describing where the files sit and how they are structured. Editing the manifest to carry the correct S3 URI is the step everything else depends on.
Worth being direct about this one: the dataset arrived clean, so none of the failure modes that dominate real analytics work — schema drift, nulls in grouping columns, duplicates inflating counts — ever appeared. The transferable part is the connection pattern, not the charting.
I use AI as a working tool, not a demo. The distinction I hold to across every pipeline I build: models explain and draft, tests decide. An LLM is excellent at turning a failure into a readable explanation and at drafting the boring 80% of a transformation. It is not allowed to be the thing that determines whether data is correct — that stays with deterministic assertions I can reason about.
That line is not caution for its own sake. A model that silently passes bad data is worse than no monitoring, because it manufactures confidence. So the architecture is always the same shape: the tests gate, the model narrates.
Outside the pipeline, I use the same tooling to ship things end to end — sites, automation, and video — because a data engineer who can also build and publish is more useful than one who can only hand over a notebook.
Debugging, scaffolding pipelines, translating between SQL dialects, generating documentation from schema and lineage. Used in the desktop app and in Claude Code against real repositories.
Prompt-to-deployed web application — React and Tailwind on TanStack Start. Used to design, build, and ship this portfolio's predecessor to a custom domain.
Workflow automation connecting services without writing glue code for every integration — triggers, transforms, and scheduled runs.
Avatar-led short-form video from purpose-written scripts. Script-driven rather than repurposed, with on-screen text timed as canvas elements.
Generative B-roll and cinematic footage to support narrated video, driven through an MCP connector rather than the web UI.
Called directly inside data workflows for anomaly explanation and plain-language failure summaries — layered on top of dbt tests, never replacing them.
Assignments from the Bravo ’26 bootcamp, plus site builds, all public and linked. Nothing here is a screenshot standing in for something that does not exist.
Scripted short-form video on the practical uses of Claude that hold up in day-to-day engineering work — the ones that survive contact with a real repository, rather than demo material. Written for the format instead of cut down from something longer.
Watch on Instagram →Creator-style delivery to camera, working in the UGC format rather than a polished corporate register.
Watch on Instagram →A scheduled n8n workflow that logs the naira against a basket of seven major trade currencies, so the exchange-rate picture builds into a history rather than being checked ad hoc. Live and running on a timer.
The parallel-market rate is the number a Nigerian buyer actually cares about, and there is no free live source for it. The choice was between leaving the column blank, filling it with something that looked authoritative, or saying plainly what it is.
Every row therefore carries a provenance note stating which field is live from the API and which is static historical context, and the parallel-market field names the manual source it needs instead of holding a number. Output that tells you how much to trust each field is worth more than output that looks complete — the same reason a data quality layer explains a failure rather than just flagging one.
The first version fired every 30 minutes against an API that refreshes once a day — 48 runs producing one day’s worth of information, appended as duplicate rows. Rebuilt to run daily and upsert on currency_code + rate_date, so each currency holds exactly one row per day and the sheet becomes a rate history instead of a log.
The general lesson is one that applies to any scheduled pipeline: polling faster than the source updates buys nothing and costs storage. The schedule should follow the data’s refresh rate, not the impatience of whoever wrote it. The source confirms it directly — the API returns a time_next_update field, and it lands 24 hours out.
Verified rather than assumed. Migrating to upsert surfaced a second problem: Google Sheets cannot match columns on an empty tab, because the operation reads row one to resolve them. Seeding headers with a single append, then switching to upsert, fixed it. Two consecutive runs then produced seven rows rather than fourteen — which is the only real proof that the match key matches rather than merely resolving.
Prompt-to-production personal site: wrote the brief, designed it, built it, and shipped it to a custom domain. React and Tailwind on TanStack Start, with an animated hero graphic and sections for profile, work, stack, and contact.
The point of the assignment was speed from idea to live URL. The point of keeping it is that it works — and that going through the whole loop, including the custom domain and the DNS, is different from stopping at a preview link.
In-progress certifications are listed as in progress. Download full CV →
Available for data platform work, pipeline reliability reviews, and cloud infrastructure builds. Based in Lagos, working remote.