Ingress vs Egress Traffic
“Ingress” and “egress” just mean traffic direction — in and out — but the term shows up in three different contexts (firewalls, cloud billing, Kubernetes) and the interview gotcha is that the perspective changes what counts as which. This file ties the three together; firewall-rule detail lives in 07_firewalls_security_groups.md.
The one rule: direction is relative to a boundary
Ingress and egress are always defined relative to a specific boundary — a host, a subnet, a VPC, a cluster. The same packet is egress leaving server A and ingress arriving at server B.
| Term | Meaning | “From the boundary’s point of view” |
|---|---|---|
| Ingress | inbound traffic | something is connecting to me |
| Egress | outbound traffic | I am connecting out to something |
Always ask “ingress/egress of what?” A request from a user to your API is ingress at your load balancer. That same API then calling Stripe is egress from your VPC. Both happen inside one user request.
Context 1 — Firewalls and security groups
Ingress/egress rules control who can connect in vs what this host can connect out to. Key points (full detail in 07_firewalls_security_groups.md):
- Stateful firewalls (AWS security groups) auto-allow return traffic — you write the ingress rule, the response egress is allowed automatically.
- Stateless firewalls (AWS NACLs) evaluate each packet alone — you must write both ingress and egress rules, including ephemeral-port ranges for return traffic.
- Most teams lock down ingress (port 443 to the world) and leave egress wide open (
0.0.0.0/0). That’s the common mistake — egress filtering limits the blast radius of a compromised server (data exfiltration, SSRF, malware C2) and is required by PCI/HIPAA.
Context 2 — Cloud data transfer costs (the senior topic)
This is the one interviewers actually probe, because it drives real architecture decisions. In every major cloud the pricing is asymmetric:
| Direction | Typical cost |
|---|---|
| Ingress (data into the cloud) | free |
| Egress (data out to the internet) | charged per GB — ~$0.05–0.09/GB on AWS, tiered |
| Cross-AZ (same region) | charged both directions, ~$0.01/GB each way |
| Cross-region | charged, more than cross-AZ |
| Within one AZ, private IPs | free |
Why it matters:
- Egress is the silent bill. A service that streams large responses, serves media, or ships logs/backups to another provider racks up egress charges. Ingress being free is why “just upload it to S3” is cheap and “serve it back out” is not.
- Cross-AZ traffic is egress too. A chatty app in AZ-a talking to a database in AZ-b pays cross-AZ transfer both ways. This is why you keep an app instance and its cache/replica in the same AZ where latency and cost both allow.
- The fixes are architectural:
- CDN (CloudFront) in front of static/media — cache at the edge so origin egress happens once, not per request. CDN egress is also cheaper than raw EC2 egress. See 13_cdn.md.
- VPC endpoints / PrivateLink for S3, DynamoDB, etc. — keeps traffic on the AWS backbone instead of routing out through a NAT Gateway (which charges per GB processed on top of egress). See 04_nat.md.
- Same-AZ placement for chatty service-to-service paths.
- Compression — gzip/br responses; egress is billed on bytes on the wire.
- Keep heavy data in-cloud — process where the data lives rather than pulling it out.
user ──(ingress: free)──▶ ALB ──▶ app ──(egress: $$)──▶ user (response)
│
├─(cross-AZ: $$)──▶ RDS in another AZ
└─(via NAT GW: $$ + $$)──▶ external API
A request that looks like one transaction can touch three separately-billed transfer paths.
Context 3 — Kubernetes Ingress and egress
Kubernetes overloads the words again:
- Ingress (capital-I, the resource) — a K8s object + an Ingress Controller (nginx, Traefik, ALB controller) that routes external HTTP(S) traffic to Services. It’s the cluster’s front door. See ../17_kubernetes/05_ingress_and_networking.md.
- NetworkPolicy — has
ingressandegressrules controlling pod-to-pod and pod-to-external traffic. Default is allow-all both ways; a policy with an emptyegressblock becomes default-deny-egress for the selected pods. - Egress from a cluster — pods reaching external services. In managed clusters this often goes through a NAT Gateway (same per-GB cost as above), and an egress gateway or static-egress-IP setup is how you get a stable outbound IP for third-party allowlisting.
Quick troubleshooting frame
When “traffic isn’t flowing,” name the boundary and check both directions:
- Source egress — is the sending host/subnet/pod allowed out? (SG egress, NACL egress, NetworkPolicy egress)
- Path — is there a route? (route table, IGW/NAT GW, peering, endpoint)
- Destination ingress — is the receiving host/subnet allowed in? (SG ingress, NACL ingress, NetworkPolicy ingress)
- Destination listening — is the process actually bound and accepting?
Stateless layers (NACLs) need the return direction checked too — that’s the classic “ingress works, responses dropped” bug.
Common gotchas
- “Egress is free because ingress is” — no; the asymmetry is the whole point. Ingress free, egress charged.
- Forgetting cross-AZ counts as egress — a same-region multi-AZ app still pays transfer; people assume “same region = free.”
- NAT Gateway double charge — NAT GW bills per GB processed on top of the egress per-GB. High-volume egress to AWS services should use a VPC endpoint instead.
- Wide-open egress SGs — the default; a real security gap, not just a cost one.
- Confusing K8s
Ingress(the resource) with ingress (the direction) — interviewers will check you know both senses. - Stateless NACL, ingress-only rules — return traffic on ephemeral ports gets dropped; you must allow egress too.
Interview angle
- “What’s the difference between ingress and egress traffic?” — Inbound vs outbound, always relative to a boundary (host, subnet, VPC, cluster). The same packet is egress at the sender and ingress at the receiver — always pin down “of what.”
- “Why is egress more expensive than ingress in the cloud?” — Clouds make data-in free to encourage you to bring workloads in, and charge data-out (to the internet, cross-region, even cross-AZ) per GB. It’s a deliberate pricing asymmetry, and it drives real design choices.
- “Your cloud bill has a huge data-transfer line item — how do you cut it?” — Put a CDN in front of static/media so origin egress happens once; use VPC endpoints instead of routing AWS-service traffic through a NAT Gateway; co-locate chatty services in the same AZ; compress responses; keep heavy processing where the data already lives.
- “Why filter egress when ingress is the obvious attack surface?” — Egress filtering limits the blast radius of a compromised server: it blocks data exfiltration, SSRF, and malware command-and-control, and it’s mandated by compliance frameworks like PCI and HIPAA.
- “In Kubernetes, what does ‘ingress’ refer to?” — Two things: the
Ingressresource (plus a controller) that routes external HTTP traffic into the cluster, and theingressdirection in a NetworkPolicy. Worth naming both so it’s clear you know it’s an overloaded term.