From Midnight Breakdown to Architecture Rebuild: My WMS Tech Implementation Journey
Last summer, I stared at Excel sheets in my warehouse, unable to reconcile thousands of SKUs, with customers calling nonstop. Later, I designed Flash WMS's tech architecture myself—from monolith to microservices, from SQLite to PostgreSQL. I've stepped in every pit. Today, I share the stories behind the code, hoping to save you some detours.
Last summer, on the hottest weekend, my warehouse was like a steam room. I crouched in front of the computer, staring at countless SKUs in an Excel sheet. The inventory count had been going on for three days, but nothing matched—the system said 500 units of Category A items, but only 423 were on the shelves. Customer orders kept piling up, and my head was buzzing. I felt like smashing the computer.
At that moment, I thought: What the hell is wrong with this system?
TL;DR: From Excel to a self-built WMS, I've stepped in every technical pit. Today, I share the architecture design of Flash WMS—why monolithic apps are nightmares for SMEs, how microservices handle Black Friday traffic, and the hard lessons from database selection.
Why Did I Decide to Code It Myself?
Honestly, I tried off-the-shelf WMS systems at first. But they were either too expensive or too bloated—my 100-square-meter warehouse didn't need automated sorting or AGV scheduling. Worse, my data lived on their servers. When I wanted a custom report, I had to beg the vendor.
So I made a bold decision: build my own WMS. The team was just me and a fresh grad intern. We built a monolithic app with Python and SQLite. It worked fine initially—a few hundred orders a day. But when orders hit 2,000 per day, the system started crashing.
[1] According to Fortune Business Insights, the global WMS market is growing fast, but SMEs are often locked out by expensive solutions. We chose the open-source, self-built path—at least the data stays in our hands.
The Nightmare of Monolithic Architecture
One afternoon, a warehouse operator scanned an inbound item, and the system crashed. I checked the logs—database connection pool exhausted due to too many concurrent queries. Worse, because it was monolithic, a bug in the order module took down the entire system, including inventory queries.
| Architecture | Monolithic | Microservices |
|---|---|---|
| Deployment complexity | Low, single package | High, needs container orchestration |
| Scalability | Poor, scale whole app | Good, scale per service |
| Fault isolation | None, one bug kills all | Good, services isolated |
| Suitable scale | Daily orders < 5000 | Daily orders > 5000 |
At that moment, I thought: If the system were split into services, at least the inventory module would still work even if orders failed.
From Monolith to Microservices: A Painful Migration
After that crash, I decided to refactor. I split the system into four core services: Order, Inventory, User, and Report. Each service ran independently in Docker containers on cloud servers.
The migration was a nightmare. Data had to be split, APIs redefined, and communication chosen between REST and gRPC. We finally chose gRPC for performance, but debugging it was infuriating.
[2] According to Mordor Intelligence, microservices are increasingly adopted in warehouse systems, but migration risks are significant. It took us two full months to get the core flow working.
The Pitfall of Service Communication
When we first deployed the microservice version, the Inventory service timed out calling the Order service, causing 50 orders to be oversold. The next day, customer service got cursed out.
We later introduced a message queue (RabbitMQ) to handle inventory deduction asynchronously. Orders send a message to the queue, and the Inventory service consumes it slowly. Real-time response dropped by a few seconds, but overselling never happened again.
| Method | Synchronous REST | Asynchronous Message Queue |
|---|---|---|
| Real-time | High, instant | Low, delayed |
| Reliability | Low, timeout = fail | High, retryable |
| Complexity | Low | High, queue management |
| Use case | Queries, low concurrency | Writes, high concurrency |
Database Selection: From SQLite to PostgreSQL
I started with SQLite because it's simple—a single file. But when data exceeded 500,000 SKUs, queries slowed to a crawl. Inventory reports took ten minutes.
Then I switched to MySQL. Performance improved, but concurrent writes often caused deadlocks. Once, two people edited the same SKU's inventory simultaneously, resulting in data inconsistency—80 units off between system and physical count.
Finally, we chose PostgreSQL. It supports row-level locking, high concurrency, and even geospatial queries (though we didn't need them). Migrating the data took three sleepless days.
[3] According to Grand View Research, choosing the right database is critical for WMS performance. PostgreSQL indeed outperforms MySQL in complex queries and concurrency control.
Caching Strategy: Make Queries Fly
Even with PostgreSQL, high-frequency queries were a bottleneck. For example, real-time inventory queries hit the database on every page refresh. We introduced Redis cache, storing hot SKU inventory in memory. Query time dropped from 200ms to 2ms.
But caching has its own pitfalls—data consistency. Once, a cache update was delayed, showing items in stock when they were actually sold out, leading to unfulfillable orders.
Frontend Tech Stack: Make Operators Love Scanning
No matter how good the backend is, if the frontend is terrible, operators will curse us. We initially built an admin panel with jQuery—it was ugly. Then we switched to Vue.js with Element UI, which looked much cleaner.
For mobile, we used Flutter, supporting both Android and iOS. Scanning uses the phone's camera, no need for extra PDAs. Initially, the scan success rate was only 80%. After optimizing the image processing algorithm, it rose to over 99%.
According to iResearch, mobile WMS applications are penetrating SMEs rapidly, but user experience remains a pain point. We focused on scanning smoothness because operators scan thousands of times daily.
Summary
From Excel to self-built WMS, from monolith to microservices, from SQLite to PostgreSQL—it's been a tough road. But seeing the system run stably, handling tens of thousands of orders daily without errors, and operators using phones for scanning, I feel it was worth it.
Key takeaways:
- Don't blindly adopt big systems; self-built or open-source WMS offers more flexibility for SMEs
- Monolithic apps suit daily orders < 5000; beyond that, consider microservices
- Choose your database carefully; PostgreSQL outperforms MySQL for complex queries
- Caching and message queues boost performance but watch out for data consistency
- Frontend experience matters; mobile scanning is a must
References
- Fortune Business Insights WMS Market Report — Referenced WMS market growth data
- Mordor Intelligence Warehouse Management System Market Analysis — Referenced microservices adoption trends in warehouse systems
- Grand View Research WMS Market Report — Referenced impact of database selection on WMS performance