You have a domain. You have a server (or a host) with an IP address. DNS is the small set of records that makes "type the name, reach the IP" actually work. Three record types do nearly everything; understanding them once is the difference between "it just doesn't work" and "I know what's broken."
The reason DNS feels like a black box is that nothing about it is visible while it's working. You type a URL, the page loads. You type a URL the day after a config change, sometimes the page loads, sometimes it doesn't, and the difference depends on which server in which city happened to answer your computer's lookup. None of that is intuitive. The mental model that's missing β and the only one that matters β is what DNS actually does.
DNS is a globally-distributed lookup table. Names go in, answers come out. Your domain β say, mybrand.com β has an entry that says "when someone asks for me, route them to IP X." Subdomains (www.mybrand.com, api.mybrand.com) can have their own entries with different answers. The records that hold these answers come in a handful of types. You write them at your registrar (or wherever you delegated DNS to). Then you wait for the world's DNS caches to catch up β that's "propagation," and it's the part that makes the system feel slow.
This tutorial covers the three record types that handle 95% of real domains, how to set them up correctly the first time, and the three checks that tell you whether DNS is actually working before you spend an hour debugging an app that's fine.
mybrand.com) vs. a subdomainBefore opening the DNS dashboard, know what your destination looks like:
198.51.100.42 β common for VPSs (DigitalOcean droplet, Hetzner server, etc.). Use an A record.2001:db8::1 β increasingly common; some hosts are IPv6-only. Use an AAAA record.my-app.vercel.app β what platforms-as-a-service give you. Use a CNAME record.The rule: numeric address gets an A (or AAAA); a name gets a CNAME. Mixing them up is the #1 setup error.
mybrand.com with no subdomainAt your DNS provider (your registrar's panel, or wherever you've delegated DNS):
@ (or leave blank, meaning the root). Value: your server's IP. TTL: 3600 (one hour) is fine.@ and it works.This is the record that makes typing mybrand.com reach your site.
mybrand.com and www.mybrand.com to workAdd a record for www:
www, value mybrand.com. This makes www follow the root.www, same target as the root.Pick a canonical form ("we want everyone on mybrand.com") and have your host redirect the other to it. Magic Deploy and most modern hosts do this automatically.
TTL is how long, in seconds, DNS servers around the world are allowed to cache your record before re-checking. The default (often 3600 = 1 hour) is fine for steady-state. Two practical rules:
For low-stakes domains, leave it at default and don't think about it.
When you publish a new DNS record, the authoritative server (your registrar / DNS provider) has it instantly. But every DNS resolver in the world β your ISP's resolver, public resolvers like 8.8.8.8 and 1.1.1.1, your laptop's local cache β is holding some cached answer with a TTL. Until that TTL expires, those resolvers happily serve the cached (often old) answer instead of asking again.
"Propagation" is the wait for all those caches to expire. In practice:
Before suspecting the app, verify DNS itself:
# 1. What does your local resolver see right now?
dig mybrand.com +short
# Expected: your IP. If empty or wrong, the record isn't published or hasn't propagated.
# 2. What does a different resolver see?
dig @1.1.1.1 mybrand.com +short
# Asks Cloudflare's public resolver (1.1.1.1) instead of your local one.
# Different resolver = different cache state. If this agrees with #1,
# both resolvers updated. If it differs, your local cache is just stale β
# that's a wait, not a bug. For the truest view (no caches anywhere):
# dig +trace mybrand.com
# walks from the root nameservers down, asking each fresh. Slowest, most honest.
# 3. Are you actually reaching the server?
curl -I https://mybrand.com
# Expected: an HTTP response. If you get connection refused or timeout,
# the IP is wrong, the server isn't listening, or the firewall is blocking.
The pattern: if #1 differs from #2, propagation is still happening β wait. If #2 is wrong, the record at your DNS provider is wrong β fix the record. If both are right but #3 fails, DNS is fine; the problem is at the server.
Once DNS works, http://mybrand.com reaches your server. https://mybrand.com doesn't, until you set up a TLS certificate. This is a separate step, usually handled by:
sudo certbot --nginx -d mybrand.com -d www.mybrand.com --redirect. The --redirect flag rewrites HTTP to HTTPS in the nginx config; certbot also installs a cron job for automatic renewal every 90 days.Never run a public site without HTTPS. Modern browsers warn loudly; everyone expects it; the cost is zero. The TLS cert is the second layer after DNS, and the two together make the site reachable safely.
None of these are required just to serve a website, but you'll meet them eventually:
[email protected] to actually receive mail, you point MX records at your email host (Fastmail, Google Workspace, Proton, etc.). The host gives you the exact values β name, priority, target β and you paste them in. MX is independent of A/CNAME, so receiving email at a domain doesn't affect where the website lives.The rule of thumb: A/AAAA/CNAME route traffic; MX routes email; TXT proves things. Knowing which type a problem belongs to is half the debugging.
example.com.), some without. They mean the same thing in DNS-land. When you copy/paste a CNAME target between providers, the dot may or may not need to be there; check the provider's docs if a CNAME record looks right but doesn't resolve.