<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Exploring how software works behind the scenes.]]></title><description><![CDATA[Exploring how software works behind the scenes.]]></description><link>https://mohdashraf.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Exploring how software works behind the scenes.</title><link>https://mohdashraf.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 31 Aug 2026 06:53:42 GMT</lastBuildDate><atom:link href="https://mohdashraf.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Serialization and Deserialization: The Invisible Backbone of Modern Software]]></title><description><![CDATA[If you've ever called an API, saved a file, cached a value in Redis, or sent a message through a queue - you've relied on serialization and deserialization, whether you noticed it or not.
They don't g]]></description><link>https://mohdashraf.hashnode.dev/serialization-and-deserialization-the-invisible-backbone-of-modern-software</link><guid isPermaLink="true">https://mohdashraf.hashnode.dev/serialization-and-deserialization-the-invisible-backbone-of-modern-software</guid><dc:creator><![CDATA[mohd ashraf]]></dc:creator><pubDate>Thu, 23 Jul 2026 10:00:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/687227034b82e8222fc752d9/db0b8ca2-bdb1-4c92-b37e-500959574162.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've ever called an API, saved a file, cached a value in Redis, or sent a message through a queue - you've relied on serialization and deserialization, whether you noticed it or not.</p>
<p>They don't get much attention because they <em>just work</em> - until they don't. A schema mismatch, a broken field, an insecure <code>pickle.loads()</code> call, and suddenly this "boring" concept becomes the most important thing in your stack.</p>
<p>This post breaks down what serialization and deserialization actually are, why they exist, the formats you'll encounter, and the pitfalls that catch even experienced engineers off guard.</p>
<hr />
<h2>The Core Problem</h2>
<p>Every running program holds its data in <strong>memory</strong> - as objects, structs, arrays, and references. This representation is:</p>
<ul>
<li><p>Specific to the programming language and runtime</p>
</li>
<li><p>Tied to a particular memory layout (pointers, addresses)</p>
</li>
<li><p>Completely local to that one running process</p>
</li>
</ul>
<p>That's fine as long as your data never needs to leave the process. But almost nothing in modern software works that way. You need to:</p>
<ul>
<li><p>Send data to another service over a network</p>
</li>
<li><p>Save data to disk so it survives a restart</p>
</li>
<li><p>Store data in a database or cache</p>
</li>
<li><p>Pass data between programs written in different languages</p>
</li>
</ul>
<p>Raw in-memory objects can't do any of that. You can't copy a Python object's memory bytes into a Java process and expect it to make sense. You need a <strong>common, portable representation</strong> - and that's exactly what serialization gives you.</p>
<hr />
<h2>Definitions</h2>
<p><strong>Serialization</strong> is the process of converting an in-memory object into a linear format (text or bytes) that can be stored or transmitted.</p>
<p><strong>Deserialization</strong> is the reverse process - taking that stored or transmitted format and reconstructing the original object so a program can use it again.</p>
<p>Think of it like packing a suitcase before a flight. Your clothes (the object) are only useful when worn, but you can't just throw them loose into an airplane. You fold and pack them (serialize) into something that survives the trip, then unpack them (deserialize) at your destination so they're wearable again.</p>
<pre><code class="language-python">import json

# Serialization: Python object → JSON string
data = {"name": "Alice", "age": 30}
serialized = json.dumps(data)
# '{"name": "Alice", "age": 30}'

# Deserialization: JSON string → Python object
deserialized = json.loads(serialized)
# {"name": "Alice", "age": 30}
</code></pre>
<p>Simple as that example looks, this exact pattern underlies API calls, config loading, cache reads/writes, and message queues across virtually every backend system in production today.</p>
<hr />
<h2>Common Serialization Formats</h2>
<p>Not all serialization formats are created equal. Picking the right one is an actual engineering decision, not a formality.</p>
<table>
<thead>
<tr>
<th>Format</th>
<th>Type</th>
<th>Notes</th>
</tr>
</thead>
<tbody><tr>
<td><strong>JSON</strong></td>
<td>Text</td>
<td>Human-readable, ubiquitous, the default for REST APIs and config files</td>
</tr>
<tr>
<td><strong>XML</strong></td>
<td>Text</td>
<td>Verbose, supports schemas/validation, common in legacy and enterprise systems</td>
</tr>
<tr>
<td><strong>YAML</strong></td>
<td>Text</td>
<td>Human-friendly, popular for config files (Kubernetes, CI/CD pipelines)</td>
</tr>
<tr>
<td><strong>Protocol Buffers (protobuf)</strong></td>
<td>Binary</td>
<td>Compact and fast, requires a predefined <code>.proto</code> schema, used heavily with gRPC</td>
</tr>
<tr>
<td><strong>MessagePack</strong></td>
<td>Binary</td>
<td>JSON's structure, but binary and smaller</td>
</tr>
<tr>
<td><strong>Avro</strong></td>
<td>Binary</td>
<td>Schema-based, popular in big data pipelines (Kafka, Hadoop)</td>
</tr>
<tr>
<td><strong>Pickle</strong></td>
<td>Binary</td>
<td>Python-specific, can serialize almost any object - but dangerous with untrusted input</td>
</tr>
<tr>
<td><strong>BSON</strong></td>
<td>Binary</td>
<td>Used internally by MongoDB</td>
</tr>
</tbody></table>
<p><strong>Text formats</strong> trade size and speed for human readability and easy debugging - you can open a JSON payload and immediately understand it.</p>
<p><strong>Binary formats</strong> trade readability for speed and compactness. At scale, that trade-off matters a lot: smaller payloads mean less bandwidth, faster serialization means lower latency.</p>
<hr />
<h2>Where This Shows Up in Real Systems</h2>
<p>Serialization isn't a niche concept - it's load-bearing infrastructure across nearly every layer of a modern application:</p>
<p><strong>APIs and microservices</strong> - Service A serializes a response to JSON, sends it over HTTP, and Service B deserializes it into its own internal objects. This is the entire basis of REST.</p>
<p><strong>Message queues</strong> - Kafka, RabbitMQ, and SQS all pass serialized messages between producers and consumers. The producer doesn't know or care what language the consumer is written in - the message format is the contract.</p>
<p><strong>Databases</strong> - ORMs serialize objects into rows and columns (or JSON columns for semi-structured data). Document stores like MongoDB store BSON directly.</p>
<p><strong>Caching layers</strong> - Redis and Memcached store serialized blobs. Every cache write is a serialization; every cache read is a deserialization.</p>
<p><strong>RPC frameworks</strong> - gRPC uses protobuf for fast, strongly-typed communication between services, trading some flexibility for major performance gains over plain JSON.</p>
<p><strong>File I/O and persistence</strong> - Saving application state, session data, or config - anything that needs to survive a process restart goes through this cycle.</p>
<p><strong>Distributed computing</strong> - Spark and Hadoop serialize data constantly to shuffle it between nodes in a cluster.</p>
<p>If you removed serialization from any of these systems, they'd simply stop functioning. There'd be no way to move data across the process boundary.</p>
<hr />
<h2>Design Considerations That Actually Matter</h2>
<h3>1. Schema and Versioning</h3>
<p>Software evolves. If Service A adds a new field to its data model and Service B is still running against the old schema, deserialization can silently break - or worse, silently misinterpret data.</p>
<p>This is one of the most underrated failure modes in distributed systems. A few ways teams handle it:</p>
<ul>
<li><p><strong>Protobuf and Avro</strong> handle this gracefully through field numbering and default values, allowing backward and forward compatibility by design.</p>
</li>
<li><p><strong>Plain JSON</strong> needs discipline - ignore unknown fields on read, provide sane defaults for missing ones, and version your API contracts explicitly (<code>/v1/</code>, <code>/v2/</code>).</p>
</li>
</ul>
<p>Skipping this step is how "it worked in staging" turns into a 2 AM production incident.</p>
<h3>2. Performance</h3>
<p>Text formats are slower to parse and bulkier over the wire. In high-throughput systems - trading platforms, real-time analytics, anything latency-sensitive - binary formats like protobuf or FlatBuffers are preferred because they serialize and deserialize faster while using less bandwidth.</p>
<p>This is a genuine trade-off, not a strict upgrade: you lose human readability and easy debugging in exchange for speed. Most teams start with JSON and only move to a binary format once performance data justifies it.</p>
<h3>3. Security</h3>
<p>This is the one that gets underestimated the most. Deserialization is a real, well-documented attack surface.</p>
<p>If you deserialize untrusted input - especially using formats that support object reconstruction with executable behavior, like Java's native serialization or Python's <code>pickle</code> - an attacker can craft a malicious payload that executes arbitrary code the moment it's deserialized.</p>
<p>A few concrete rules:</p>
<ul>
<li><p><strong>Never call</strong> <code>pickle.loads()</code> <strong>on data from an untrusted source.</strong> It's not a hypothetical risk - it's a well-known Python attack vector.</p>
</li>
<li><p>Java has had multiple major CVEs tied specifically to insecure native deserialization.</p>
</li>
<li><p>JSON and XML are generally safer, since they don't inherently support executing arbitrary code - but XML has its own well-known risk: <strong>XXE (XML External Entity) injection</strong>, which can be used to read local files or perform server-side request forgery if the parser isn't configured defensively.</p>
</li>
</ul>
<p>The rule of thumb: treat any deserialization of untrusted input the same way you'd treat untrusted input anywhere else in your system - validate it, sandbox it, and prefer formats that don't allow arbitrary code execution during parsing.</p>
<h3>4. Cross-Language Compatibility</h3>
<p>If your frontend is JavaScript and your backend is Java (or Go, or Rust, or anything else), you have no way to share native, language-specific object serialization. You need a common format both sides understand - which is exactly why JSON became the lingua franca of the web, and why protobuf schemas are shared explicitly across services in polyglot microservice architectures.</p>
<hr />
<h2>A Concrete Example Across Formats</h2>
<p><strong>In-memory object (conceptual):</strong></p>
<pre><code class="language-plaintext">Person { name: "Alice", age: 30, hobbies: ["reading", "chess"] }
</code></pre>
<p><strong>As JSON:</strong></p>
<pre><code class="language-json">{"name": "Alice", "age": 30, "hobbies": ["reading", "chess"]}
</code></pre>
<p><strong>As a Protobuf schema:</strong></p>
<pre><code class="language-protobuf">message Person {
  string name = 1;
  int32 age = 2;
  repeated string hobbies = 3;
}
</code></pre>
<p>The protobuf version compiles down to compact binary bytes - significantly smaller than the JSON equivalent - but it's not human-readable on the wire, and both sender and receiver need access to the same <code>.proto</code> schema to interpret it correctly.</p>
<p>There's no universally "best" format here. JSON wins on simplicity and debuggability. Protobuf wins on size and speed. The right choice depends entirely on what your system actually needs.</p>
<hr />
<h2>Why This Is Genuinely Essential</h2>
<p>Strip serialization and deserialization out of software development, and here's what disappears with it:</p>
<ul>
<li><p><strong>Distributed systems</strong> - no microservices, no APIs, no cloud computing as we currently build it</p>
</li>
<li><p><strong>Persistence</strong> - nothing could be meaningfully saved to disk and reloaded across restarts</p>
</li>
<li><p><strong>Interoperability</strong> - a Python service and a Go service would have no shared way to exchange structured data</p>
</li>
<li><p><strong>Caching and messaging</strong> - data couldn't be temporarily stored and retrieved by a different process</p>
</li>
</ul>
<p>Serialization and deserialization are the universal translator that lets data move between processes, machines, languages, and time - because raw in-memory data is inherently local, temporary, and language-specific. It's one of those pieces of infrastructure that's invisible when it works, and impossible to ignore the moment it doesn't.</p>
<hr />
<h2>Closing Thought</h2>
<p>The next time you debug a "why is this field null" bug in a JSON payload, or wonder why your Redis cache read returned garbage, or trace a schema mismatch between two services - remember you're not fighting an obscure edge case. You're standing at the exact seam where two independent systems are trying to agree on a shared language. Understanding that seam well is what separates engineers who patch symptoms from engineers who fix root causes.</p>
]]></content:encoded></item><item><title><![CDATA[DNS Explained: How Your Browser Finds a Website (And How It Handles Billions of Requests a Day)]]></title><description><![CDATA[Every time you type a website address into your browser, something invisible happens before anything else can load: your browser has to figure out the actual location of that website on the internet. ]]></description><link>https://mohdashraf.hashnode.dev/dns-explained-how-your-browser-finds-a-website-and-how-it-handles-billions-of-requests-a-day</link><guid isPermaLink="true">https://mohdashraf.hashnode.dev/dns-explained-how-your-browser-finds-a-website-and-how-it-handles-billions-of-requests-a-day</guid><dc:creator><![CDATA[mohd ashraf]]></dc:creator><pubDate>Tue, 07 Jul 2026 11:05:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/687227034b82e8222fc752d9/8a0b8599-318a-48af-958d-c4b17b319e01.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every time you type a website address into your browser, something invisible happens before anything else can load: your browser has to figure out the <em>actual</em> location of that website on the internet. This article covers both halves of that story - what DNS is and how it works, and the engineering that lets it handle an enormous global scale without breaking a sweat.</p>
<h2>The Problem DNS Solves</h2>
<p>Every website on the internet is really just a number - an <strong>IP address</strong> - something like:</p>
<pre><code class="language-plaintext">142.250.xxx.xxx
</code></pre>
<p>But nobody wants to memorize strings of numbers for every site they visit. That's exactly the problem the <strong>Domain Name System (DNS)</strong> was built to solve.</p>
<h2>DNS Is Like Your Phone's Contact List</h2>
<p>Here's a simple way to think about it:</p>
<ul>
<li><p>📱 <strong>Contact Name</strong> → John</p>
</li>
<li><p>📞 <strong>Phone Number</strong> → +91 XXXXX XXXXX</p>
</li>
</ul>
<p>You don't memorize everyone's phone number - you search for the name, and your phone instantly finds the number behind it.</p>
<p><strong>DNS does exactly this for the internet.</strong> It's the translator sitting between human-friendly names (<code>google.com</code>) and machine-friendly numbers (<code>142.250.xxx.xxx</code>).</p>
<h2>What Actually Happens When You Type a URL</h2>
<p>When you type <code>google.com</code> into your browser, here's the real sequence of events:</p>
<ol>
<li><p><strong>Browser cache check</strong> - Your browser first checks whether it already knows the answer from a recent visit.</p>
</li>
<li><p><strong>DNS Resolver</strong> - If not cached, it asks a <strong>DNS Resolver</strong> - usually run by your ISP, or a public one like Google DNS (<code>8.8.8.8</code>) or Cloudflare (<code>1.1.1.1</code>).</p>
</li>
<li><p><strong>Root DNS Server</strong> - The resolver asks a <strong>Root Server</strong>: "who's responsible for <code>.com</code> domains?"</p>
</li>
<li><p><strong>TLD Server</strong> - The root server points to a <strong>TLD (Top-Level Domain) Server</strong>, which knows: "who's responsible for <code>google.com</code> specifically?"</p>
</li>
<li><p><strong>Authoritative Server</strong> - The TLD server points to the <strong>Authoritative Server</strong>, which holds the actual, final answer - the real IP address.</p>
</li>
<li><p><strong>Connection</strong> - Your browser now has the IP address and connects directly to Google's server.</p>
</li>
</ol>
<pre><code class="language-plaintext">Browser
   │
  ▼
Local DNS Resolver
   │
   ▼
Root DNS Server
   │
   ▼
.com TLD Server
   │
   ▼
Authoritative DNS Server
   │
   ▼
Returns the IP Address
</code></pre>
<p>All of this typically happens in <strong>under 100 milliseconds</strong> - fast enough that you never notice it occurring.</p>
<h2>The Real Question: How Does This Scale to Billions of Requests?</h2>
<p>Knowing the lookup flow is one thing. But DNS handles an estimated <strong>100+ billion queries a day</strong>, globally, without becoming a bottleneck. That doesn't happen by accident - it's the result of some genuinely elegant systems engineering.</p>
<h3>1. Hierarchy - Divide the Problem</h3>
<p>No single server stores the entire internet's domain records. Instead, responsibility is split across layers:</p>
<ul>
<li><p><strong>Root servers</strong> only know which TLD servers (<code>.com</code>, <code>.org</code>, <code>.in</code>, etc.) to point queries toward.</p>
</li>
<li><p><strong>TLD servers</strong> only know which authoritative server owns a specific domain.</p>
</li>
<li><p><strong>Authoritative servers</strong> hold the actual, final DNS records for that domain.</p>
</li>
</ul>
<p>Each layer does one small, well-defined job. This is precisely what makes the system <strong>horizontally scalable</strong> - no single point has to know everything.</p>
<h3>2. Caching + TTL - Avoid Repeating Work</h3>
<p>Every DNS record comes with a <strong>TTL (Time To Live)</strong> - a set number of seconds it's allowed to be cached before a fresh lookup is required.</p>
<p>Your browser, operating system, home router, and ISP all cache DNS results independently. Because of this layered caching, the vast majority of DNS lookups are answered from a nearby cache and <strong>never even reach the root or authoritative servers</strong>. This is also why the <em>second</em> time you visit a website, it tends to load noticeably faster - DNS resolution is essentially skipped.</p>
<h3>3. Anycast Routing - One Address, Hundreds of Locations</h3>
<p>There are only <strong>13 logical root server addresses</strong> in the DNS system - but they're deployed across hundreds of physical server locations worldwide using a technique called <strong>Anycast</strong>.</p>
<p>With Anycast, the same IP address can route your request to the <em>physically nearest</em> server location, rather than a single fixed data center. This dramatically cuts latency and - just as importantly - removes any single point of failure. If one physical location goes down, traffic is automatically routed to the next nearest one, and users never notice.</p>
<h3>4. Recursive vs. Iterative Queries - Offloading the Heavy Lifting</h3>
<p>Your device doesn't walk the entire DNS hierarchy itself. Instead:</p>
<ul>
<li><p>Your device makes a <strong>recursive query</strong> - it asks one resolver a question and simply waits for a complete answer.</p>
</li>
<li><p>The <strong>resolver</strong> then performs the <strong>iterative</strong> work - walking through root → TLD → authoritative servers on your behalf - and only hands your device the final result.</p>
</li>
</ul>
<p>This division of labor means the complex, multi-step hierarchy walk is handled by infrastructure specifically built and optimized for it, rather than every single device on the internet doing that work independently.</p>
<h2>Why This Architecture Works</h2>
<p>Put together, DNS scales not because of sheer server count, but because of <strong>deliberate architectural choices</strong>:</p>
<ul>
<li><p><strong>Divide responsibility</strong> across a hierarchy so no server needs to know everything</p>
</li>
<li><p><strong>Cache aggressively</strong> at every layer so repeat lookups rarely need a full round-trip</p>
</li>
<li><p><strong>Distribute physically</strong> using Anycast so requests are always answered by the nearest available server</p>
</li>
<li><p><strong>Offload complexity</strong> to specialized resolvers instead of burdening every client device</p>
</li>
</ul>
<p>This is the same set of principles - hierarchy, caching, distribution, and delegation - that shows up again and again in large-scale system design, whether you're building a DNS system or a distributed database.</p>
<h2>Why DNS Matters (The Short Version)</h2>
<ul>
<li><p>✅ Humans remember easy names like <code>google.com</code></p>
</li>
<li><p>✅ Computers only understand IP addresses</p>
</li>
<li><p>✅ DNS is the invisible translator connecting the two, at massive scale, in milliseconds</p>
</li>
</ul>
<p>Without DNS, we'd have to memorize the IP address of every single website we ever wanted to visit - and worse, none of it would scale to the size of today's internet without the hierarchy, caching, and distribution techniques described above.</p>
<h2>Final Thoughts</h2>
<p>DNS is one of the most invisible - yet most critical - pieces of internet infrastructure. You never see it working, but literally nothing loads without it. It's also why "the website is down" sometimes actually just means "DNS hasn't propagated yet" - a classic gotcha when deploying a new domain or migrating servers.</p>
<p>Understanding not just <em>what</em> DNS does, but <em>how</em> it's engineered to handle global scale, is genuinely useful groundwork for anyone getting into system design, backend infrastructure, or DevOps - the same hierarchy-cache-distribute pattern shows up constantly once you start looking for it.</p>
<hr />
<p><em>If you found this useful, follow along for more deep dives into the infrastructure that quietly powers the modern web.</em></p>
]]></content:encoded></item><item><title><![CDATA[HTTPS & SSL/TLS Certificates: How Your Browser Knows a Website Is Secure]]></title><description><![CDATA[When you visit a website like:
https://example.com

Have you ever stopped to think about how your browser actually knows it's talking to the real example.com, and not an attacker impersonating it?
The]]></description><link>https://mohdashraf.hashnode.dev/https-ssl-tls-certificates-how-your-browser-knows-a-website-is-secure</link><guid isPermaLink="true">https://mohdashraf.hashnode.dev/https-ssl-tls-certificates-how-your-browser-knows-a-website-is-secure</guid><dc:creator><![CDATA[mohd ashraf]]></dc:creator><pubDate>Sun, 05 Jul 2026 10:54:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/687227034b82e8222fc752d9/3f5da0d7-ebef-4c92-b01f-2714469c13a2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you visit a website like:</p>
<pre><code class="language-plaintext">https://example.com
</code></pre>
<p>Have you ever stopped to think about <em>how</em> your browser actually knows it's talking to the real <code>example.com</code>, and not an attacker impersonating it?</p>
<p>The answer lies in two closely related things: <strong>HTTPS</strong> and <strong>SSL/TLS Certificates</strong>. Together, they form the backbone of trust and privacy on the modern web - and understanding how they work is essential for anyone building or securing web applications.</p>
<h2>The Office Building Analogy</h2>
<p>Here's a simple mental model that makes this concept click immediately:</p>
<ul>
<li><p>🏢 <strong>Website</strong> = An office building</p>
</li>
<li><p>🪪 <strong>SSL/TLS Certificate</strong> = An employee ID card</p>
</li>
<li><p>👮 <strong>Browser</strong> = The security guard at the entrance</p>
</li>
</ul>
<p>Before letting anyone into the building, the security guard checks their ID card. If it's valid and issued by a legitimate authority, they're let in. If the ID is fake, expired, or doesn't match the person holding it, they're stopped at the door.</p>
<p>Your browser does the same thing every time you visit an HTTPS website - except that instead of checking a physical ID, it checks a <strong>digital certificate</strong>.</p>
<h2>What Actually Happens When You Visit an HTTPS Site</h2>
<p>Here's the step-by-step process that happens behind the scenes, almost instantly, every time you load a secure website:</p>
<ol>
<li><p><strong>The website sends its SSL/TLS Certificate</strong> to your browser as soon as the connection begins.</p>
</li>
<li><p><strong>Your browser verifies the certificate</strong> - checking that it was issued by a trusted <strong>Certificate Authority (CA)</strong>, that it hasn't expired, and that it hasn't been tampered with or issued for a different domain.</p>
</li>
<li><p><strong>If everything checks out, a TLS Handshake occurs</strong> - a rapid exchange between your browser and the server that establishes a shared, secure encryption key for that session.</p>
</li>
<li><p><strong>Your connection is now encrypted.</strong> From this point forward, everything you send - passwords, payment details, personal information - travels across the internet in a form that's unreadable to anyone intercepting it.</p>
</li>
</ol>
<p>This entire process happens in the background, typically adding just a few milliseconds to your connection time, and it's the reason you see a padlock icon in your browser's address bar.</p>
<h2>Why "HTTP" and "HTTPS" Use Different Ports</h2>
<p>This ties directly back to a foundational networking concept: ports.</p>
<ul>
<li><p>🌐 <strong>HTTP</strong> → Port 80 → No encryption ❌</p>
</li>
<li><p>🔒 <strong>HTTPS</strong> → Port 443 → Certificate-based encryption ✅</p>
</li>
</ul>
<p>When you type <code>https://</code>Your browser automatically connects to port 443 instead of port 80 and immediately expects the server to perform the certificate exchange and TLS handshake before any actual data is transferred.</p>
<h2>What Happens When a Certificate Is Invalid</h2>
<p>If a certificate is expired, self-signed without proper trust, or issued for a domain that doesn't match the site you're visiting, your browser won't silently let it slide - it will stop you with a warning like:</p>
<blockquote>
<p>⚠️ <strong>"Your connection is not private"</strong></p>
</blockquote>
<p>This warning exists specifically to protect users from <strong>man-in-the-middle attacks</strong>, where someone tries to intercept your connection and impersonate a legitimate website. Modern browsers treat this as a hard stop rather than a soft suggestion, because bypassing it can expose you to serious security risks.</p>
<h2>The Key Misconception About HTTPS</h2>
<p>A lot of people assume HTTPS is secure simply because it has an "S" at the end. That's not quite right.</p>
<p><strong>HTTPS is secure because of what's happening underneath it - TLS (Transport Layer Security) and SSL/TLS Certificates</strong>, which handle two distinct jobs simultaneously:</p>
<ol>
<li><p><strong>Identity verification</strong> - proving the website is who it claims to be, via the Certificate Authority chain of trust.</p>
</li>
<li><p><strong>Data encryption</strong> - scrambling the data in transit so that even if it's intercepted, it can't be read without the correct encryption keys.</p>
</li>
</ol>
<p>Both pieces matter. Identity verification without encryption would mean your data is still exposed. Encryption without identity verification would mean you could be encrypting data straight to an attacker's server. HTTPS solves both problems together.</p>
<h2>What If Someone Intercepts Your HTTPS Traffic?</h2>
<p>This is a common - and important - question: if an attacker manages to intercept your HTTPS traffic mid-transit, can they actually read your data?</p>
<p><strong>In properly implemented HTTPS, no.</strong> The data is encrypted using keys established during the TLS handshake, which are unique to that session and never transmitted in a way that an eavesdropper could extract. Even if an attacker captures every packet of your encrypted traffic, without the corresponding decryption keys, the data appears as unreadable ciphertext.</p>
<p>This is precisely why HTTPS is considered safe for transmitting sensitive information like login credentials and payment details, even over unsecured networks like public Wi-Fi - the encryption travels <em>with</em> the connection, protecting the data regardless of who might be listening on the network.</p>
<p>That said, HTTPS isn't a silver bullet against every kind of attack. It protects data <em>in transit</em>, but doesn't protect against compromised endpoints, malware on your device, phishing sites with legitimately issued certificates for lookalike domains, or vulnerabilities in how a website itself is coded. Security is layered, and HTTPS is one critical layer among several.</p>
<h2>Why This Matters for Developers</h2>
<p>Understanding SSL/TLS isn't just useful for passing a networking quiz - it directly affects real engineering decisions:</p>
<ul>
<li><p><strong>API security</strong> - Any API handling sensitive data should enforce HTTPS-only communication.</p>
</li>
<li><p><strong>Certificate management</strong> - Tools like Let's Encrypt have made obtaining and renewing certificates free and automatic, but understanding <em>why</em> they matter helps you configure things correctly.</p>
</li>
<li><p><strong>Mixed content issues</strong> - Loading HTTP resources on an HTTPS page triggers browser warnings and can break functionality; understanding certificates helps you debug this quickly.</p>
</li>
<li><p><strong>Reverse proxies &amp; load balancers</strong> - Tools like Nginx often handle "SSL termination," decrypting HTTPS traffic before passing it internally - a concept that only makes sense once you understand the handshake process.</p>
</li>
<li><p><strong>Security audits &amp; compliance</strong> - Many industry standards (PCI-DSS, HIPAA, GDPR-adjacent practices) require HTTPS as a baseline requirement, not an optional nicety.</p>
</li>
</ul>
<h2>Final Thoughts</h2>
<p>The padlock icon in your browser's address bar represents a surprisingly elegant system: a chain of trust (Certificate Authorities), a verification process (certificate validation), and a cryptographic handshake (TLS) - all working together in milliseconds to protect nearly every meaningful interaction you have on the web.</p>
<p>Next time you see that padlock, you'll know exactly what's happening behind it: your browser just checked an ID card, shook hands securely, and set up an encrypted tunnel - all before you even noticed the page had loaded.</p>
<hr />
<p><em>If you found this useful, follow along for more deep dives into the fundamentals that power secure, modern web applications.</em></p>
]]></content:encoded></item><item><title><![CDATA[HTTP & The Hidden Role of Port 80: What Really Happens When You Visit a Website]]></title><description><![CDATA[Every single time you open a website, two things happen almost instantly and invisibly: your browser finds the right server, and it speaks the right "language" to that server so it understands what yo]]></description><link>https://mohdashraf.hashnode.dev/http-the-hidden-role-of-port-80-what-really-happens-when-you-visit-a-website</link><guid isPermaLink="true">https://mohdashraf.hashnode.dev/http-the-hidden-role-of-port-80-what-really-happens-when-you-visit-a-website</guid><dc:creator><![CDATA[mohd ashraf]]></dc:creator><pubDate>Sat, 04 Jul 2026 19:45:33 GMT</pubDate><content:encoded><![CDATA[<p>Every single time you open a website, two things happen almost instantly and invisibly: your browser finds the right server, and it speaks the right "language" to that server so it understands what you're asking for.</p>
<p>That language is <strong>HTTP</strong> - HyperText Transfer Protocol. And the part that rarely gets talked about is <em>how</em> your browser actually finds the right "door" to knock on once it reaches the server. That's where <strong>ports</strong> come in, and specifically, <strong>Port 80</strong>.</p>
<p>This article breaks down what's actually happening behind that split-second page load - from typing a URL to seeing pixels on your screen.</p>
<h2>The URL You Type Isn't the Full Story</h2>
<p>When you type this into your browser:</p>
<pre><code class="language-plaintext">http://example.com
</code></pre>
<p>You <em>think</em> you're just telling your browser "go to example.com." But under the hood, your browser is actually connecting to:</p>
<pre><code class="language-plaintext">example.com:80
</code></pre>
<p>You never see the <code>:80</code> Because your browser adds it automatically. Port 80 is the universally agreed-upon default port for HTTP traffic, so there's no need to type it explicitly - it's implied.</p>
<p>If you visited a site running on a non-standard port, though, you <em>would</em> need to type it - something like <code>http://example.com:8080</code>. This is common in local development environments (React apps on <code>:3000</code>, Node servers on<code>:5000</code>, etc.).</p>
<h2>IP Addresses vs. Ports: A Simple Analogy</h2>
<p>This is the part that trips people up early in their engineering careers, so here's a mental model that makes it click instantly:</p>
<ul>
<li><p>🏢 <strong>IP Address</strong> → The address of a building</p>
</li>
<li><p>🚪 <strong>Port</strong> → The specific apartment number inside that building</p>
</li>
</ul>
<p>The <strong>IP address</strong> gets your request to the correct physical (or virtual) server. But a single server can run <em>many</em> different applications at once - a web server, a database, an SSH service, a caching layer, and more. The <strong>port number</strong> is what tells the operating system exactly <em>which</em> of those applications should handle the incoming request.</p>
<p>Without ports, a server would have no way to distinguish "this request is for my website" from "this request is trying to access my database."</p>
<h2>Step-by-Step: What Happens When You Load a Website</h2>
<p>Here's the full journey from keystroke to rendered page:</p>
<ol>
<li><p><strong>You type a URL</strong> - e.g., <code>http://example.com</code> - into your browser's address bar.</p>
</li>
<li><p><strong>DNS resolution happens</strong> - your browser (or OS) resolves <code>example.com</code> to an IP address.</p>
</li>
<li><p><strong>The browser sends an HTTP request</strong> to that IP address, targeting <strong>Port 80</strong> (added automatically since none was specified).</p>
</li>
<li><p><strong>The web server receives the request</strong> on Port 80, where it's actively listening, and processes it - this might mean fetching a file, querying a database, or running server-side logic.</p>
</li>
<li><p><strong>The server sends back an HTTP response</strong> - this could be HTML, CSS, JavaScript, JSON, images, or other assets.</p>
</li>
<li><p><strong>Your browser parses and renders</strong> everything it receives into the visual page you interact with.</p>
</li>
</ol>
<p>All of this - DNS lookup, connection, request, response, rendering - typically happens in <strong>a few hundred milliseconds</strong>, which is part of why the web <em>feels</em> instantaneous even though a lot is happening.</p>
<h2>Why Not Just Use Port 80 for Everything?</h2>
<p>Because different services need to run independently and simultaneously on the same machine, without stepping on each other. Ports act as internal traffic directors. This is exactly why your local machine can run a website <em>and</em> a database <em>and</em> an SSH connection at the same time without any conflicts - each service is bound to its own port, listening only for traffic addressed to it.</p>
<h2>Ports Every Developer Should Know</h2>
<p>You'll run into these constantly, whether you're configuring servers, setting up Docker containers, writing <code>.env</code> files, or debugging network issues:</p>
<table>
<thead>
<tr>
<th>Port</th>
<th>Service</th>
</tr>
</thead>
<tbody><tr>
<td>80</td>
<td>HTTP</td>
</tr>
<tr>
<td>443</td>
<td>HTTPS</td>
</tr>
<tr>
<td>22</td>
<td>SSH</td>
</tr>
<tr>
<td>3306</td>
<td>MySQL</td>
</tr>
<tr>
<td>5432</td>
<td>PostgreSQL</td>
</tr>
<tr>
<td>6379</td>
<td>Redis</td>
</tr>
<tr>
<td>27017</td>
<td>MongoDB</td>
</tr>
<tr>
<td>21</td>
<td>FTP</td>
</tr>
</tbody></table>
<p>A quick note on <strong>Port 443</strong>: this is HTTPS's default port — the encrypted, secure version of HTTP. Just like Port 80 is hidden for <code>http://</code>Port 443 is hidden for <code>https://</code>. Modern browsers push almost all traffic through 443 now, since HTTPS has become the standard rather than the exception.</p>
<h2>Why This Matters Beyond Trivia</h2>
<p>Understanding HTTP and ports isn't just a fun fact - it's foundational to almost everything you'll touch as a backend or full-stack developer:</p>
<ul>
<li><p><strong>REST APIs</strong> : every API endpoint you call is, at its core, an HTTP request to a specific host and port.</p>
</li>
<li><p><strong>Authentication</strong>: tokens, cookies, and sessions are all passed over HTTP(S) headers.</p>
</li>
<li><p><strong>Docker</strong>: you'll constantly map container ports to host ports (<code>-p 8080:80</code>), and this only makes sense once you understand what a port actually does.</p>
</li>
<li><p><strong>Nginx &amp; reverse proxies</strong>: these tools work by listening on one port (often 80 or 443) and forwarding traffic internally to other ports where your actual application is running.</p>
</li>
<li><p><strong>Load balancers</strong> distribute incoming traffic across multiple servers, all of which are listening on specific ports.</p>
</li>
<li><p><strong>Caching layers</strong>: services like Redis rely on dedicated ports (6379) to stay isolated from your main application traffic.</p>
</li>
<li><p><strong>System design</strong>: almost every system design interview or architecture diagram assumes you understand how traffic flows through IPs and ports.</p>
</li>
</ul>
<p>Once this concept is solid, a lot of "advanced" backend and DevOps topics stop feeling like black boxes and start feeling like logical extensions of something you already understand.</p>
<h2>Final Thoughts</h2>
<p>The next time you type a URL and the page loads instantly, remember: your browser just found a specific building (IP address), knocked on a specific apartment door (port), spoke a shared language (HTTP), and got a response back - all before you even finished blinking.</p>
<p>It's a small piece of the puzzle, but it's one of those foundational concepts that quietly underlies almost everything else in web development and system design.</p>
<hr />
<p><em>If you found this useful, follow along for more deep dives into the fundamentals that power the systems we use every day.</em></p>
]]></content:encoded></item></channel></rss>