<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: George Sims</title>
    <description>The latest articles on DEV Community by George Sims (@george-sims).</description>
    <link>https://dev.to/george-sims</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F541611%2Fafe9be05-63e4-4022-8d92-df0fb63196fe.jpeg</url>
      <title>DEV Community: George Sims</title>
      <link>https://dev.to/george-sims</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/george-sims"/>
    <language>en</language>
    <item>
      <title>How DNS Really Works</title>
      <dc:creator>George Sims</dc:creator>
      <pubDate>Sat, 01 Aug 2026 14:08:22 +0000</pubDate>
      <link>https://dev.to/george-sims/how-dns-really-works-3hoi</link>
      <guid>https://dev.to/george-sims/how-dns-really-works-3hoi</guid>
      <description>&lt;p&gt;You've typed a URL into a browser more times than you can count. You've also, at some point, been the engineer paged because "DNS is broken", and if you're honest, you probably fixed it without fully understanding why it broke in the first place. Flushed a cache, waited it out, restarted something, moved on. DNS has a habit of being the thing everyone touches daily and almost nobody actually understands.&lt;/p&gt;

&lt;p&gt;So let's actually walk through it. Not the one-line "it translates domain names to IP addresses" version, but the whole referral chain, the caching layers, and the part where a dozen different organisations across the planet cooperate to answer a question that none of them individually knows the answer to.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The tree nobody drew you&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DNS is organised as a tree, and every node in that tree owns a slice of authority. The root sits at the top. Below it are the top-level domains (TLDs): &lt;code&gt;.com&lt;/code&gt;, &lt;code&gt;.io&lt;/code&gt;, and the two-letter country codes like &lt;code&gt;.uk&lt;/code&gt; or &lt;code&gt;.de&lt;/code&gt;, known as ccTLDs. Below those are second-level domains (SLDs), and so on, until you hit the node that actually knows the IP address you're after.&lt;/p&gt;

&lt;p&gt;Every domain name is just a path through that tree, written backwards and separated by dots. &lt;code&gt;example.com&lt;/code&gt; means "the example node, under the com node, under the root." The root itself technically has a name too: an empty label, represented by a trailing dot. A fully qualified domain name (FQDN) makes that explicit, with a trailing dot added: &lt;code&gt;example.com&lt;/code&gt; You'll almost never type it yourself; the resolution process handles it for you.&lt;/p&gt;

&lt;p&gt;Each node delegates authority to its children and takes on a responsibility in return: making sure everything below it is uniquely named. &lt;code&gt;.com&lt;/code&gt; has to guarantee &lt;code&gt;example&lt;/code&gt; is unique within &lt;code&gt;.com&lt;/code&gt;. It doesn't care what happens under &lt;code&gt;.io&lt;/code&gt;. Whoever holds a zone, meaning the collection of records under a given domain, has to run at least two servers hosting that zone's data, called authoritative name servers, purely for redundancy. The root zone itself runs on 13 servers (&lt;code&gt;a.root-servers.net&lt;/code&gt; through &lt;code&gt;m.root-servers.net&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8zgfusvzl65jse8gc41z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8zgfusvzl65jse8gc41z.png" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Chasing the referral chain&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's the part that trips people up: querying DNS isn't really "asking a database". It's chasing a chain of referrals until someone actually knows the answer.&lt;/p&gt;

&lt;p&gt;Your machine runs something called a stub resolver, a lightweight client that's the first stop for any lookup. Before it even leaves your machine, it checks two local sources: your &lt;code&gt;/etc/hosts&lt;/code&gt; file for manual overrides, and its own small cache. If neither has an answer, the stub resolver fires off a recursive query to a resolver, usually your ISP's, or a public one like Cloudflare's &lt;code&gt;1.1.1.1&lt;/code&gt;. "Recursive" here means the stub resolver is handing off responsibility entirely: give me the full answer, I don't want to be involved in the legwork.&lt;/p&gt;

&lt;p&gt;That's the resolver's problem now, and it earns its keep. If it doesn't have the answer cached, it starts walking the tree itself, iteratively this time, meaning it does the querying and follows referrals hop by hop. First stop, a root server, which has no idea what &lt;code&gt;example.com&lt;/code&gt;'s IP address is, but knows exactly who to point towards: the &lt;code&gt;.com&lt;/code&gt; TLD server. The TLD server doesn't know the IP either, but knows which authoritative name server holds &lt;code&gt;example.com&lt;/code&gt;'s zone, and refers the resolver there. Finally, that authoritative server actually has the record and hands back the IP. For real this time, not another referral.&lt;/p&gt;

&lt;p&gt;The resolver's pseudocode might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server_ip&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# sends network request which returns result or referral
&lt;/span&gt;  &lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;referral&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;referral&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;nameserver&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; &lt;code&gt;find-ip&lt;/code&gt; &lt;em&gt;calling itself is recursion in the everyday programming sense, a different thing entirely from the "recursive query" we just talked about. The protocol term describes the client's relationship to the resolver. Whether the resolver's own code loops or recurses internally is an implementation detail; what makes its queries to root, TLD, and authoritative servers iterative is that each of those servers only ever answers with what it currently knows and never chases anything further itself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To wrap this section up, here's a simple, everyday example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's like trying to find someone's desk in a building you've never visited. You walk up to the ground-floor reception and ask for Dave from Example Corp. Reception has never heard of Dave, but they know Example Corp is on floor 12, so up you go. Floor 12's reception doesn't know Dave's desk number either, but points you to the right row. Only when you reach that row does someone actually know where Dave sits and can point straight at him. Nobody you spoke to along the way had the answer. They just knew who to send you to next.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That referral pattern is exactly why DNS scales to hundreds of millions of domains without collapsing under its own weight. Nobody has to hold the whole directory; they just have to know one level down.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Not all resolvers are equal&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It's worth being precise about the difference between a stub resolver and a recursive resolver, because conflating them is a genuinely common source of confusion when you're debugging.&lt;/p&gt;

&lt;p&gt;The stub resolver lives on your machine and does almost nothing clever: check &lt;code&gt;/etc/hosts&lt;/code&gt;, check a tiny local cache, forward the rest. The recursive resolver is the one doing real work, holding a much bigger cache, walking the tree, and absorbing the latency of slow lookups so your applications don't have to. Most people never choose their recursive resolver explicitly. It's whatever their ISP hands them via DHCP. Some of us do choose: Cloudflare's &lt;code&gt;1.1.1.1&lt;/code&gt; is a common pick, mostly for speed and a genuinely audited privacy stance. They don't sell query data, and the bulk of what little they log is deleted within 25 hours. If you want the VPN-adjacent version of the same idea, their WARP client tunnels all your device's traffic over the same network. No affiliation, just deserves to be mentioned here.&lt;/p&gt;

&lt;p&gt;If you ever want to see exactly what your browser thinks it knows, &lt;code&gt;chrome://net-internals/#dns&lt;/code&gt; still works and shows Chrome's own resolver cache. Handy the next time you're trying to work out whether a stale record is a browser problem, an OS problem, or an actual DNS problem three hops away.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The TTL sticky note&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every DNS record ships with a TTL, or time to live, telling resolvers how long they're allowed to cache the answer before asking again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of it like sticking a Post-it note with someone's phone number on your fridge. Next time you need to call them, you read the note instead of looking the number up again, much faster. But the note has an expiry date scrawled in the corner. Once that date passes, you throw it away and go look the number up properly, in case it changed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is also the single most common cause of "I changed the DNS record and nothing happened". Somewhere between you and the client, a resolver is still reading last week's Post-it note. It's why, if you're planning a change to an A record, the sane move is to drop the TTL well in advance, let the old value fully expire out of caches everywhere, make the change, and only then bump the TTL back up.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The record types you'll actually touch&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A quick reference, because you'll use maybe four of these regularly and forget the rest exist until you need them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Record&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain to IPv4 address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AAAA&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain to IPv6 address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CNAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Alias to another name, never to an IP directly. Commonly used for subdomains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Directs mail for the domain to a mail server, with a priority value for failover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TXT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Free-form text, these days mostly domain ownership verification and spam-prevention records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Declares which server is authoritative for the domain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SOA&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zone metadata: admin contact, last-updated timestamp, refresh timings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SRV&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Host and port for a specific service. Must point at an A/AAAA record, never a CNAME&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PTR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reverse lookup, IP to domain. Useful for spam filtering and for making sense of logs that only have an IP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CNAME chains, where a CNAME points at another CNAME, technically work, but every extra hop is another lookup your client has to make before it gets an answer. Point straight at the A/AAAA record where you can.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Putting it all together&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0udgrkvmsjajor712dh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0udgrkvmsjajor712dh5.png" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Getting a domain live&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you've never registered one yourself: you buy the name from a registrar, then a hosting provider (sometimes the same company, sometimes not) hosts the actual zone file on their name servers. The hosting provider's NS information gets registered against the TLD, which is what makes the domain queryable from anywhere on the internet. Once that propagates, you're live.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why this actually matters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Understanding the referral chain changes how you debug. "DNS is being weird" stops being a shrug and becomes a specific question: is this a stub resolver cache, a recursive resolver cache, a stale TTL, or an actually misconfigured record upstream? Each of those has a different fix, and only one of them is solved by "wait and see".&lt;/p&gt;

&lt;p&gt;It also changes how you plan changes. Reduce your TTL before you touch a record, not after. Understand that "propagation delay" isn't some mystical internet phenomenon. It's just caches around the world honouring TTLs you set weeks ago. Once you've internalised that DNS is fundamentally a tree of servers that mostly don't know the answer and just know who to ask next, a whole category of "why is this slow" and "why is this stale" questions stop being mysterious.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This piece skips DNSSEC, EDNS Client Subnet, and the fact that most of these servers are anycast, meaning many physical machines answering as a single IP.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>platformengineering</category>
      <category>networking</category>
      <category>dns</category>
      <category>resolver</category>
    </item>
    <item>
      <title>How a Process Really Works</title>
      <dc:creator>George Sims</dc:creator>
      <pubDate>Wed, 01 Jul 2026 10:35:53 +0000</pubDate>
      <link>https://dev.to/george-sims/how-a-process-really-works-205c</link>
      <guid>https://dev.to/george-sims/how-a-process-really-works-205c</guid>
      <description>&lt;p&gt;As a DevOps/SRE/Platform Engineer you see many varieties of processes in the wild; Microservices writing to a database, a CI pipeline which runs linters and unit tests, the Docker ecosystem itself is a type of abstraction on a process with some OS magic thrown in. Sure that's pretty easy - we all know these things. But do you really understand how that process runs under the hood?&lt;/p&gt;

&lt;p&gt;The process is the Operating System's way of executing a program, seemingly at the same time as all of the other programs running on our computer. In its simplest form, the program is an executable living on a disk. It has instructions within it, but the OS has the task of making it run (ideally successfully) alongside everything else already occupying the CPU.&lt;/p&gt;

&lt;p&gt;First, it helps to understand how the CPU works. The CPU has the capability to execute one thing at any given time*****. On modern PCs that sounds very limited. Imagine how many programs are currently running at the same time even as you read this: your laptop is probably running your IDE, some Docker containers and fetching all of your Slack messages. Under the hood the OS is doing something incredible: all of these programs are not running at the same time, but instead made to seem like they are. For this to be successful the CPU must be able to execute the programs almost instantaneously, swapping them out when the scheduler sees fit, so the internal state of each program must be known and stored somewhere in working memory, which is where the abstraction of the program - the process - is key.&lt;/p&gt;

&lt;p&gt;When talking about a process it can be described by its state. A state includes what the process can read/write to, which parts of memory it has access to and also all of its instructions that are stored in memory ready to execute. It helps to think about a process like a box, everything inside the box is used to run the program, if the CPU has the box then it can successfully run the program which that box defines. This box must be loaded into memory from the disk. The program on disk is normally already 'translated' from the programming language it is written in to a form which is understandable by the CPU, this is usually a compiled executable file (think of the output file of a &lt;code&gt;gcc&lt;/code&gt; compiler). Historically Operating Systems would load the whole program/executable into memory, but these days they are loaded 'lazily' meaning only the parts of the executable that are required in that moment are loaded.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's like baking a cake!&lt;br&gt;&lt;br&gt;
Think of a process like a cake recipe being made in the kitchen. The kitchen manager (OS scheduler) hands the baker (CPU) a set of prepared ingredients and the steps (ingredients + steps = process). The baker would then simply follow those instructions using the ingredients to bake the cake (process execution).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are two important data structures used by a process: the stack and the heap. The local variables, function parameters, return addresses etc are stored in the stack during runtime by the process. The nature of the stack is LIFO (last in, first out), the process needs to remember where to return to after calling any function. To do this it will 'push' the return address (register) to the stack, once the function has finished the process can then 'pop' the stack to get that address to return back to. The heap can be seen as something which grows over time during the life of the process. Data structures which grow dynamically such as linked lists and hash tables are stored there. Think about the C function &lt;code&gt;malloc()&lt;/code&gt;, it is used to dynamically allocate memory to be used during execution, the heap is the place where that will be stored.&lt;/p&gt;

&lt;p&gt;Now we have all of the pieces of the process defined and loaded, the process is now ready to be scheduled on the CPU. This is the job of the scheduler. The scheduler is managed on the OS level and uses scheduling policies which help determine which processes should be run on the CPU and when. Historical information, performance metrics and workload knowledge are all things the scheduler will check to make an informed decision. There is a list of states that a process can be in at any given time, the three main ones are: 'Running', 'Blocked' and 'Ready'. Naturally when running it means that the CPU is executing the process. When a process, say a network call or a DB write happens, they both require I/O (which in the CPUs mind is an eternity), this means that the CPU should run something else while waiting even though the process isn't finished yet. Once those processes have the data they were waiting for, they are considered ready and the scheduler will eventually make them CPU bound again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The bread is burning!&lt;br&gt;&lt;br&gt;
Go back to our baker analogy. If she was following the recipe and she suddenly smelled smoke, that would take higher priority than her current cake. The kitchen manager would then mark down where she was in the recipe, tell her to attend to the potential fire (a different process), then pick up where she left off. That is how context switching works on the CPU - a different process is required to run (be it due to priority or simply time) so the current process' context is saved so it can be loaded back again afterwards.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What about program size? To be successful the program must first be loaded into memory before it can be executed by the CPU - but what if that program is larger than what is available on the machine? Back in the day the process would simply fail. Program creators would make sure that the program would take up N addresses, where N was address 0 up to 2^32 on 32-bit machines and 2^64 on 64-bit. Upon loading the whole program could then be stored in the available addresses before execution. Nowadays computers have the capability to use virtual memory, an abstraction on both disk and RAM. The OS allows for the process to only be loaded partially into available memory, and when required load parts of the program from the disk to memory, swapping out the unused parts. This is called paging. This way the program can grow way past the limitation of memory, and instead be limited by physical disk space. This abstraction also allows each process to be totally isolated and not corrupt another's address space - crucial to the architecture of containers, which we will cover in a future post.&lt;/p&gt;

&lt;p&gt;After reading this post you should now not only grasp how processes work under the hood, but also start to think about why parallelization is so important to factor into your design choices as early as possible. If your microservice requires a DB call, make it asynchronous so that another process can run while it waits. Write your CI pipelines so that your linting, unit testing and building don't block each other while I/O bound. Finally always understand that you are at the mercy of the CPU scheduler when trying to get everything perfectly synced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;*modern CPUs have multiple cores and thus can actually run two or more things at once, but for simplicity's sake let's assume we have one core&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>operatingsystem</category>
      <category>linuxprocesses</category>
      <category>platformengineering</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
