← Back to writing

April 19, 2026

Designing for Real Constraints

Designing for Real Constraints

“Why would the app be 120MB? I’m not downloading.”
— Typical Nigerian mobile user

Yet most developers still don’t care.

If you check Twitter or other online forums, you’ll see arguments about which tools give the best developer experience, what operating system is superior, or what setup makes you the most productive. I understand the appeal. A good developer experience can lead to a good user experience. But it doesn’t always translate, especially when real-world constraints are involved.

I’ve built and deployed products in those constraints. One of them is Acadeva.

Seeing tools built for a mobile-dominated market like Nigerian students, yet only working properly on desktops or requiring strong internet and large downloads, makes you wonder if the builders truly understand their users.

The Reality We Build For

Let’s use Africa as a case study.

Africa is a mobile-first market. The vast majority of users rely on smartphones for their day-to-day digital activities, and for many, it’s their only computing device.

But the infrastructure is not scaling at the same pace.

Every day, new SIM cards are activated and new devices come online, yet network quality often remains inconsistent due to congestion and limited expansion of supporting infrastructure. Electricity is another layer of the problem. Power supply is unreliable in many areas, which means users are constantly managing battery life.

These are not edge cases. This is the environment.

So when you build an app that assumes:

  • fast and stable internet
  • constant connectivity
  • large storage space
  • high RAM availability

you’re not building for your market. You’re building for a version of it that doesn’t exist.

Performance Is the Product

Apps should be designed to use less processing power, less RAM, less data, and less battery. This is not an optimization phase you leave for later. It is part of the product itself.

There’s a reason apps like WhatsApp dominate. It’s not just features. It’s efficiency. It works across low-end devices, survives poor networks, and respects user resources.

Now compare that to many modern apps that repeatedly fetch the same data, ignore caching, and ship unnecessarily large bundles.

The other day, I noticed that Acadeva was making too many requests to the server immediately after opening. When I checked the code, I found that a piece of AI-generated logic was fetching data that was already available in local storage.

My issue wasn’t that AI was used. The issue was that no one questioned it.

AI will give you working code. It will not automatically give you optimized code for your environment. You still have to think.

The Gap in Modern Development

A lot of developers today, especially those growing up with AI tools, can build features quickly. But many lack a solid understanding of caching, optimization, and system design.

And because things work fine on high-end devices, they ship.

Meanwhile, the average Android phone in many African markets runs on around 3GB RAM. That difference matters.

This is why I strongly believe that beyond knowing how to code, developers need to understand how systems behave under constraints. Best practices and optimization are not optional skills. They are foundational.

A good developer is not just someone who builds features. It’s someone who can build for constraints, whether real or simulated.

Building Acadeva with Constraints in Mind

When we set out to build Acadeva, these realities guided every decision.

I constantly thought about every resource going into the final bundle and tracked how requests impacted performance. We treated efficiency as a requirement, not a bonus.

  • All assets were compressed as much as possible
  • Data that doesn’t change frequently is stored offline
  • Network requests were reduced and carefully monitored

For local storage:

  • On Android: Room (SQLite ORM) or DataStore
  • On iOS: Core Data or NSUserDefaults depending on the use case
  • With Capacitor: IndexedDB, localStorage, or Capacitor Storage and SQLite plugins

For performance testing, Chrome Lighthouse was useful for simulating slower network conditions and identifying bottlenecks early.

The target was always mobile. That decision alone simplifies many trade-offs.

What Happens If You Ignore This

Picture this.

A user is running out of storage. Their phone starts suggesting apps to delete.

Your app is at the top of that list because of its size.

Or your app quietly drains their data subscription every time it runs in the background.

Or it eats into their battery at a time when they may not have power for hours.

In those moments, your features don’t matter. Your design doesn’t matter.

Your app is gone.

Final Thoughts

Build for the worst.

Assume poor internet. Assume low battery. Assume limited storage. Assume entry-level devices.

If your app works well there, it will work anywhere.

You may not hit every target perfectly, but you will build something that survives real-world conditions.

And in markets like Africa, survival is what separates products that exist from products that matter.