Check is a shared mobility operator and currently the market leader in moped sharing in the Netherlands. The company built its mobile app completely in-house, while its fleet grew to 5,000 mopeds and 1,500 e-bikes.
For a long time, the team relied on the manufacturer's cloud server provided by Segway, which worked well enough. That changed when Check entered the bike-sharing market, and Segway did not offer its cloud service for the new bike models. Building and maintaining a custom IoT cloud server was not an option either, so the team started looking for a third-party solution – and needed it fast.
“We had a great product team focused on our app, and we had absolutely no interest in spending engineering resources to build and maintain a custom IoT cloud server ourselves.”
After recommendations from experts in the micromobility industry, Check started looking into third-party middleware. The main reason the company chose flespi was that we seemed to be the only server provider that already had the Segway protocol implemented and ready to use out of the box, which allowed Check to test it immediately on its new bikes.
From testing to full-scale migration
By the time Segway eventually decided to deprecate its cloud service entirely, Check had already tested flespi on its bikes and built a high level of confidence in the platform; that's why they decided to migrate the 3,000 mopeds as well.
“It was worth the effort because it unified our entire fleet under one modern and reliable backend.”
However, the migration required more than redirecting the devices to a new server. The integration exposed a series of protocol-level issues that we had to solve before the fleet could go live.
One of the first surprises was that some lock and unlock commands physically worked while flespi reported them as failures. Looking at the raw traffic revealed two different problems: the command timer could expire while the device was still processing the request, and the C3 saddle unlock command could return two responses – first a failure and then, about four seconds later, a success.
The timer was fixed first, but testing at a larger scale revealed another issue. After a C3 saddle unlock, the E110 could enter what the team called “C4-only mode”: the saddle would open normally, but after it was closed again, the device stopped accepting incoming commands for around 90 seconds and eventually disconnected.
The hunt for two missing bytes
The first hypothesis was that the device was waiting for the C4 acknowledgment, so we temporarily suppressed those acknowledgments. The disconnects continued.
That led to a deeper look at the protocol documentation. Our team found that the emoped_c device type had actually been built around the Moped-C specification for the Segway C80 e-bike, while Check's fleet consisted of Moped-E E110 electric mopeds. The two variants shared the same protocol framing but differed in command semantics and supported settings, explaining several of the unexpected behaviors.
The investigation then went down to individual bytes. Comparing server-to-device traffic showed that virtually every outgoing Segway frame started with the binary FF FF prefix – except the C4 acknowledgment.
This explained the problem. The device did need the acknowledgment, but it was rejecting the malformed frame because those two bytes were missing. As a result, it kept resending C4, ignored other commands, and eventually disconnected.
We also compared the traffic with logs from Segway's own server, where the C4 acknowledgment did include the FF FF prefix. An audit of the protocol implementation confirmed that C4 was the only send: block missing it. The fix was one line of code!
Before:
send:
<"*">
...
After:
send:
<FFFF>
<"*">
...
After the fix was deployed, all five emoped_c test devices reconnected within seconds, with zero new protocol errors. The C4-only mode was gone, and the fleet could move forward. For Check, this level of debugging was unusual.
“As a product-focused company, our goal is to build the best rider app possible, not to spend our days parsing raw hex payloads and managing TCP sockets.”
Thus, having a developer jump into the chat helped the team resolve the issue before the migration deadline.
One reliable backend
With the protocol issues resolved, guys could run the fleet through flespi as a single backend for vehicle data and commands. The team uses MQTT as its primary way of consuming vehicle data from flespi because it is lightweight, incredibly fast, and well suited to thousands of concurrent and intermittent vehicle connections.
“At our scale, MQTT gives us the ability to instantly route telemetry and ride status directly to our backend and the Check app without heavy polling or server bloat.”
The developers use Rust for backend services, while flespi handles communication with the vehicles. When a user unlocks or locks a moped, the backend asks our platform to execute the command for that specific vehicle, and the result comes back as a standardized message via MQTT. Check keeps the business logic on its side, including verifying that the vehicle is stationary and the saddle is locked before completing a ride, while timeouts are handled programmatically for unresponsive vehicles.
The engineering team also uses our AI assistant, Codi, as a first step when technical questions or unexpected device behavior appear, helping narrow down where an issue lies without searching through the documentation from scratch.
The engineering impact
The biggest improvement has been the engineering focus regained by not having to build and maintain an IoT cloud server on-site. Internal infrastructure costs also dropped significantly, and the migration caused zero disruption for riders.
Looking back, the hardest part was committing to the platform before it had been tested across the full fleet. The team would involve the flespi engineers earlier and test the full end-to-end customer journey sooner to find bugs earlier. Still, the approach worked well in practice. Ultimately, starting small by testing the new bikes first gave us a tested process that could also be used for the rest of the fleet.

