
I still remember the day a North American colleague, visiting our office in São Paulo, asked why we didn’t just “spin up another cloud instance” to handle a sudden traffic spike for a client. He was a sharp engineer, no doubt about it. But his question came from a place where fiber connections hum quietly underground, power flows uninterrupted, and the biggest headache is deciding between AWS or Azure. For us, in that moment, the headache was that the bairro’s electrical grid had just sagged under a heatwave, and the backup generator was running on fumes. That’s where the real design work begins.
Here at Fortec, we bridge two engineering worlds. One is the polished, assumption-laden universe of Western tech solutions—where infrastructure is a given, not a variable. The other is the daily reality of much of Brazil, and frankly, a good chunk of the Global South, where an engineer has to treat internet connectivity, power stability, and physical security as first-class design constraints. This isn’t a complaint; it’s a call for practical, resource-conscious thinking. If your product or service is going to work in a favela in Rio, a rural cooperative in Minas Gerais, or even a mid-sized factory on the outskirts of Fortaleza, you need to unlearn some of the most basic tenets of Silicon Valley design.
The Invisible Foundation
Walk into any co-working space in Lisbon or London, and you’ll see developers confidently building real-time video streaming apps, massive IoT data pipelines, and always-on cloud sync services. The assumption is that the device will always have a stable, high-bandwidth connection. The code is written for the happy path. But what happens when the path isn’t just unhappy—it’s frequently non-existent?
In many parts of Brazil, connectivity is not a binary on/off switch. It is a spectrum that shifts throughout the day. A 4G signal might be strong at 10 AM, only to degrade to a crawl by 6 PM when the local tower is overloaded. A fixed broadband connection in a commercial district might rely on aging copper that drops packets whenever it rains. The Western assumption is that “offline” is a rare, temporary error state. For us, it’s an operating mode. We design systems that are offline-first by necessity, not by trend. This means local storage that syncs when it can, queueing mechanisms that don’t corrode under weeks of delay, and user interfaces that give clear, dignified feedback—not just a spinning wheel of death.
Beyond the Cloud: The Edge is Not a Choice
I’ve had conversations where a well-meaning architect suggests an “edge computing” solution, envisioning a neat array of micro data centers. In our context, the edge is often a dusty single-board computer bolted to the wall of a warehouse, sharing a power strip with a decades-old fan. The design philosophy must shift from “let’s push compute to the edge” to “the edge is all we can rely on, and the cloud is a nice-to-have bonus when it’s available.”
This requires a different kind of software architecture. Instead of a thin client calling a fat API, we often build fat clients that can operate autonomously with a complete local data model. Conflict resolution isn’t an afterthought; it’s the core of the data layer. We use strategies like CRDTs or simple last-write-wins with vector clocks, but the implementation must account for devices whose clocks drift because they can’t always reach an NTP server. These are the tiny, maddening details that Western frameworks rarely consider.

The Electrical Grid is a Participant in Your Architecture
If connectivity is the first broken assumption, power stability is a close second. In many Western design patterns, power loss is an emergency that triggers graceful shutdown procedures. For a point-of-sale system in a small comércio in the Zona Norte, power dips and brownouts are a Tuesday. The system must survive not just a clean shutdown, but the violent, instantaneous loss of voltage, followed by a surge when the grid comes back.
This means thinking about data integrity at the hardware and filesystem level. Using journaling filesystems is a start, but we also need application-level checks that can roll back a partially written transaction that was cut off mid-byte. We’ve learned to favor simple, append-only log structures over complex database files that are more susceptible to corruption. The software must also be able to boot into a known-good state without human intervention, because the “user” might be a shopkeeper who has no technical training and simply needs to start scanning products again immediately after the lights flicker back on.
Designing for the In-Between States
Western user experience design loves clean, binary states: connected or disconnected, online or offline, charged or charging. But what about the phone that’s being charged by a spluttering generator that delivers 180V instead of 220V? The device might technically be “charging,” but so slowly that it’s actually losing power while in use. The UI should not just show a lightning bolt icon; it should communicate the effective power state. Similarly, a network indicator shouldn’t just show a Wi-Fi symbol; it should indicate the quality of the connection to the actual backend service, not just the router. A device can be on Wi-Fi but functionally offline because the backhaul is down.
This granularity is not a luxury. For a delivery driver relying on a routing app in a peri-urban area, the difference between “no signal” and “signal is too weak for live navigation, but I have cached maps” is the difference between a completed delivery and a frustrated call to the dispatcher. We build these distinctions into the interface because the physical and economic realities demand it.
Physical Reality Trumps Digital Abstractions
Western tech culture often celebrates “moving fast and breaking things,” with the implicit understanding that the “things” are digital and can be patched with an over-the-air update. But when your hardware is deployed in a remote monitoring station for a water reservoir, a “broken thing” might be a sensor node that’s now inaccessible because the rainy season has made the dirt road impassable for three months. A failed update isn’t a 500 error on a staging server; it’s a bricked device that requires a two-day trip by motorcycle to reach.
This changes the entire approach to testing and deployment. We practice paranoid-level validation of firmware updates, with redundant boot partitions and automatic rollback mechanisms that have been tested against the most bizarre power-loss scenarios we can imagine. We also have to consider physical maintenance. A device’s enclosure must not only be IP65-rated against dust and water but also be openable by a technician who may have only a worn-out Phillips screwdriver and a flashlight. Using exotic security screws or glue-sealed cases is a design failure. The engineering culture here is one of pragmatic accessibility, a direct inheritance from the gambiarra spirit—the art of making things work with what’s at hand.

The Gambiarra as a Design Principle
To an outsider, gambiarra might look like a messy, unreliable hack. But in its best form, it’s a deep, systemic creativity born of constraint. It’s the ability to solve a problem with the materials and tools immediately available, without waiting for the perfect, vendor-approved solution. As engineers, we shouldn’t romanticize it uncritically—a poorly spliced wire is still a fire hazard. But we can learn from its core ethos: assume nothing, use what’s there, and favor repairability over proprietary elegance.
This principle translates directly into our software architecture. We avoid heavy, monolithic frameworks that require a perfect environment to run. We favor modular components that can be swapped out. If a message queue needs to be replaced with a simpler polling mechanism over a serial port because the network is down, the system should allow that without a rewrite. It’s not about building a beautiful, perfect machine; it’s about building a resilient organism that can survive in a messy ecosystem.
Cultural and Linguistic Assumptions in Software
The infrastructure problem isn’t just about hardware. It extends into the software’s interface and logic. Many Western-developed libraries and APIs make assumptions about data formats that simply don’t hold. A classic example: address validation. A U.S.-centric form expects a street number, street name, city, state, and ZIP code. Now try plugging in an address from a small town in the interior of Bahia, where the official street name exists on a map but nobody uses it, the house is identified by a painted number on a tree, and the “neighborhood” is the primary locator. A system that rigidly enforces a five-field address form will reject the reality of a large portion of its users.
We’ve had to build address systems that accept free-form text and use fuzzy matching against a constantly updated local database, because the official postal code database is often years out of date. Similarly, name fields that demand a “first” and “last” name clash with Brazilian naming conventions that often include multiple surnames. A user named “João Carlos da Silva Santos” is not going to neatly split his name. These seem like small UI issues, but they are symptoms of a deeper monocultural design mindset. When a user can’t even enter their name into your system, you’ve lost their trust at the first step.
Localizing Beyond Translation
True localization is not just translating strings from English to Portuguese. It’s about adapting the operational logic. For example, a scheduling system designed in Germany might assume that a business day is 9-to-5 with a precise lunch break. In many parts of Brazil, commercial hours are more fluid, varying by city ordinance, day of the week, and even the weather. A delivery ETA calculation that doesn’t account for the fact that many streets become one-way during certain hours, or that a feira livre (street market) blocks a road every Wednesday morning, will generate promises it cannot keep. We build these local temporal and spatial rules into the engine, not as an afterthought but as a core configuration layer.
Practical Design Patterns for Constrained Environments
So, how do we actually build systems that work under these conditions? It starts with a shift in priorities. Instead of optimizing for developer convenience or the latest framework, we optimize for resilience and data sovereignty. Here are a few patterns we’ve found effective:
- Async-First Communication: Never assume a synchronous HTTP request will complete. Every outgoing message is persisted locally before transmission. This is a variant of the transactional outbox pattern, but implemented at the application level, often with a simple SQLite database rather than a heavy message broker.
- Delta Sync: When bandwidth is scarce and costly, syncing full objects is wasteful. We design APIs that transfer only the changes since the last successful sync, using a protocol that can be carried over SMS or a low-bandwidth MQTT channel if needed.
- Graceful Degradation of Features: A field service app might have a full interactive map with live traffic when online. When offline, it falls back to a rasterized tile set and a simple distance-based routing algorithm. The user still gets a functional tool, not an error message.
- Hardware-Abstracted Sensing: Don’t code to a specific sensor model. Code to a sensor interface that can be backed by a $50 industrial probe or a makeshift analog input, because the original sensor will fail and the replacement will be whatever is available locally.
The Economic Logic of Robustness
Some might argue that building this level of resilience is too expensive for a startup or a small team. I’d counter that not building it is far more expensive. A SaaS platform that works flawlessly in a San Francisco office but fails in a São Paulo warehouse doesn’t just lose a sale; it burns a market. Once a logistics manager in Brazil has a system fail during a critical operation, you won’t get a second chance. The cost of rebuilding trust is astronomical compared to the upfront engineering cost of handling reality.
Additionally, this approach forces a kind of architectural discipline that benefits the product everywhere. A system that can survive a power cut in Paraná will handle a data center outage in Virginia with unflappable calm. The constraints of an emerging market act as a stress test that exposes hidden fragility in any global system. It’s a competitive advantage, not a charity case.
FAQ: Engineering for Unpredictable Infrastructure
Why can’t we just rely on mobile networks getting better?
Mobile networks are improving, but coverage is still highly uneven, especially outside major urban centers. More critically, reliability is not just about signal bars; it’s about contention ratios on the tower, backhaul capacity, and the operator’s peering arrangements. A “4G” icon doesn’t guarantee a usable data channel. Designing for offline operation is essential because the network’s quality cannot be controlled from the application side.
Isn’t building offline-first apps much more complex and time-consuming?
It adds upfront design complexity, particularly around data synchronization and conflict resolution. However, modern tools like local-first databases (SQLite, PouchDB/CouchDB) and well-defined state machines reduce the burden. The real complexity is often in the business logic, not the technical plumbing. Investing that time yields a product that is fundamentally more resilient and opens up markets that competitors, wedded to always-online models, simply cannot enter.
How do you handle security on devices that are physically exposed in remote areas?
Physical security is a layered problem. At the hardware level, we use encrypted storage and secure boot where possible, but we also assume a device could be stolen or tampered with. The design principle is to minimize the value of the device itself: it should hold the minimum necessary data locally, and any sensitive operations should require a remote attestation that can be revoked. A stolen device should be a useless brick, not a key to the kingdom. This often means shifting authentication to a physical token held by the user or a biometric factor that never leaves the local secure enclave.
What’s the first step in auditing a product for these infrastructure assumptions?
Start with a “day in the life” of your user, but honestly. Don’t just observe them in the office with a fiber connection. Go to the loading dock, the delivery van, the rural clinic. Map every external dependency your application has: DNS, NTP, your API gateway, third-party analytics scripts. For each dependency, ask: what happens if this is unavailable for a second, an hour, a week? If the answer is “the application crashes or hangs,” you’ve found your first project. The goal is to contain failures to the feature level, never the application level.
The problem with Western tech assumptions isn’t that the engineers are malicious or unintelligent. It’s that infrastructure is invisible to those who have never lacked it. Our job, as engineers working across these two realities, is to make the invisible visible and to build systems that don’t just tolerate the messy, unpredictable nature of our physical world, but thrive in it. It’s a more demanding way to build, but the result is technology that actually serves the people who need it most, wherever the power lines end.