Laravel backend engineer · Benghazi, Libya · EMEA · open to remote

Beyond the controller.

I'm Nabil. For ten years I've owned Laravel systems end to end — Eloquent, APIs, Redis, queues, workers, and the production paths that only matter when traffic spikes. Most recently: the digital platform that moves a country's money. This page is how I think about that work.

Scroll. Move your cursor through the stream — each particle is a session. Scroll. Each particle in the stream is a real session.

The last twelve months, on one Laravel platform I architected and built end to end — stats as of 15 Aug 2026

0 LYD

total transaction volume through Wahda Bank's digital platform.

0 sessions

~392K daily · ~11.9M monthly — Laravel, Redis queues, Go hot paths, Vue.

Numbers that size stop being impressive and start being a responsibility. Everything below is about carrying them without breaking what already works.

01 — Beyond the controller

A scalable change inside a mature Laravel codebase

Not a rewrite. Not a greenfield. The interesting work: peak load, Redis, workers, and a codebase that already had opinions — changed carefully so production stayed boring.

Laravel system of record Core bank + payment rails Redis queues · cache Workers jobs · events Go hot path everything inline feature flag · shadow traffic same contract · versioned · contract-tested
Before: one request did everything. Salary day: locks, queue depth, slow vendors. Side effects to Redis jobs; hot path isolated. Every shortcut with an expiry date. Boring salary days. Smaller codebase.
Context

Wahda Bank's digital platform started life as a well-behaved Laravel application. By the time it was carrying a meaningful share of the country's retail payments it was mature in the way that word really means: hundreds of endpoints, Eloquent models with real money in them, integrations with a core-banking system and instant payment rails — OnePay, LYPAY — a mobile app in the field that people would not update, and a business that could not tolerate a bad Tuesday.

Constraint

The problem arrived on salary days. Every transfer was processed inline in the request: validate, call core banking, write the ledger, notify, log. Under peak load the connection pool filled, lock waits on account rows cascaded, and a notification provider having a slow hour could make a payment feel slow.

The obvious answer — “rewrite the payments layer in something fast” — was also the most dangerous one. A rewrite is a promise to rediscover every edge case a mature system has already paid for.

Approach

So I didn't rewrite. I investigated the existing behaviour first, drew a line around the one thing that actually needed to be fast — the transfer hot path — and treated everything else as a scheduling problem.

  • Everything that wasn't the money left the request. Notifications, statements, analytics and fraud scoring became Redis-backed queued jobs (Horizon) with explicit retry and idempotency semantics. Events carried the rest. The request that remained did one thing.
  • The hot path moved into a small Go service behind the exact contract Laravel had always exposed. Laravel stayed the system of record and the orchestrator; Go became a worker that is very good at one narrow job. They speak through a versioned interface with contract tests, so the mobile app in the field never knew anything changed.
  • Correctness first, speed second. Idempotency keys on every money-moving call; a reconciliation job comparing the new path against the old on shadow traffic before a single real transfer used it; per-cohort feature flags so rollout was a dial, not a switch.
The trade-off

Performance you can't afford to keep is technical debt with better PR. So each shortcut had an expiry: the parallel code path was written up in an ADR with a delete-by release; the dual-write comparison came out as soon as it had been quiet for two cycles; any query I touched left with an index and a test.

I let the old code stay ugly where it was safe, and made it clean only where it was hot — after I understood why it looked that way.

Outcome

The next salary day was boring, which was the point. Peak-hour latency stopped tracking queue depth, a slow vendor stopped being able to slow a payment, and the mature codebase got a little smaller instead of a little scarier.

That platform now moves roughly 156 billion LYD a year across 143 million sessions, 77 million transactions, and 601 thousand users — and it still runs on Laravel where Laravel is right, and Go where Go is right.

02 — Domain over plumbing

I build when the problem is the domain — not the framework.

Laravel, Horizon, Redis, Guzzle
are solved. The domain isn't.

The plumbing is solved. Using Laravel well — Eloquent, jobs, events, Horizon, caching — is a skill; replacing it is a hobby. The one place I found that rule worth breaking was the integration layer under the bank.

Every Libyan payment rail — the core-banking system, OnePay, LYPAY — speaks a different dialect: different signing schemes, different ideas of what a “pending” transaction is, different reconciliation files arriving at different hours. Nothing on Packagist understood any of it. The first version wrapped each rail in its own ad-hoc client, which is a reliable way to get four copies of the same bug.

So I wrote a small PHP library for it: one ledger model every rail maps onto; a request pipeline where signing, idempotency, retries and timeouts are composable middleware; and a reconciliation engine that turns each provider's settlement file into the same stream of events. Adding a new rail became a few hundred lines of adapter instead of a new project.

Why build? Because when real money is moving, I can't afford magic behind my back. Every step has to be explicit — not hidden in a clever black box. Why keep it small? Because I've maintained other people's clever frameworks. It's better to know the codebase than to be surprised by it.

Same instinct at a smaller scale: a generator that builds Postman collections from route definitions, so API docs stop drifting from the code. And where the product needed it — Livewire, Filament, Inertia, Tailwind — I use the TALL / Laravel ecosystem instead of inventing another UI stack.

03 — Stack, honestly

What I bring to a Laravel backend seat.

Rated one to five. I'd rather you be pleasantly surprised on the technical test than the other way round.

  1. Laravel & modern PHP 5

    Ten years across Laravel, Lumen, Livewire and Filament. PHP 8.x — strict types, enums, readonly. I know where the framework ends and your problem begins.

  2. Eloquent · SQL 5

    Ledger-grade schemas, isolation levels, index design, EXPLAIN as a daily habit. MySQL and PostgreSQL under real money.

  3. APIs & complex backends 5

    Internal and external APIs, multi-rail integrations, services and domain logic that span models, jobs and events — designed to stay readable under change.

  4. Redis · queues · events 4

    Horizon jobs, idempotency, retries, dead letters. Redis as cache, lock and rate limiter. Event-driven side effects so the request stays thin.

  5. TALL stack Livewire · Tailwind 4

    Livewire and Filament in production admin surfaces; Tailwind for product UI. Alpine when the page needs a spark without a SPA. Backend-first — range across the stack when it helps.

  6. Performance & scale 4

    Peak-day banking traffic taught the habits: N+1 hunting, queue depth watching, feature-flagged rollouts, and designing for the next 10× before it arrives.

  7. Other languages Go · Node · Vue 4

    Go for narrow hot paths; Node for streaming; Vue/Inertia when the product needs a serious front end. Happy to dig into unfamiliar code before changing it.

  8. Ownership & review culture 5

    Clear written communication, ADRs, iterative review and QA. I've led teams; what I want now is deep craft on important systems — with people who ship.

04 — Off the clock

Watching Barça.

Ninety minutes where the only metric that matters is the scoreboard — and when someone goes airborne after a goal, the week gets lighter. FC Barcelona is my off-switch: the noise, the flip, the GOOOOOOOL. Craft under pressure, just a different pitch.

Visca el Barça →
An FC Barcelona player mid-backflip celebrating a goal in a packed stadium

Why CRAE

You build interconnected Laravel platforms — CRM, gaming, network, marketing — with real users, real transactions, high-frequency queues and Redis in the critical path. That is the shape of problem I've spent years inside.

Backend-first, TALL when it helps, ownership without corporate theatre. I've run a department; what I want now is deep craft on important systems, next to people who still ship.

You pay trial work and keep the hiring loop short. A company that respects an engineer's time is one I'd like to build for.

Let's talk.

Benghazi, Libya · EMEA · Arabic (native), English (professional)
MSc & BSc Software Engineering, University of Benghazi · Open to remote