Skip to content

FULL-STACK ENGINEER · REGENSBURG, GERMANY

I build software, then I keep it running.

I’m Isaac Hatilima, a full-stack and DevOps engineer. More than six years of shipping web and mobile products, from the database to the App Store, and building the infrastructure underneath them.

SHIPPING SINCE
2019
BASED IN
Regensburg, Germany
BUILDING
Web · Mobile · APIs
BACKEND
PHP · Laravel
INFRASTRUCTURE
Kubernetes · Hetzner
APPROACH
Build · Ship · Run
BUILD · SHIP · RUN

THE RACK

One unit per project. Open one to see what is inside.

A language-learning app for translation practice with AI grading. I build and run my own products, carrying them through releases, incidents and support.

FOCUS

  • Language learning
  • Mobile
  • AI grading

RunningShippedPublished

UPTIME LOG

Six years of shipping, and running what I ship.

  1. JUN 2025 – NOW

    DevOps and Infrastructure Engineer (self-directed), home lab, Regensburg

    Kubernetes (k3s) clusters with Traefik and Longhorn, Hetzner infrastructure provisioned with Terraform and Ansible, observability with Grafana and Prometheus, high-availability PostgreSQL.

  2. SEP 2023 – NOV 2025

    Full-Stack Software Engineer, Bet3000 Entertainment, Waldkraiburg

    Production web applications in React, TypeScript and PHP. Built a real-time device management platform that cut operational process time by 80%, a franchise management application and a reporting layer across MSSQL and Oracle.

  3. MAR 2022 – AUG 2023

    Software Engineer, APS-Tech Group, Ellwangen

    A React Native app for point-of-interest exploration, a real-time IoT backend in Python and Django REST Framework, and a WPF industrial metrology application.

  4. MAY 2019 – FEB 2022

    IT Support Engineer, TechMasters Zambia, Lusaka

    Built a PHP incident tracking system used by 100+ staff across several banks, led an enterprise Windows migration and kept ATM network uptime above 95%.

  5. EDUCATION, 2019

    Diploma in Computer Science with Education

    Evelyn Hone College, Lusaka, Zambia

More about me

TOOLS

The stack I work in.

FRONTEND

React, TypeScript, JavaScript, Inertia.js, Livewire, Tailwind CSS

MOBILE

React Native, Expo, App Store and Google Play releases

BACKEND

PHP 8, Laravel (Horizon, Reverb, Cashier), Python, Django REST Framework, Node.js

APIS AND REAL-TIME

REST, OpenAPI, WebSockets, OAuth 2.0, JWT, webhooks

DATABASES

PostgreSQL, MySQL, Redis, MSSQL, Oracle

CLOUD AND DEVOPS

Docker, Kubernetes (k3s), Terraform, Ansible, Traefik, Hetzner Cloud, Grafana, Prometheus

CI/CD AND TESTING

GitLab CI/CD, GitHub Actions, Jenkins, Pest, Vitest

LANGUAGES

English (native), German (A1, improving)

CODING FINDS / LATEST

ALSO OVER MCP FOR CODING AGENTS

Problem. Put a heavy job behind an "Export orders" button and every click queues another copy. Impatient users click two, three, ten times, and each click is another full export competing for the same workers and the same database.

Guarding the dispatch with a cache flag looks like a fix, but Cache::has() followed by Cache::put() is two separate steps, so two quick requests can both get past the check. The flag also outlives the job: it stays set after the export has finished, so the button does nothing until the flag expires.

Fix. Implement ShouldBeUnique on the job and return the key that defines a duplicate from uniqueId(). When the job is dispatched, Laravel takes an atomic cache lock named after the job class and that key. If the lock is already held, the new dispatch is dropped. The lock is released as soon as the job finishes, or once it has failed all of its retries.

The #[UniqueFor] attribute is the safety net. It releases the lock after that many seconds even if a worker dies halfway through, so one crash cannot block exports for good.

Result. Extra clicks become no-ops instead of extra exports, and there is no flag to clear or forget. The lock lives in the cache, so use a store that supports atomic locks (Redis, Memcached, DynamoDB, database, file or array) and make sure every server shares it. If you only want to stop two copies running at once but still queue the second one, use the WithoutOverlapping job middleware instead.

php
// Before: a flag that two quick clicks can both get pastif (! Cache::has("export:{$team->id}")) {    Cache::put("export:{$team->id}", true, 900);    ExportOrders::dispatch($team);}// After: the queue holds the lock#[UniqueFor(900)]class ExportOrders implements ShouldQueue, ShouldBeUnique{    use Queueable;    public function __construct(public Team $team) {}    // One export per team; other teams still run in parallel    public function uniqueId(): string    {        return (string) $this->team->id;    }    public function handle(): void    {        // Build and email the CSV...    }}// Ignored while this team's export is queued or runningExportOrders::dispatch($team);

All notes

Hiring, or have something to build?

I’m based in Regensburg, Germany. Get in touch on LinkedIn, explore my code on GitHub, or download my CV for the full picture.