Building a TMS (Transportation Management System) from Scratch: Architecture Decisions
A Transportation Management System is the operating system of a logistics business, orchestrating shipments, carriers, routes, billing. Building one is a real engineering project; here's the architecture walkthrough.
Key takeaways
- A TMS has 6 core modules: shipment, route, carrier, billing, exception, analytics.
- The data model is more complex than people expect, multi-leg journeys, partial shipments, returns.
- Carrier integrations are the operational glue and the longest tail of effort.
- Real-time visibility is the customer-facing win; batch reconciliation is the operations win.
- Scaling: most TMSs hit operational scale before infrastructure scale.
When to build
Off-the-shelf TMS (Shiprocket, FarEye, Bringg, ClickPost) handles 80% of needs for shippers and 3PLs. Build only when:
- Your network is unique enough that standard TMS doesn't fit
- You need deep integration with proprietary systems
- You're a logistics tech company itself
The 6 modules
1. Shipment management
Core entity. From order received to delivered. State machine: CREATED → PICKED_UP → IN_TRANSIT → OUT_FOR_DELIVERY → DELIVERED. Each transition logged with timestamp, location, status.
2. Route management
Routes assigned to drivers/trucks. Multi-leg, multi-stop. Optimization engine plugs in here.
3. Carrier management
Onboard carriers (in-house drivers, 3PL partners, last-mile providers). Track their capacity, performance, pricing.
4. Billing and settlement
Per-shipment cost calculation. Multi-currency, multi-leg billing. Reconciliation against carrier invoices.
5. Exception management
What happens when things go wrong: missed pickup, delayed delivery, lost package, damaged. Workflows for each.
6. Analytics
Operational dashboards, SLA tracking, cost per delivery, performance by carrier.
Data model essentials
Shipment
ID, source, destination, weight, dimensions, value, fragile, customer, dispatch_date, expected_delivery_date, status.
Leg
A shipment can have multiple legs (warehouse → hub → delivery center → customer). Each leg has its own carrier and status.
Tracking event
Timestamped, geo-tagged event linked to a shipment.
Carrier
ID, name, type (in-house, 3PL), service areas, pricing structure.
Integration surface
Carriers
API integration with each carrier (Delhivery, Bluedart, FedEx, India Post, custom freight). Each has its own quirks.
E-commerce platforms
Shopify, WooCommerce, Magento, custom, orders flow in via webhook or pull.
Maps and geocoding
Google Maps, Mapbox, OpenStreetMap for address resolution and routing.
Mobile apps
Driver apps push tracking data, accept deliveries.
Customer portals
Track shipments, request returns.
Payments
Settlement with carriers; COD reconciliation.
Scaling considerations
Database
Shipment volume can be huge. Partition by date or carrier. Archive old shipments to cold storage.
Real-time tracking
Each driver app pings every minute. At 1000 drivers, that's 1M events/day. Use queues + time-series store.
Geo-spatial queries
Find drivers near a pickup. Use Postgres with PostGIS or specialized geo-spatial DB.
Common pitfalls
Under-modeling multi-leg. Real shipments often have multiple legs.
Sync calls to carriers in critical paths. Carrier APIs are slow; async with retries.
No reconciliation. Carrier invoices vs your records will diverge.
Notification spam. Customers don't want a notification for every event. Tune.
What we recommend
Build module by module. Get shipment + tracking right first; add billing, exceptions, analytics over time. Integrate one carrier deeply before adding more.
FAQs
Microservices or monolith? Modular monolith almost always.
Real-time tracking via GPS? Yes, but rate-limit and aggregate.
Multi-currency from day one? Yes if you're international.
