Building a Multi-Region RFID Tracking Platform on AWS
When an international postal programme needed infrastructure to track receptacles across 50+ countries using RFID, the core challenge wasn't storage or scale — it was data assembly. Two completely separate data sources, living in different systems in different regions, had to be joined in real time to produce a meaningful picture of where every receptacle physically was in its journey.
This post walks through the AWS infrastructure I designed and deployed — how the pieces fit together, why certain decisions were made, and what broke along the way.
The Visibility Gap
International postal receptacle tracking today relies on EDI messaging: PREDES at dispatch closing, RESDES at destination processing. These messages capture when operators scan barcodes at defined processing points. What they don't capture is the physical reality in between.
A receptacle might be physically sitting on a loading dock for hours after PREDES is sent. Mail might arrive at a destination facility Monday evening but not get processed until Wednesday — RESDES only fires when the operator opens and scans it. The gap between the electronic event and the physical event is invisible to the existing messaging infrastructure.
RFID fills that gap. Fixed readers at facility entry and exit points capture receptacle movement automatically — no operator intervention required. By linking the RFID reads to S9 receptacle identifiers, the platform can calculate the actual physical timestamps: when receptacles truly left origin, when they truly arrived at destination, and how long they sat in between.
The Data Problem
The platform works with two completely separate data sources.
The first is RFID scan events. On-premise postal facility infrastructure captures receptacle movements as EPCIS-standard events. Every time a receptacle passes a facility reader, an event is generated with a tag ID, read point, and timestamp. The on-premise EPCIS system (Elasticsearch) pushes these events in real time via REST/JSON to the Edge API hosted on AWS in Stockholm.
The second is EPC-to-S9 matching data. A separate database in Frankfurt holds the correlation between each EPC RFID tag and its corresponding S9 receptacle identifier — the 29-character barcode printed on every receptacle label that encodes origin, destination, dispatch, and sequence. Without this correlation, the RFID events are just timestamped tag reads with no postal context. You can't know where the receptacle is going or who it belongs to.
These two sources need to be joined automatically, in real time, on every insert, so that Power BI dashboards can query a single clean table without complex logic.
Multi-Region Architecture
The platform runs across two AWS regions. Stockholm (eu-north-1) is primary — all application services, the reporting database, CDN, and the enrichment pipeline run here. Frankfurt (eu-central-1) hosts the EPC-to-S9 matching database that provides the postal identity context for every RFID read.
AWS DMS continuously replicates the matching data from Frankfurt to Stockholm in full load + CDC mode. A column transformation rule corrects a data quality inconsistency between the two systems — tag IDs in the source database had a formatting difference that would silently break all joins if left uncorrected.
VPC peering between the two regions keeps the replication traffic private without traversing the public internet.
The Enrichment Pipeline
Rather than building enrichment logic into the application layer, everything runs as PostgreSQL triggers in the reporting database. Triggers fire automatically on every insert:
Deduplication — Keeps a maximum of two rows per tag-per-reader combination — the earliest and latest reads. Readers can scan the same tag repeatedly as a receptacle sits in a facility, and without dedup, the table bloats rapidly.
Geolocation enrichment — Looks up the facility reference table by read point and populates geographic coordinates automatically.
Status calculation — Joins the RFID event against the S9 matching data, extracts origin and destination, and computes the receptacle's operational status. A mirror trigger re-enriches existing records when new matching data arrives, since the S9 correlation sometimes lands after the RFID events.
Power BI reads exclusively from the pre-enriched output table. No live joins, no transformation logic in the dashboard layer.
Containerized Application Layer
Four services run on ECS Fargate in the Stockholm cluster, all at minimal size with autoscaling. A YARP reverse proxy gateway handles authentication and routes requests. The .NET 8 API handles RFID event ingestion and serves report data. A Users microservice manages identity and per-country access control. Hangfire runs background jobs for data normalization and scheduled refresh.
Services communicate internally through AWS Cloud Map with ECS Service Connect. Only the gateway is exposed through the ALB — everything else stays internal.
The Service Connect Problem
The most frustrating operational issue in the project. Every time a new container image was deployed, internal service discovery silently broke — services couldn't reach each other and everything returned 502s with no obvious cause.
The root issue was that the standard ECS deployment tooling doesn't preserve Service Connect configuration across deployments. The fix required a post-deployment step in CI/CD to explicitly re-apply the configuration after every deploy. Not well-documented, and it cost significant debugging time to identify.
Dual Ingestion Paths
Beyond the automated EPCIS push, the platform also supports manual file uploads. Operators can extract RFID data for any time period and upload it directly via S3 — useful for historical backfills, ad-hoc investigations, or data from facilities not yet connected to the real-time pipeline.
An S3 event triggers Lambda, which validates the file and routes it to EFS. Hangfire picks it up and runs it through the same normalization and enrichment pipeline as the automated flow. Both paths produce identical output — the dashboard has no awareness of how the data arrived.
What I'd Do Differently
Service Connect in CI/CD from day one. The debugging time lost to silently broken DNS after deployments was significant and entirely preventable with a post-deploy step in the initial pipeline setup.
Populate the facility reference table before the first data lands. Backfilling geo-coordinates after the fact required custom scripts and manual verification against reference data.
Data quality assessment before DMS setup. The tag ID formatting inconsistency between source and reporting databases should have been caught during initial assessment, not discovered after records silently failed to join.
NG Solutions designs and deploys production AWS infrastructure. Multi-region pipelines, containerized platforms, IoT and RFID integration — get in touch.