Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
37 posts found
Where Does a Slow Request Come From: Diagnosing the Network with curl -w, DevTools Timing and Wireshark
Computer Science Fundamentals PART 10

Where Does a Slow Request Come From: Diagnosing the Network with curl -w, DevTools Timing and Wireshark

A slow request's time splits into DNS, TCP, TLS, server (TTFB) and download phases, and every phase has a recognizable signature. Five cases with curl -w under a 50 ms RTT via netem (no keep-alive, an IPv6 attempt, TLS 1.2, a slow server, a large response), .NET's System.Net metrics, dotnet-counters and a TLS key log file for Wireshark.

8 Nov 2026 10 min 5
HTTP/3 and QUIC: Secure Transport over UDP, Alt-Svc and HTTP/3 in .NET
Computer Science Fundamentals PART 09

HTTP/3 and QUIC: Secure Transport over UDP, Alt-Svc and HTTP/3 in .NET

HTTP/3 uses QUIC, which runs over UDP instead of TCP: TLS 1.3 built in, ordering per stream, one RTT less on a new connection. Discovery via Alt-Svc and the DNS HTTPS record, QuicConnection.IsSupported=false on macOS, Kestrel HTTP/3 working with libmsquic in a Linux container, why HTTP/3 isn't faster on loopback, and the full RTT it saves at 50 ms RTT, with real measurements.

8 Nov 2026 10 min 7
HTTP/2: Binary Framing, Multiplexing, HPACK and HTTP/2 in Kestrel
Computer Science Fundamentals PART 08

HTTP/2: Binary Framing, Multiplexing, HPACK and HTTP/2 in Kestrel

HTTP/2 doesn't change semantics; it splits messages into binary frames belonging to streams, interleaves them on one TCP connection and compresses headers with HPACK. Pseudo-headers and h2c with curl, one connection instead of 20 for 20 concurrent requests, Kestrel's 100-stream limit, HttpClient's default 1.1, and 103 Early Hints instead of Server Push.

8 Nov 2026 9 min 5
HTTP Caching and Conditional Requests: Cache-Control, ETag and 304
Computer Science Fundamentals PART 07

HTTP Caching and Conditional Requests: Cache-Control, ETag and 304

An HTTP cache uses Cache-Control to decide how long a copy stays fresh, and ETag or Last-Modified to cheaply revalidate it with a 304 Not Modified when it expires. no-cache vs no-store, heuristic freshness for static files without Cache-Control, the old index.html after a deploy, and an ETag handler written because HttpClient has no cache of its own.

8 Nov 2026 9 min 7
Reading HTTP/1.1 Off the Wire: Message Format, Method Semantics and Keep-Alive
Computer Science Fundamentals PART 06

Reading HTTP/1.1 Off the Wire: Message Format, Method Semantics and Keep-Alive

HTTP/1.1 is a text protocol: a start line, headers, an empty line and a body framed by Content-Length or chunked. Requests written by hand with nc and openssl s_client, a 400 for a request without Host, what the 3d in chunked means, safe/idempotent methods and a handler that only retries idempotent requests, keep-alive, and Kestrel against request smuggling.

8 Nov 2026 10 min 7
The TLS 1.3 Handshake: Certificate Chain, SNI, ALPN and Post-Quantum Key Exchange
Computer Science Fundamentals PART 05

The TLS 1.3 Handshake: Certificate Chain, SNI, ALPN and Post-Quantum Key Exchange

TLS 1.3 sets up the encrypted channel in one RTT by putting the key_share in the ClientHello; ECDHE gives forward secrecy and X25519MLKEM768 adds post-quantum protection. The handshake with openssl s_client, a ClientHello growing from 285 to 1,525 bytes, certificate chain errors, SNI/ECH/ALPN, 0-RTT and .NET staying on TLS 1.2 on macOS.

8 Nov 2026 11 min 5
How DNS Works: Resolvers, Record Types, TTL and Querying with dig
Computer Science Fundamentals PART 04

How DNS Works: Resolvers, Record Types, TTL and Querying with dig

DNS resolves a name through a chain of stub resolver, recursive resolver, root, TLD and authoritative servers and caches every answer for its TTL. dig +trace, A/AAAA/CNAME/MX/TXT/CAA/HTTPS records, negative caching, DoH, and a blue-green experiment showing why HttpClient's open connections don't see DNS changes.

8 Nov 2026 10 min 7
How TCP Works: 3-Way Handshake, Congestion Control and HttpClient Socket Exhaustion
Computer Science Fundamentals PART 03

How TCP Works: 3-Way Handshake, Congestion Control and HttpClient Socket Exhaustion

TCP opens a connection with a 3-way handshake for a reliable byte stream, starts slowly with slow start and waits in TIME_WAIT on close; that's why new HttpClient per request exhausts ports. 500 TIME_WAITs for 500 requests, 6x slower with TLS, IHttpClientFactory, PooledConnectionLifetime and handler defaults, with real output.

8 Nov 2026 10 min 7
IP Addresses, Subnets, Ports and NAT: localhost, 0.0.0.0 and Connectivity in Containers
Computer Science Fundamentals PART 02

IP Addresses, Subnets, Ports and NAT: localhost, 0.0.0.0 and Connectivity in Containers

An IP address finds an interface, a port finds a socket on that machine; a server bound to 127.0.0.1 can only be reached from inside that machine. RFC 1918 private addresses, subnets with CIDR, NAT, ephemeral ports, address already in use, and why a Kestrel bound to localhost in a container returns an Empty reply, with real output.

8 Nov 2026 11 min 4
What Happens When You Press Enter on a URL: End to End from DNS to Render
Computer Science Fundamentals PART 01

What Happens When You Press Enter on a URL: End to End from DNS to Render

When you press Enter, the browser parses the URL, finds the IP with DNS, connects with TCP and TLS 1.3, sends the HTTP request and renders the response; a new connection spends at least three to four RTTs before the first byte. We read every phase line by line against our own Kestrel server with curl -v and curl -w.

8 Nov 2026 11 min 6
What Big-O Doesn't Tell You: Constants, Cache and Measuring with BenchmarkDotNet
Computer Science Fundamentals PART 05

What Big-O Doesn't Tell You: Constants, Cache and Measuring with BenchmarkDotNet

Big-O tells you about growth, but real time is decided by constants, the cache, allocations and the input distribution. An O(n²) insertion sort twice as fast as LINQ on 10 books, LinkedList 3.8x slower, Dictionary falling to O(n²) with a bad GetHashCode, and estimating complexity by measuring with the doubling experiment.

8 Nov 2026 12 min 4
Amortized Analysis: Why List<T>.Add Counts as O(1)
Computer Science Fundamentals PART 04

Amortized Analysis: Why List<T>.Add Counts as O(1)

List<T>.Add sometimes copies the whole list, but because capacity doubles, the total cost of n Adds never exceeds 3n; that's why it counts as amortized O(1). The aggregate, accounting and potential methods, 50 billion copies with +10 growth, Dictionary's prime sizes and a 38 ms resize spike, with real measurements.

8 Nov 2026 11 min 3
Blog Map