Module 0 · How software actually works

0.1 What happens when you open an app

Lesson 0.1 · 14 min read

There's a moment you've seen ten thousand times and never thought about once.

You tap an icon. Something spins for a fraction of a second. Then a screen full of content appears, your content, loaded fresh, arranged just for you. Instagram knows which photos to show you. Your banking app knows your balance. Gmail knows about the email that arrived four seconds ago.

None of that content was sitting inside the app on your phone. It couldn't have been. The app on your phone is a few dozen megabytes. Your Instagram feed, drawn from billions of photos updated every second by hundreds of millions of people, does not fit in a few dozen megabytes. So where did it come from? How did it get to your screen so fast? And why does understanding this one journey matter for everything you're about to build?

Let's follow it, all the way down and all the way back.


The two computers

Here's the first idea, and almost everything else rests on it.

When you use an app, you are almost never using one computer. You're using two, and they're talking to each other.

The first computer is the one in your hand, or on your desk. This is the client. It's the thing the user actually touches. Its job is to show things and to capture what the user does: taps, scrolls, typing, swipes.

The second computer is somewhere else entirely. It might be in a data center in Virginia, or Ireland, or Singapore. You will never see it. This is the server. Its job is to hold the real information, do the serious work, and answer questions that the client asks.

The client is a storefront. Bright, designed, arranged to be looked at and walked through. The server is the warehouse out back, and the accounts office above it, and the manager who decides what's in stock. When you walk into a store and ask "do you have this in a medium?", the person at the counter doesn't personally know. They check with the back. The storefront is where you stand. The warehouse is where the truth is kept.

Your Instagram feed lives in the warehouse. The app on your phone is the storefront that goes and asks for it.

So the whole event of "opening an app and seeing your stuff" is really a conversation between these two computers. One asks. The other answers. Almost everything in software is some version of this exchange, and the more precisely you understand it, the more precisely you can build.

Let's watch the conversation happen, step by step.

Interactive: request response journey

A hands-on visual for this idea is in the works. The text around it carries everything you need for now.


Step one: the client needs to find the server

You tap the icon. The app wakes up and immediately has a problem: it needs to talk to its server, but where is the server?

Servers don't have names. They have numbers, called IP addresses, that look like 142.250.190.78. Every computer reachable over the internet has one, the way every house on Earth has a physical address. But nobody wants to memorise 142.250.190.78. We want to type instagram.com.

So there's a translation layer, and it's one of the quietly essential pieces of the entire internet. It's called DNS, the Domain Name System, and it is exactly a phone book. You know the name of who you want to reach. DNS knows their number. The app asks DNS "what's the address for instagram.com?", DNS answers with the IP address, and now the app knows where to send its question.

This lookup happens in a few milliseconds and you never see it. But it's happening, every time, for every app and website. When someone says "the DNS is down," this is what broke: the phone book. The servers are all still there, humming away, perfectly fine. Nobody can find their number.


Step two: the client sends a request

Now the app knows the server's address. Time to actually ask for something.

The app sends a request. This is a small, structured message that travels across the internet to the server, and it says, in effect: "Hi. It's me, this specific logged-in user. Please give me my feed."

That request is more than a plea into the void. It carries specifics. It says what it wants (the feed). It carries proof of who's asking (a token that says "this really is this user, already logged in, allowed to see their own feed"). It might carry details (give me the newest 20 posts, not all of them). The request is a precise order slip handed across the counter, not a vague gesture.

The request travels using a set of rules called HTTP, the Hypertext Transfer Protocol. Don't let the long name scare you. A protocol is just an agreed-upon format for a conversation, so both sides understand each other. When you call a restaurant to book a table, there's an unspoken protocol: you say the day, the time, the number of people, a name. HTTP is that same idea, formalised, so that any client and any server anywhere in the world can understand each other's requests and answers. It's the shared grammar of the web.

You'll also see HTTPS, with the S. That's the identical thing with one crucial addition: the whole conversation is scrambled so that anyone who intercepts it in transit sees only nonsense. The order slip is sealed in an envelope instead of written on a postcard. Every serious app uses HTTPS, always, and later in the series you'll understand exactly how that scrambling works and why it's close to unbreakable.


Step three: the server does the real work

The request arrives at the warehouse. Now the interesting part begins, and this is where the actual engineering lives.

The server reads the request and starts working. First, it checks the token: is this really who they claim to be, and are they allowed to ask for this? (This is authentication and authorization, and it's a whole topic we'll give real attention to, because getting it wrong is how data leaks.) Assuming that checks out, the server goes to find the answer.

But the answer isn't just sitting there ready. The server has to build it. To assemble your feed, it needs to figure out who you follow, find their recent posts, decide the order to show them in, maybe mix in an ad or two, and check which ones you've already seen. That information doesn't live in the server's own memory. It lives in a database, which is a separate, specialised system built for one purpose: storing enormous amounts of information and finding exactly the right piece of it, fast.

So the server, in the middle of handling your request, turns around and makes its own request, to the database. It asks a precise question in a language built for exactly this, and the database answers. The server might do this several times, gathering the pieces. Then it takes all those raw pieces and shapes them into a clean, organised answer, ready to send back.

Notice the pattern repeating. The client asked the server. Now the server is asking the database. It's requests and responses all the way down, each layer asking the layer beneath it for what it needs. Once you see this pattern, you start seeing it everywhere, and complex systems stop looking like magic and start looking like a chain of simple conversations.


Step four: the response travels back

The server has built the answer. Now it sends it back across the internet to your phone. This is the response.

The response usually isn't a finished screen. This surprises people at first. The server doesn't send back a picture of your feed. It sends back the data of your feed, in a clean, structured format, most commonly one called JSON, which is just a tidy, organised way of writing down information so a computer can read it reliably. Think of it as the answer arriving as a precisely filled-out form, not as a photograph. It lists the posts, and for each one: who posted it, the image address, the caption, the like count, the timestamp.

Why data and not a picture? Because it's smaller, faster to send, and it lets the client decide how to present it. The same feed data can be arranged one way on your phone, another way on a tablet, another way on the website. The warehouse ships the raw goods. The storefront arranges the display. Keeping those two jobs separate is one of the foundational ideas in how software is built, and we'll come back to it many times.


Step five: the client renders

The data arrives back at your phone. Now the app does the final job, the one you actually see.

It takes that structured data and turns it into the visible, tappable, scrollable thing on your screen. It reads "here's a post, here's the image address, here's the caption," and it draws that, fetches the actual image, lays out the text, wires up the like button so it responds to your tap. This process of turning data into what the user sees is called rendering, and it's the client's specialty. The storefront receives the goods from the warehouse and builds the display.

And now the loop is closed. You tapped an icon, and a few hundred milliseconds later you're looking at a fresh, personal, up-to-the-second feed, assembled on demand by two computers having a fast and precise conversation on your behalf. It felt instant. It wasn't. It was a whole journey, and now you've seen every step of it.


Wait, is any of this different on mobile?

We used Instagram on a phone as the example, so you might assume we've been describing mobile all along. Mostly we have. But it's worth stopping here, because "is a mobile app different from a website?" is one of the first real questions a builder has to answer, and the answer shapes what you build and how.

Here's the reassuring part first. The skeleton does not change. A mobile app is still a client. It still finds a server through DNS, still sends requests over HTTP, still gets back JSON, still renders it to the screen. The two computers, the request, the response: all identical. Whatever you learned above, you keep. Mobile doesn't rewrite the rules. It just changes the client side of the story in a few ways that genuinely matter.

The biggest difference is how the client gets onto the device, and what it is. A website has no installation. You type a URL, and the browser downloads the client fresh every time, then throws most of it away when you leave. A mobile app is different: you install it from the App Store or Play Store, and a real chunk of software now lives permanently on the phone. That installed bundle is the client. It's already sitting there before you ever open it, which is part of why apps can feel snappier than websites and can do things the moment you tap, before any server is even contacted.

That installed nature creates a second real difference: updates work differently, and this catches builders off guard. When you fix a bug on a website, you change it on the server and every visitor gets the new version instantly on their next load. There's one copy, and it's yours. On mobile, the client is already on millions of phones. Pushing a fix means shipping a new version to the App Store, waiting for Apple or Google to review it, and then waiting for users to actually update, which many never do. So at any moment your app is running on dozens of different versions across the world, and you have to design for that. This is a genuine engineering constraint, not a footnote, and it's why serious mobile teams keep as much logic as possible on the server, where they can change it freely, and put as little as possible in the installed app, which is slow and painful to change.

Now, to the question of what "a mobile app" even is, because there's a real fork in the road here that you'll have to choose between when you build one.

Native means the app is built specifically for one operating system, using that system's own tools: Swift or Objective-C for Apple's iOS, Kotlin or Java for Android. This is a custom-tailored suit. It fits perfectly, it's the fastest, and it can reach everything the phone offers: camera, GPS, notifications, the fingerprint sensor, all of it, with full smoothness. The cost is that it fits only one body. Building for both iPhone and Android the native way means building the same app twice, in two languages, with two teams' worth of effort.

Cross-platform is the answer to that cost. Tools in this category let you write the app once and run it on both iOS and Android from a single codebase. It's an off-the-rack suit, well-fitted and far cheaper to produce in two sizes at once. For most products this trade is well worth it, which is why a large share of the apps on your phone are built this way. The cost is a thin layer of translation between your code and each phone's native abilities, which occasionally means slightly less smoothness or a delay before the newest phone features are reachable.

And then there's the option of no app at all. A well-built website can run beautifully on a phone's browser, adjusting its layout to the small screen. This is a mobile web experience, and its superpower is that there's nothing to install and nothing to update: it's just a website, so it has all the instant-update freedom we described. Its limit is reach. A browser, for safety reasons, only lets a website touch a narrow slice of the phone's hardware. Deep camera control, certain sensors, the most seamless notifications: these are often gated behind having a real installed app. So the choice between a real app and a mobile website is really a trade between reach and friction, and understanding that trade is how you make the call deliberately.

The takeaway is this. Everything you learned about the journey still holds on mobile, without exception. What mobile adds is a set of choices and constraints on the client end: an installed thing instead of a fetched one, a slower and stricter path to shipping changes, and a real decision about whether to build native, cross-platform, or lean on the web. We'll go deeper into each of these when we reach the frontend and deployment modules. For now, just hold the shape of it: same skeleton, different skin, with real consequences hanging off the difference.


Why this matters more than it seems

You could be forgiven for thinking this is just trivia, a nice diagram to nod at. It isn't. This single journey is the skeleton that every decision you'll make as a builder hangs on. Let me show you what I mean, because this is the part that separates knowing the steps from understanding them.

Every step takes time, and time is the user experience. The DNS lookup, the request traveling to the server, the server querying the database, the response traveling back, the rendering. Each one costs milliseconds, and they add up into the thing your user actually feels as "fast" or "slow." When you understand that a screen's speed is the sum of a specific chain of events, you stop treating slowness as a mystery and start treating it as something with causes you can find and fix. We'll spend a whole post on exactly this, because the cost of every millisecond is more concrete, and more designable, than most people realise.

Where work happens is a real choice with real consequences. Some work can be done on the client, some must happen on the server. That decision affects speed, security, and cost. Put something on the client that belonged on the server, and you might expose data you shouldn't, or make the app easy to cheat. Understanding the two computers is what lets you make that call deliberately instead of accidentally.

Most bugs live at the boundaries. When something breaks in a real app, it's very often not inside one of these steps but in the handoff between them. The request that didn't carry the right token. The response that came back in a shape the client didn't expect. The database query that returned nothing. When you understand the journey, a broken app stops being a wall of panic and becomes a short list of specific places to look. Did the request go out? Did the server answer? Did it answer with the right thing? Did the client understand the answer? That checklist is a debugging superpower, and it comes directly from understanding this one loop.

Every app you admire, and every app you'll build, is running this loop constantly, thousands of times, as you scroll and tap. It is the heartbeat of software. Everything else in this series is, in one way or another, a deeper look at one part of this journey: the client, the server, the request, the database, the response. You now have the whole map in your head. From here, we go closer.


Do this before the next post

Open any website in a desktop browser, right-click anywhere on the page, and choose "Inspect." A panel will open. Find the tab labeled Network, then reload the page.

Watch the list fill up. Every single line is a request, exactly the kind we just followed. The client asking the server for something: the page, an image, your data. Click on one and you'll see the request go out and the response come back. You don't need to understand the details yet. Just watch it happen, and notice how many separate conversations it takes to build one page you thought of as a single thing.

That panel is going to become one of your most important tools, and we'll return to it properly soon. For now, just look. You're watching the two computers talk.