4GO
The automated half of a rental business: book, unlock and drive away with no branch, no counter and nobody on the other end.
Context
4GO is the second rental product of AbuDiyab, the Saudi rental business with its own case study on this site, and it is deliberately the opposite of it. It serves the same market, a Kingdom that positions itself as the meeting point of three continents and moves accordingly, but it serves the part of that market which would rather not talk to anybody. AbuDiyab runs on branches, counters and handover: a person checks the licence, inspects the car and passes over the keys. 4GO removes all of that. It has its own fleet and its own operation, and the entire experience is automated, from booking on a phone to unlocking a car and driving it away without speaking to anyone. Two surfaces exist and no more: a mobile application for the customer and an administration dashboard for the people running the fleet. There is no website, because there is no counter for one to replace. Third-party vehicle IoT is what makes it possible, carrying location, access and ignition.
The problem
The documented engineering challenge is synchronisation across five states: vehicle availability, booking, customer, payment and rental state are the same transaction seen from five angles, and they can genuinely disagree. A payment can succeed after the booking it paid for has expired; a vehicle can be taken between selection and confirmation; a rental can begin before payment settles. Each of those pairs has to be reconciled rather than assumed away, on a phone, over a mobile network where interruption mid-payment is ordinary rather than exceptional. And here there is genuinely nobody to fix it. Removing the counter removes the fallback that every other rental business quietly relies on: a person who can look at a half-finished transaction, look at the customer, and decide. Everything that person did has to be done by software or not at all, and the failure is not an inconvenience but a customer standing next to a car that will not open.
The solution
A mobile application carrying the rental lifecycle end to end: search, vehicle selection, reservation, payment, the rental itself and its ongoing management. The documented capabilities span vehicle discovery, vehicle rental, booking, reservation management, rental management, payment information and vehicle services, from choosing a car to running an active rental. The vehicles are what make the automation possible. A third-party IoT integration carries location, access and ignition, so the app that took the booking is also the thing that opens the car and lets it start, and the handover that a branch performs in person happens as a command instead. Alongside the rental itself the product carries vehicle tracking, insurance coverage and rental reporting, and closing a rental still produces an invoice cleared with the Saudi tax authority, which the automation has to reach without anyone present to hand over a receipt. The hardware, the provider and the full command set are not recorded. How consistency is maintained across that lifecycle (whether a vehicle is held during checkout and for how long, what happens on a payment timeout, and whether reconciliation is synchronous or deferred) is not documented, so the mechanism that would answer the five-state problem is an open question here rather than a described design.
Architecture
A Laravel 10 backend on Octane over MySQL, with Redis in front of the repeated reads, deployed to an Amazon EKS cluster on AWS and run for high availability, which on this product is not an operational preference but a functional requirement. A branch-based rental degrades gracefully when the software is down, because the staff fall back to paper and keys. This one does not degrade at all: if the platform is unreachable, nobody unlocks a car. Availability of the system is therefore availability of the product. Two surfaces reach it: a Flutter application for the customer and a React and TypeScript dashboard for the people running the fleet. Firebase carries push, and ZATCA carries the invoice, because an automated rental is still a taxable one and the absence of a counter does not excuse the absence of a cleared invoice. As documented, the topology is the simplest possible: a mobile application in front of a single backend, with availability, booking, payment and rental state behind it, and the real topology is not established beyond that sketch. The diagram therefore draws what is actually documented (one client, a sketched API, the five states named as the synchronisation problem, and the vehicle IoT link) rather than a verified deployment. It runs on its own backend rather than sharing AbuDiyab’s, which matters more than it sounds: the two products belong to one company and describe opposite operating models, and keeping them on separate systems means the automated one was free to be built around unattended handover rather than bolted onto software written for a counter. A payment gateway is implied by the documented payment workflows but never named, so it appears as an unconfirmed element; which store or service realises each of the five states is equally undocumented.
Read this diagram as text
- Mobile app
- The single documented surface: the whole lifecycle from vehicle discovery to managing an active rental happens here, on a network that can drop mid-payment.
- Admin dashboard
- React and TypeScript, and the only surface with people behind it: the fleet, the rentals and whatever the automation could not settle on its own.
- Vehicle IoT
- IoT sensors in the rental vehicles: live tracking, and remote control including turning a vehicle on and off. The hardware, provider and protocol are not documented.
- Backend / API
- Its own Laravel backend, separate from AbuDiyab’s, so the automated product is not built on software written for a branch counter.
- MySQL
- Holds the transaction that the whole product turns on, and the five views of it that can disagree: vehicle availability, booking, customer, payment and rental state.
- Redis
- Fronts the reads that repeat, on a catalogue browsed far more often than it is rented.
- ZATCA
- Saudi e-invoicing. Closing an unattended rental still produces a stamped invoice cleared with the authority, with nobody present to hand over a receipt.
- Firebase
- Cloud Messaging, which on a product with no counter is the only way to tell a customer anything.
- Payment gateway
- A payment gateway is implied by the documented payment workflows but is never named.
- Mobile app → Backend / API (full rental lifecycle)
- Admin dashboard → Backend / API (fleet and exceptions)
- Backend / API → MySQL (five states, one transaction)
- Backend / API → Redis (repeated reads)
- Backend / API → ZATCA (clear invoice)
- Backend / API → Firebase (push delivery)
- Backend / API → Payment gateway (payment · gateway not named)
- Vehicle IoT → Backend / API (tracking ↔ remote on / off)
What makes it interesting
The parts a system like this is actually judged on.
- Removing the person is the whole product, and it is also the whole difficulty. A branch agent verifies a licence, judges whether to hand over a car, inspects it on return and resolves anything that goes wrong in between, and none of that is written down anywhere as a requirement because a human was always doing it. Automating a rental means discovering every one of those judgements and deciding, for each, whether software makes it, refuses it, or escalates it to somebody who is no longer standing there.
- High availability stops being an operational nicety on a product with no counter. A branch-based rental degrades when its software fails, because people fall back to paper, keys and judgement. An unattended one has nothing to fall back to: an outage is a customer standing beside a car that will not open, in a car park, with no member of staff within reach. Uptime is therefore a product requirement rather than an infrastructure target, and it is the reason the deployment shape matters here more than it would elsewhere.
- The IoT link is not telemetry here, it is the handover. On a branch-based product, tracking a vehicle is useful information; on this one, the command that unlocks a car is the moment the rental actually begins. That makes a third-party integration load-bearing in a way a monitoring feed never is: if it is unavailable, the customer cannot start their rental, and there is no counter to fall back to.
- Availability, booking, customer, payment and rental state are five views of one transaction, not five independent records: a payment that succeeds after its booking has expired, or a rental that starts before payment settles, is a legal ordering of events the system has to reconcile, not a bug it can rule out.
- Availability is only ever a statement about the recent past: the vehicle a customer selects can be taken before they confirm, so the design question is not whether that race exists but where it is resolved (at selection, at reservation or at payment), and the answer is not documented.
- Taking payment on a phone inverts the usual assumption: network interruption mid-payment is the case to design for, not the edge case, which makes every checkout a distributed transaction whose client half can disappear at any step.
- Steps a branch agent used to absorb, like resolving a half-finished transaction, have no human fallback in a mobile-first lifecycle, so every ambiguous state has to be made either impossible or self-resolving.
- The vehicle link is two-way: the IoT sensors report continuously while the platform can turn a vehicle on or off remotely, which extends the five-state problem into the physical world; a command issued against stale rental state acts on a real car.
Engineering challenges
- Five-way state synchronisation: availability, booking, customer, payment and rental state can disagree.
- Payment over a mobile network: interruption mid-payment is normal, not exceptional.
- Availability at selection versus confirmation: the vehicle can be taken between the two.
- A mobile-first lifecycle: steps previously handled by a branch agent have no human fallback.
- Remote vehicle control: a command issued against stale rental state acts on a real car.
Integrations
- Third-party vehicle IoT: location, access and ignition, which is what replaces the counter rather than merely monitoring the fleet
- ZATCA: Saudi e-invoicing, so an unattended rental still closes with a cleared tax invoice
- Firebase: push notification delivery to the mobile application
- Vehicle IoT sensors: live tracking and remote on / off control; the hardware, provider and protocol are not documented.
Technology
- Laravel 10
- Laravel Octane
- MySQL
- Redis
- Flutter
- Dart
- React
- TypeScript
- Firebase
- ZATCA e-invoicing
- AWS
- Amazon EKS
- Docker