Summary:

  • Security groups operate at the instance level with stateful filtering, while NACLs function at the subnet level with stateless evaluation, creating a layered defense model in AWS VPCs.
  • Understanding default AWS quotas, including 60 inbound and 60 outbound rules per security group and 20 rules per direction for NACLs, is essential for architecting scalable network security.
  • Security groups only support allow rules, whereas NACLs support both allow and deny rules with explicit rule evaluation order, making each tool suited for different security scenarios.
  • Advanced features like security group referencing with Transit Gateway and prefix list support for IPv6 enable enterprise-grade multi-account architectures.

When a packet traverses your AWS Virtual Private Cloud, it encounters two distinct gatekeepers before reaching its destination. These gatekeepers, security groups and Network Access Control Lists, form the backbone of AWS network security. Their fundamental differences in behavior, scope, and rule evaluation determine whether your architecture is resilient or riddled with vulnerabilities.

Understanding the difference between AWS security groups and NACLs directly impacts how you design defense-in-depth strategies, troubleshoot connectivity issues, and answer critical questions in System Design interviews. With AWS introducing features like security group referencing with Transit Gateway in late 2024, mastering these concepts has never been more relevant for engineers building production-grade cloud infrastructure.

The following diagram illustrates how traffic flows through both security layers before reaching an EC2 instance within a VPC subnet.

vpc_traffic_flow_sg_nacl
Traffic flow through NACL and security group layers in an AWS VPC

What is a security group in AWS

A security group acts as a virtual firewall that controls inbound and outbound traffic at the Elastic Network Interface level. This effectively means it operates at the instance level. Every EC2 instance, RDS database, Lambda function in a VPC, and Elastic Load Balancer has at least one security group attached to its ENI.

When you launch an instance without specifying a security group, AWS automatically assigns the default security group for that VPC. This default group allows all outbound traffic and permits inbound traffic only from other resources associated with the same security group.

Security groups evaluate traffic based on rules you define, but they possess a critical characteristic that distinguishes them from NACLs. They are stateful. If you allow an inbound request from a specific IP address on port 443, the response traffic is automatically permitted regardless of outbound rules. The stateful nature eliminates the need to configure explicit return traffic rules, simplifying configuration for most use cases.

Consider the following core attributes of security groups:

  • Instance-level scope: Attached directly to ENIs, providing granular control over individual resources.
  • Allow-only rules: Security groups cannot explicitly deny traffic. They only specify what is permitted.
  • Rule evaluation: All rules are evaluated simultaneously, and traffic is allowed if any rule matches.

Pro tip: You can attach up to five security groups to a single ENI by default, allowing you to compose security policies from reusable rule sets. This is particularly powerful when managing microservices where different groups handle database access, inter-service communication, and external API exposure separately.

Security group quotas and limits for 2026

AWS imposes specific quotas on security groups that architects must account for when designing large-scale systems. As of 2026, each security group supports up to 60 inbound rules and 60 outbound rules when using IPv4. If you reference another security group or a prefix list within a rule, each reference counts as a single rule regardless of how many IP addresses it represents.

The default quota allows 2,500 security groups per VPC and 5 security groups per network interface. These limits can be increased through AWS Service Quotas.

When supporting dual-stack environments with IPv6, capacity planning becomes critical. Because a single rule cannot contain both an IPv4 and an IPv6 CIDR block, you must create duplicate rules for both address families. This effectively halves your available rule quota, requiring careful architecture to prevent your security groups from silently maxing out their rule limits.

What is a Network ACL in AWS

A Network Access Control List operates at the subnet level, acting as a firewall for all traffic entering or leaving a subnet regardless of which instances reside within it. Unlike security groups, NACLs are stateless. They evaluate inbound and outbound traffic independently.

If you allow inbound HTTPS traffic on port 443, you must explicitly configure an outbound rule permitting the response traffic on ephemeral ports. These typically range from 1024 to 65535 depending on the operating system.

Every VPC comes with a default NACL that allows all inbound and outbound traffic. When you create a custom NACL, AWS configures it to deny all traffic by default until you add explicit allow rules. This behavioral difference between default and custom NACLs is a frequent source of confusion and a common interview question. NACLs evaluate rules in numerical order, starting from the lowest rule number, and apply the first matching rule encountered.

Watch out: A custom NACL denies all traffic by default, which can immediately break connectivity to instances in the associated subnet. Always add explicit allow rules before associating a custom NACL with a production subnet.

NACL rule evaluation and ephemeral ports

The rule evaluation order in NACLs follows a strict numerical sequence that differs fundamentally from security groups. Each rule has a number between 1 and 32766, and AWS evaluates rules starting from the lowest number. The moment a rule matches the traffic, that rule’s action (allow or deny) is applied, and no further rules are evaluated. A deny rule with number 100 will block traffic even if an allow rule with number 200 would have permitted it.

Ephemeral port configuration represents one of the most overlooked aspects of NACL management. When a client initiates a connection to your server on port 443, the response traffic returns on a randomly selected ephemeral port. Linux systems typically use ports 32768-60999, while Windows uses 49152-65535. Your outbound NACL rules must permit traffic on these port ranges, or responses will be silently dropped despite successful inbound connections.

The following table summarizes the ephemeral port ranges for common operating systems:

Operating systemEphemeral port rangeNACL outbound rule recommendation
Amazon Linux / RHEL32768-60999Allow TCP 32768-65535
Windows Server49152-65535Allow TCP 49152-65535
NAT Gateway1024-65535Allow TCP 1024-65535

Stateful vs stateless: the fundamental distinction

The stateful versus stateless distinction represents the most critical conceptual difference when comparing security groups vs NACL behavior. Stateful filtering, employed by security groups, maintains connection tracking information in memory. When an inbound packet is permitted, the security group automatically creates a temporary entry allowing the corresponding outbound response. This connection tracking persists for the duration of the session, eliminating the need for explicit return traffic rules.

Stateless filtering, used by NACLs, treats every packet as an independent unit with no memory of previous packets. Each packet is evaluated against the rule set without any context about whether it belongs to an established connection. This design requires administrators to configure both inbound rules for requests and outbound rules for responses, including the ephemeral port ranges discussed earlier. The stateless nature provides more granular control but demands more comprehensive rule configuration.

Real-world context: In a recent production incident at a fintech company, engineers spent hours debugging why their application could initiate outbound API calls but never received responses. The root cause was a custom NACL missing outbound rules for ephemeral ports. This is a classic stateless filtering oversight that stateful security groups would have handled automatically.

The diagram below contrasts how stateful and stateless filtering handle the same TCP handshake sequence.

stateful_vs_stateless_comparison
Stateful security group vs stateless NACL handling of TCP connections

Performance implications of connection tracking

The stateful nature of security groups introduces a performance consideration that senior engineers must understand. Connection tracking consumes memory on the underlying hypervisor, and each tracked connection occupies resources until the connection times out or closes. For instances handling millions of concurrent connections, such as high-throughput load balancers or real-time messaging servers, this tracking overhead can become significant.

NACLs, being stateless, impose no connection tracking overhead. They evaluate each packet against the rule set without maintaining state, making them more predictable in high-throughput scenarios. This advantage comes at the cost of configuration complexity. The trade-off between operational simplicity and performance predictability should inform your architectural decisions based on workload characteristics.

Default behaviors and quota comparison

Understanding default behaviors prevents common misconfigurations that can either expose resources to unauthorized access or completely block legitimate traffic. The default security group in a VPC permits all outbound traffic and allows inbound traffic only from resources associated with the same security group. This self-referencing rule enables instances in the default security group to communicate freely with each other while blocking external access.

The default NACL behaves differently, allowing all inbound and outbound traffic by default. This permissive stance means that newly created subnets associated with the default NACL have no network-level restrictions beyond what security groups enforce. Custom NACLs deny all traffic until explicit allow rules are added. This asymmetry between default and custom NACL behavior is a frequent source of production incidents.

AttributeSecurity groupNetwork ACL
Operates atInstance/ENI levelSubnet level
StateStatefulStateless
Rule typesAllow onlyAllow and deny
Rule evaluationAll rules evaluatedLowest number first
Default inbound (default resource)Allow from same SGAllow all
Default inbound (custom resource)Deny allDeny all
Rules per direction (Default)6020
Resources per VPC (default)2,500200

Historical note: Before 2019, security groups had a combined limit of 50 rules for both inbound and outbound. AWS increased this to 60 per direction in response to customer feedback about complex microservice architectures requiring more granular rule sets.

Combining security groups and NACLs for defense in depth

Enterprise architectures rarely rely on a single security layer. The combination of security groups and NACLs creates a defense-in-depth strategy where each layer addresses different threat vectors. Security groups excel at defining application-level access patterns, such as allowing web servers to communicate with application servers on specific ports. NACLs provide subnet-level protection that can block entire IP ranges or implement network segmentation policies.

A practical layering strategy involves using NACLs to enforce broad network policies and security groups for fine-grained application rules. Consider a three-tier architecture with public, application, and database subnets:

  1. Public subnet NACL: Allow inbound HTTP/HTTPS from the internet, allow outbound to the application subnet on application ports, and allow outbound to the internet on ephemeral ports for return traffic.
  2. Application subnet NACL: Allow inbound only from public subnet, allow outbound to database subnet on database ports.
  3. Database subnet NACL: Allow inbound only from application subnet on database ports, deny all direct internet access.

Security groups then refine these policies at the instance level, specifying exactly which application servers can connect to which database instances. This layered approach ensures that even if a security group is misconfigured, the NACL provides a safety net.

defense_in_depth_architecture
Defense-in-depth architecture using NACLs and security groups together

When NACLs provide value security groups cannot

Since security groups cannot deny traffic explicitly, NACLs become essential when you need to block specific IP addresses or ranges. If your application experiences an attack from a known malicious IP range, adding a deny rule to the subnet’s NACL immediately blocks that traffic before it reaches any instance. Security groups would require removing allow rules, which may not be granular enough if the malicious IPs fall within a broader allowed range.

NACLs also provide protection against misconfigured security groups. A junior engineer accidentally opening port 22 to 0.0.0.0/0 on a security group would still be blocked if the NACL only permits SSH from your corporate IP range. This safety net is particularly valuable in organizations with many engineers modifying security configurations.

Pro tip: Use NACLs as your emergency response mechanism for incident response. Pre-create NACL rules with high rule numbers that deny traffic from placeholder CIDR blocks. During an incident, simply update the CIDR to the attacker’s IP range for immediate subnet-wide blocking.

IPv4 vs IPv6 and prefix list support

Both security groups and NACLs support IPv4 and IPv6 rules, but the implementation details differ in ways that affect quota consumption and operational complexity. Because AWS does not allow you to specify both an IPv4 and an IPv6 CIDR block within a single rule, dual-stack environments require you to manually create separate, duplicate rules for each address family. This effectively doubles your rule count, which can quickly exhaust your 60-rule limit in security groups.

Prefix lists offer a solution for managing large numbers of IP addresses efficiently. A managed prefix list is a set of CIDR blocks that you can reference in security group rules. AWS provides managed prefix lists for services like S3 and DynamoDB, allowing you to permit access to these services without specifying individual IP ranges. Custom prefix lists enable you to group your own CIDR blocks and reference them across multiple security groups.

NACLs do not support prefix list references directly. Each CIDR block must be specified as an individual rule, which can quickly consume the 20-rule-per-direction limit. This limitation makes NACLs less suitable for scenarios requiring access to many IP ranges, pushing such use cases toward security groups with prefix lists.

Security group referencing with Transit Gateway

One of the most powerful features introduced for multi-account architectures is security group referencing across VPCs connected via Transit Gateway. This feature allows a security group in one VPC to reference a security group in a peered VPC, enabling dynamic access control without hardcoding IP addresses. When instances in the referenced security group change, the rules automatically apply to the new IPs.

Consider a hub-and-spoke architecture where a shared services VPC hosts monitoring and logging infrastructure. Application VPCs can reference the monitoring security group in their rules, allowing the monitoring servers to collect metrics without maintaining IP-based allow lists. This approach scales elegantly as you add new application VPCs or replace monitoring infrastructure.

Watch out: Security group referencing across Transit Gateway requires specific route table configurations and security group rule syntax. The referenced security group must be in a VPC attached to the same Transit Gateway, and you must use the security group ID with the appropriate prefix for cross-VPC references.

Real-world enterprise use cases

Enterprise environments present complex scenarios where the interplay between security groups and NACLs determines both security posture and operational efficiency. Multi-region deployments, compliance requirements, and hybrid cloud connectivity each demand specific configurations that leverage the strengths of both tools.

Multi-account architecture patterns

Organizations using AWS Control Tower or AWS Organizations typically separate workloads across multiple accounts for blast radius reduction and compliance isolation. In these architectures, NACLs enforce account-level network boundaries while security groups manage application-specific access. A common pattern includes:

  • Network account: Hosts the Transit Gateway for centralized routing and inspection, relying on AWS Network Firewall or TGW Route Tables for inter-account traffic filtering, while NACLs only protect the specific, local transit subnets.
  • Shared services account: Contains security groups referenced by application accounts for centralized services.
  • Application accounts: Manage their own local VPCs, defining custom NACLs for broad subnet-level segmentation and security groups for fine-grained, workload-specific rules.

This separation allows network teams to manage broad connectivity policies through NACLs while application teams retain autonomy over their security group configurations.

Compliance and audit considerations

Regulatory frameworks like PCI-DSS and HIPAA require documented network segmentation and access controls. NACLs provide subnet-level segmentation that auditors can easily verify, while security groups demonstrate instance-level controls. The combination satisfies requirements for both network and host-based firewalls.

For audit purposes, AWS Config rules can monitor both security groups and NACLs for compliance violations. Rules like vpc-sg-open-only-to-authorized-ports and nacl-no-unrestricted-ssh-rdp automatically flag configurations that violate your security policies. Integrating these checks into your CI/CD pipeline prevents non-compliant changes from reaching production.

compliance_monitoring_architecture
Compliance monitoring architecture for security groups and NACLs

Real-world context: A healthcare SaaS provider reduced their PCI-DSS audit preparation time by 60% after implementing automated Config rules for security group and NACL compliance. The continuous monitoring replaced quarterly manual reviews and caught three potential violations before they reached production.

Conclusion

The difference between AWS security groups and NACLs extends far beyond their stateful versus stateless nature. Security groups provide instance-level, allow-only rules with automatic return traffic handling, making them ideal for application-specific access control. NACLs offer subnet-level filtering with explicit allow and deny capabilities, enabling network segmentation and emergency IP blocking that security groups cannot achieve. Together, they form a defense-in-depth strategy that addresses threats at multiple layers of your architecture.

As AWS continues evolving these services with features like security group referencing across Transit Gateway, engineers must stay current with both capabilities and limitations. The default 60-rule limit per security group direction and 20-rule limit per NACL direction directly impact how you design rule sets for complex environments. Mastering these tools prepares you for production architecture decisions and System Design interviews where demonstrating layered security thinking distinguishes senior candidates.

Whether you are troubleshooting connectivity issues, designing multi-account architectures, or preparing for compliance audits, the principles covered here provide the foundation for making informed decisions about AWS network security.